Version 1.14.0-dev.5.0

Merge commit '1f8eddcc2113ed5a0474520455582066a3ce6aaf' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3172396..b61bead 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,6 +38,10 @@
     when being written to a `.packages` file, this is unlikely to break many
     people in practice.
 
+  * **Breaking:** Support for `barback` versions prior to 0.15.0 (released July
+    2014) has been dropped. Pub will no longer install these older barback
+    versions.
+
   * `pub serve` now GZIPs the assets it serves to make load times more similar
     to real-world use-cases.
 
diff --git a/DEPS b/DEPS
index ed1aa95..aa5c78c 100644
--- a/DEPS
+++ b/DEPS
@@ -10,9 +10,6 @@
   # The svn location to pull out dependencies from
   "third_party": "http://dart.googlecode.com/svn/third_party",
 
-  # The svn location for pulling pinned revisions of bleeding edge dependencies.
-  "bleeding_edge": "http://dart.googlecode.com/svn/branches/bleeding_edge",
-
   # Use this googlecode_url variable only if there is an internal mirror for it.
   # If you do not know, use the full path while defining your new deps entry.
   "googlecode_url": "http://%s.googlecode.com/svn",
@@ -55,7 +52,6 @@
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.2",
   "dev_compiler_rev": "@0.1.9",
-  "fake_async_rev" : "@38614",
   "firefox_jsshell_rev" : "@45554",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
   "gsutil_rev" : "@33376",
@@ -77,14 +73,14 @@
   "mustache4dart_rev" : "@5724cfd85151e5b6b53ddcd3380daf188fe47f92",
   "oauth2_tag": "@1.0.0",
   "observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
-  "observatory_pub_packages_rev": "@5c199c5954146747f75ed127871207718dc87786",
+  "observatory_pub_packages_rev": "@cf90eb9077177d3d6b3fd5e8289477c2385c026a",
   "package_config_rev": "@0.1.3",
   "path_tag": "@1.3.6",
   "petitparser_rev" : "@37878",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
   "pool_tag": "@1.2.1",
-  "pub_rev": "@3000544b752bbc89e5e01559eed7f70e9401632b",
+  "pub_rev": "@a1dd3484795b2bc221aaa8d007f3162251b3c08e",
   "pub_cache_tag": "@v0.1.0",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
@@ -112,7 +108,6 @@
   "WebCore_rev" : "@44061",
   "yaml_tag": "@2.1.5",
   "zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
-  "font_awesome_rev": "@31824",
   "barback-0.13.0_rev": "@34853",
   "barback-0.14.0_rev": "@36398",
   "barback-0.14.1_rev": "@38525",
@@ -153,14 +148,8 @@
 
   Var("dart_root") + "/third_party/7zip":
      Var("third_party") + "/7zip" + Var("7zip_rev"),
-  Var("dart_root") + "/third_party/chrome":
-      Var("third_party") + "/chrome" + Var("chrome_rev"),
-  Var("dart_root") + "/third_party/pkg/fake_async":
-      Var("third_party") + "/fake_async" + Var("fake_async_rev"),
   Var("dart_root") + "/third_party/firefox_jsshell":
       Var("third_party") + "/firefox_jsshell" + Var("firefox_jsshell_rev"),
-  Var("dart_root") + "/third_party/font-awesome":
-      Var("third_party") + "/font-awesome" + Var("font_awesome_rev"),
   Var("dart_root") + "/third_party/gsutil":
       Var("third_party") + "/gsutil" + Var("gsutil_rev"),
   Var("dart_root") + "/third_party/pkg/petitparser":
@@ -306,18 +295,6 @@
       (Var("github_mirror") % "which") + Var("which_tag"),
   Var("dart_root") + "/third_party/pkg/yaml":
       (Var("github_mirror") % "yaml") + Var("yaml_tag"),
-
-  # These specific versions of barback and source_maps are used for testing and
-  # should be pulled from bleeding_edge even on channels.
-  Var("dart_root") + "/third_party/pkg/barback-0.13.0":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.13.0_rev"),
-  Var("dart_root") + "/third_party/pkg/barback-0.14.0+3":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.14.0_rev"),
-  Var("dart_root") + "/third_party/pkg/barback-0.14.1+4":
-      Var("bleeding_edge") + "/dart/pkg/barback" + Var("barback-0.14.1_rev"),
-  Var("dart_root") + "/third_party/pkg/source_maps-0.9.4":
-      Var("bleeding_edge") + "/dart/pkg/source_maps" +
-      Var("source_maps-0.9.4_rev"),
 }
 
 deps_os = {
diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
index f28ccf4..a36a54a 100644
--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
@@ -78,7 +78,7 @@
     await analysisFinished;
 
     print('analysis completed in ${stopwatch.elapsed}');
-    print('completion received at : ${timings}');
+    print('completion received at : $timings');
     await shutdown();
   }
 }
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index c27a188..2c2c2cb 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -10,7 +10,7 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/protocol_server.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
+import 'package:analyzer/dart/element/element.dart' as engine;
 import 'package:analyzer/src/generated/utilities_dart.dart' as engine;
 
 /**
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index f72f051..f0d7931 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -21,12 +21,12 @@
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -34,6 +34,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:plugin/plugin.dart';
 
@@ -1330,7 +1331,7 @@
     }
     // if library has not been resolved yet, the unit will be resolved later
     Source librarySource = librarySources[0];
-    if (context.getLibraryElement(librarySource) == null) {
+    if (context.getResult(librarySource, LIBRARY_ELEMENT5) == null) {
       return null;
     }
     // if library has been already resolved, resolve unit
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 1fc175b..a91e47d 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -5,8 +5,9 @@
 library computer.highlights;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
index ddab12f..fc0d77e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights2.dart
@@ -5,8 +5,9 @@
 library computer.highlights2;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index a6f7337..45467ca 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -6,54 +6,12 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     show HoverInformation;
+import 'package:analysis_server/src/utilities/documentation.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 
 /**
- * Converts [str] from a Dart Doc string with slashes and stars to a plain text
- * representation of the comment.
- */
-String _removeDartDocDelimiters(String str) {
-  if (str == null) {
-    return null;
-  }
-  // remove /** */
-  if (str.startsWith('/**')) {
-    str = str.substring(3);
-  }
-  if (str.endsWith("*/")) {
-    str = str.substring(0, str.length - 2);
-  }
-  str = str.trim();
-  // remove leading '* '
-  List<String> lines = str.split('\n');
-  StringBuffer sb = new StringBuffer();
-  bool firstLine = true;
-  for (String line in lines) {
-    line = line.trim();
-    if (line.startsWith("*")) {
-      line = line.substring(1);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    } else if (line.startsWith("///")) {
-      line = line.substring(3);
-      if (line.startsWith(" ")) {
-        line = line.substring(1);
-      }
-    }
-    if (!firstLine) {
-      sb.write('\n');
-    }
-    firstLine = false;
-    sb.write(line);
-  }
-  str = sb.toString();
-  // done
-  return str;
-}
-
-/**
  * A computer for the hover at the specified offset of a Dart [CompilationUnit].
  */
 class DartUnitHoverComputer {
@@ -102,7 +60,7 @@
           ClassElement containingClass =
               element.getAncestor((e) => e is ClassElement);
           if (containingClass != null) {
-            hover.containingClassDescription = containingClass.toString();
+            hover.containingClassDescription = containingClass.displayName;
           }
           // containing library
           LibraryElement library = element.library;
@@ -111,13 +69,16 @@
             hover.containingLibraryPath = library.source.fullName;
           }
         }
+
         // documentation
         hover.dartdoc = _computeDocumentation(element);
       }
       // parameter
       hover.parameter = _safeToString(expression.bestParameterElement);
       // types
-      hover.staticType = _safeToString(expression.staticType);
+      if (element == null || element is VariableElement) {
+        hover.staticType = _safeToString(expression.staticType);
+      }
       hover.propagatedType = _safeToString(expression.propagatedType);
       // done
       return hover;
@@ -130,8 +91,7 @@
     if (element is ParameterElement) {
       element = element.enclosingElement;
     }
-    String dartDoc = element.computeDocumentationComment();
-    return _removeDartDocDelimiters(dartDoc);
+    return removeDartDocDelimiters(element.documentationComment);
   }
 
   static _safeToString(obj) => obj != null ? obj.toString() : null;
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 9b4c9b7..55c6560 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -6,8 +6,9 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/collections.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -199,7 +200,7 @@
     if (constructorNameNode != null) {
       String constructorName = constructorNameNode.name;
       isPrivate = Identifier.isPrivateName(constructorName);
-      name += '.${constructorName}';
+      name += '.$constructorName';
       offset = constructorNameNode.offset;
       length = constructorNameNode.length;
     }
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index b817147..4e2e00b 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -6,13 +6,34 @@
 
 import 'package:analysis_server/src/collections.dart';
 import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart' as engine;
 
 /**
  * A computer for class member overrides in a Dart [CompilationUnit].
  */
 class DartUnitOverridesComputer {
+  static const List<ElementKind> FIELD_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.GETTER,
+    ElementKind.SETTER
+  ];
+
+  static const List<ElementKind> GETTER_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.GETTER
+  ];
+
+  static const List<ElementKind> METHOD_KINDS = const <ElementKind>[
+    ElementKind.METHOD
+  ];
+
+  static const List<ElementKind> SETTER_KINDS = const <ElementKind>[
+    ElementKind.FIELD,
+    ElementKind.SETTER
+  ];
+
   final CompilationUnit _unit;
 
   final List<Override> _overrides = <Override>[];
@@ -33,7 +54,16 @@
               continue;
             }
             SimpleIdentifier nameNode = classMember.name;
-            _addOverride(nameNode.offset, nameNode.length, nameNode.name);
+            List<ElementKind> kinds;
+            if (classMember.isGetter) {
+              kinds = GETTER_KINDS;
+            } else if (classMember.isSetter) {
+              kinds = SETTER_KINDS;
+            } else {
+              kinds = METHOD_KINDS;
+            }
+            _addOverride(
+                nameNode.offset, nameNode.length, nameNode.name, kinds);
           }
           if (classMember is FieldDeclaration) {
             if (classMember.isStatic) {
@@ -42,7 +72,8 @@
             List<VariableDeclaration> fields = classMember.fields.variables;
             for (VariableDeclaration field in fields) {
               SimpleIdentifier nameNode = field.name;
-              _addOverride(nameNode.offset, nameNode.length, nameNode.name);
+              _addOverride(
+                  nameNode.offset, nameNode.length, nameNode.name, FIELD_KINDS);
             }
           }
         }
@@ -54,6 +85,7 @@
   void _addInterfaceOverrides(
       Set<engine.Element> elements,
       String name,
+      List<ElementKind> kinds,
       engine.InterfaceType type,
       bool checkType,
       Set<engine.InterfaceType> visited) {
@@ -65,7 +97,7 @@
     }
     // check type
     if (checkType) {
-      engine.Element element = _lookupMember(type.element, name);
+      engine.Element element = _lookupMember(type.element, name, kinds);
       if (element != null) {
         elements.add(element);
         return;
@@ -73,25 +105,28 @@
     }
     // check interfaces
     for (engine.InterfaceType interfaceType in type.interfaces) {
-      _addInterfaceOverrides(elements, name, interfaceType, true, visited);
+      _addInterfaceOverrides(
+          elements, name, kinds, interfaceType, true, visited);
     }
     // check super
-    _addInterfaceOverrides(elements, name, type.superclass, checkType, visited);
+    _addInterfaceOverrides(
+        elements, name, kinds, type.superclass, checkType, visited);
   }
 
-  void _addOverride(int offset, int length, String name) {
+  void _addOverride(
+      int offset, int length, String name, List<ElementKind> kinds) {
     // super
     engine.Element superEngineElement;
     {
       engine.InterfaceType superType = _currentClass.supertype;
       if (superType != null) {
-        superEngineElement = _lookupMember(superType.element, name);
+        superEngineElement = _lookupMember(superType.element, name, kinds);
       }
     }
     // interfaces
     Set<engine.Element> interfaceEngineElements = new Set<engine.Element>();
-    _addInterfaceOverrides(interfaceEngineElements, name, _currentClass.type,
-        false, new Set<engine.InterfaceType>());
+    _addInterfaceOverrides(interfaceEngineElements, name, kinds,
+        _currentClass.type, false, new Set<engine.InterfaceType>());
     interfaceEngineElements.remove(superEngineElement);
     // is there any override?
     if (superEngineElement != null || interfaceEngineElements.isNotEmpty) {
@@ -108,25 +143,32 @@
   }
 
   static engine.Element _lookupMember(
-      engine.ClassElement classElement, String name) {
+      engine.ClassElement classElement, String name, List<ElementKind> kinds) {
     if (classElement == null) {
       return null;
     }
     engine.LibraryElement library = classElement.library;
+    engine.Element member;
     // method
-    engine.Element member = classElement.lookUpMethod(name, library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.METHOD)) {
+      member = classElement.lookUpMethod(name, library);
+      if (member != null) {
+        return member;
+      }
     }
     // getter
-    member = classElement.lookUpGetter(name, library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.GETTER)) {
+      member = classElement.lookUpGetter(name, library);
+      if (member != null) {
+        return member;
+      }
     }
     // setter
-    member = classElement.lookUpSetter(name + '=', library);
-    if (member != null) {
-      return member;
+    if (kinds.contains(ElementKind.SETTER)) {
+      member = classElement.lookUpSetter(name + '=', library);
+      if (member != null) {
+        return member;
+      }
     }
     // not found
     return null;
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 15e3c80..d0862f0 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -1566,7 +1566,7 @@
   @override
   final Packages packages;
 
-  PackagesFileDisposition(this.packages) {}
+  PackagesFileDisposition(this.packages);
 
   @override
   String get packageRoot => null;
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 19cf98e..0c8d28b 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -22,9 +22,9 @@
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
 import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
 import 'package:analyzer/src/generated/source.dart';
@@ -66,8 +66,8 @@
             server.sendResponse(new Response.getErrorsInvalidFile(request));
           } else {
             engine.AnalysisContext context = server.getAnalysisContext(file);
-            errors = doAnalysisError_listFromEngine(context,
-                errorInfo.lineInfo, errorInfo.errors);
+            errors = doAnalysisError_listFromEngine(
+                context, errorInfo.lineInfo, errorInfo.errors);
             server.sendResponse(
                 new AnalysisGetErrorsResult(errors).toResponse(request.id));
           }
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 370e7bf..653d509 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -181,17 +181,26 @@
    */
   Response processRequest(Request request, [CompletionManager manager]) {
     performance = new CompletionPerformance();
-    // extract params
+
+    // extract and validate params
     CompletionGetSuggestionsParams params =
         new CompletionGetSuggestionsParams.fromRequest(request);
-    // schedule completion analysis
-    String completionId = (_nextCompletionId++).toString();
     ContextSourcePair contextSource = server.getContextSourcePair(params.file);
     AnalysisContext context = contextSource.context;
     Source source = contextSource.source;
     if (context == null || !context.exists(source)) {
       return new Response.unknownSource(request);
     }
+    TimestampedData<String> contents = context.getContents(source);
+    if (params.offset < 0 || params.offset > contents.data.length) {
+      return new Response.invalidParameter(
+          request,
+          'params.offset',
+          'Expected offset between 0 and source length inclusive,'
+          ' but found ${params.offset}');
+    }
+
+    // schedule completion analysis
     recordRequest(performance, context, source, params.offset);
     if (manager == null) {
       manager = completionManagerFor(context, source);
@@ -199,6 +208,7 @@
     CompletionRequest completionRequest = new CompletionRequestImpl(context,
         server.resourceProvider, server.searchEngine, source, params.offset);
     int notificationCount = 0;
+    String completionId = (_nextCompletionId++).toString();
     manager.results(completionRequest).listen((CompletionResult result) {
       ++notificationCount;
       bool isLast = result is CompletionResultImpl ? result.isLast : true;
diff --git a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
index 2321ee3..5391d5e 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -7,7 +7,7 @@
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 class ImplementedComputer {
   final SearchEngine searchEngine;
diff --git a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
index 20ed6aa..931d87f 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/navigation_dart.dart
@@ -6,8 +6,9 @@
 
 import 'package:analysis_server/plugin/analysis/navigation/navigation_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index adf253e..7eea646 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -6,8 +6,10 @@
 
 import 'package:analysis_server/plugin/analysis/occurrences/occurrences_core.dart';
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 93ad959..ce2b38c 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -19,8 +19,8 @@
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/parser.dart' as engine;
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 66fac73..2267250 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -17,8 +17,8 @@
 import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -350,7 +350,8 @@
     }
   }
 
-  bool get _isPriorityContext => context is InternalAnalysisContext &&
+  bool get _isPriorityContext =>
+      context is InternalAnalysisContext &&
       (context as InternalAnalysisContext).prioritySources.isNotEmpty;
 
   @override
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 981b694..822727c 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -9,9 +9,10 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart'
     as engine;
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 827024b..c6a9a74 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -9,8 +9,9 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 export 'package:analysis_server/src/provisional/completion/completion_core.dart'
@@ -62,6 +63,11 @@
  */
 abstract class DartCompletionRequest extends CompletionRequest {
   /**
+   * Return the dart:core library element
+   */
+  LibraryElement get coreLib;
+
+  /**
    * Return the expression to the right of the "dot" or "dot dot",
    * or `null` if this is not a "dot" completion (e.g. `foo.b`).
    */
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
index 64fecef..f1a8a05 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
@@ -11,9 +11,15 @@
 import 'package:analysis_server/src/services/completion/dart/combinator_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
@@ -80,13 +86,29 @@
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new FieldFormalContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new ImportedReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new InheritedReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new KeywordContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LabelContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new LibraryMemberContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new LibraryPrefixContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalConstructorContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalLibraryContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LocalReferenceContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new NamedConstructorContributor());
+    // Revisit this contributor and these tests
+    // once DartChangeBuilder API has solidified.
+    // registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+    //     () => new OverrideContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new StaticMemberContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index 7762e9e..c04ce43 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -4,8 +4,9 @@
 
 library analysis_server.src.provisional.completion.dart.completion_target;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -264,16 +265,13 @@
   /**
    * Return `true` if the target is a functional argument in an argument list.
    * The target [AstNode] hierarchy *must* be resolved for this to work.
+   * See [maybeFunctionalArgument].
    */
   bool isFunctionalArgument() {
-    if (argIndex == null) {
+    if (!maybeFunctionalArgument()) {
       return false;
     }
-    AstNode argList = containingNode;
-    if (argList is! ArgumentList) {
-      return false;
-    }
-    AstNode parent = argList.parent;
+    AstNode parent = containingNode.parent;
     if (parent is InstanceCreationExpression) {
       DartType instType = parent.bestType;
       if (instType != null) {
@@ -302,6 +300,22 @@
   }
 
   /**
+   * Return `true` if the target maybe a functional argument in an argument list.
+   * This is used in determining whether the target [AstNode] hierarchy
+   * needs to be resolved so that [isFunctionalArgument] will work.
+   */
+  bool maybeFunctionalArgument() {
+    if (argIndex == null) {
+      return false;
+    }
+    AstNode argList = containingNode;
+    if (argList is! ArgumentList) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
    * Determine if the offset is contained in a preceding comment token
    * and return that token, otherwise return `null`.
    */
diff --git a/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
index 1f2c887..bdc0931 100644
--- a/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/edit/utilities/change_builder_dart.dart
@@ -6,8 +6,9 @@
 
 import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
 import 'package:analysis_server/src/utilities/change_builder_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart b/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
index 086ce71..f865bb5 100644
--- a/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
+++ b/pkg/analysis_server/lib/src/provisional/refactoring/refactoring_core.dart
@@ -88,7 +88,9 @@
  */
 abstract class RefactoringKind {
   factory RefactoringKind(String name, bool requiresOptions) {
-  } // TODO(brianwilkerson) Redirect to impl class.
+    // TODO(brianwilkerson) Redirect to impl class.
+    return null;
+  }
   bool get requiresOptions;
 }
 
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index d470afe..112db5d 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -11,7 +11,7 @@
     show SearchResult, newSearchResult_fromMatch;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 306477d..c60d4a5 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -15,8 +15,8 @@
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 /**
  * Instances of the class [SearchDomainHandler] implement a [RequestHandler]
@@ -178,8 +178,9 @@
       TypeHierarchyComputer computer =
           new TypeHierarchyComputer(searchEngine, element);
       List<protocol.TypeHierarchyItem> items = computer.computeSuper();
-      protocol.Response response = new protocol.SearchGetTypeHierarchyResult(
-          hierarchyItems: items).toResponse(request.id);
+      protocol.Response response =
+          new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items)
+              .toResponse(request.id);
       server.sendResponse(response);
       return;
     }
@@ -187,8 +188,9 @@
     TypeHierarchyComputer computer =
         new TypeHierarchyComputer(searchEngine, element);
     List<protocol.TypeHierarchyItem> items = await computer.compute();
-    protocol.Response response = new protocol.SearchGetTypeHierarchyResult(
-        hierarchyItems: items).toResponse(request.id);
+    protocol.Response response =
+        new protocol.SearchGetTypeHierarchyResult(hierarchyItems: items)
+            .toResponse(request.id);
     server.sendResponse(response);
   }
 
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 0a666f3..793e471 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -11,7 +11,8 @@
     show TypeHierarchyItem, convertElement;
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /**
  * A computer for a type hierarchy of an [Element].
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_core.dart b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
index b65f4bf..7048a6e 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_core.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_core.dart
@@ -23,6 +23,22 @@
   @override
   final int offset;
 
+  /**
+   * The offset of the start of the text to be replaced.
+   * This will be different than the offset used to request the completion
+   * suggestions if there was a portion of an identifier before the original
+   * offset. In particular, the replacementOffset will be the offset of the
+   * beginning of said identifier.
+   */
+  int replacementOffset;
+
+  /**
+   * The length of the text to be replaced if the remainder of the identifier
+   * containing the cursor is to be replaced when the suggestion is applied
+   * (that is, the number of characters in the existing identifier).
+   */
+  int replacementLength;
+
   @override
   final ResourceProvider resourceProvider;
 
@@ -33,5 +49,19 @@
    * Initialize a newly created completion request based on the given arguments.
    */
   CompletionRequestImpl(this.context, this.resourceProvider, this.searchEngine,
-      this.source, this.offset);
+      this.source, this.offset) {
+    replacementOffset = offset;
+    replacementLength = 0;
+  }
+
+  /**
+   * Return the original text from the [replacementOffset] to the [offset]
+   * that can be used to filter the suggestions on the server side.
+   */
+  String get filterText {
+    return context
+        .getContents(source)
+        .data
+        .substring(replacementOffset, offset);
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
index c559a80..5cb8bab 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
@@ -15,24 +15,6 @@
 import 'package:analyzer/src/generated/source.dart';
 
 /**
- * [CompletionCache] contains information about the prior code completion
- * for use in the next code completion.
- */
-abstract class CompletionCache {
-  /**
-   * The context in which the completion was computed.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The source in which the completion was computed.
-   */
-  final Source source;
-
-  CompletionCache(this.context, this.source);
-}
-
-/**
  * Manages completion contributors for a given completion request.
  */
 abstract class CompletionManager {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 29f463b..5036e08 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -9,8 +9,8 @@
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -24,14 +24,6 @@
   return 0;
 }
 
-String _getParamType(ParameterElement param) {
-  DartType type = param.type;
-  if (type != null) {
-    return type.displayName;
-  }
-  return 'dynamic';
-}
-
 /**
  * If the containing [node] is an argument list
  * or named expression in an argument list
@@ -191,6 +183,14 @@
     // DEPRECATED... argument lists are no longer suggested.
     // See https://github.com/dart-lang/sdk/issues/25197
 
+    // String _getParamType(ParameterElement param) {
+    //   DartType type = param.type;
+    //   if (type != null) {
+    //     return type.displayName;
+    //   }
+    //   return 'dynamic';
+    // }
+
     // StringBuffer completion = new StringBuffer('(');
     // List<String> paramNames = new List<String>();
     // List<String> paramTypes = new List<String>();
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index a08b8bb..26437e2 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -10,8 +10,8 @@
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 /**
  * A contributor for calculating `completion.getSuggestions` request results
@@ -32,8 +32,8 @@
       LibraryElement library = directive.uriElement;
       if (library != null) {
         LibraryElementSuggestionBuilder builder =
-            new LibraryElementSuggestionBuilder(
-                library, CompletionSuggestionKind.IDENTIFIER, false, false);
+            new LibraryElementSuggestionBuilder(request.libraryElement,
+                CompletionSuggestionKind.IDENTIFIER, false, false);
         library.visitChildren(builder);
         return builder.suggestions;
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
index fde8bfb..6e8049b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/common_usage_sorter.dart
@@ -10,12 +10,12 @@
 import 'package:analysis_server/src/protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
 import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'
-    show DART_RELEVANCE_COMMON_USAGE;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
 
@@ -38,7 +38,7 @@
   CommonUsageSorter([this.selectorRelevance = defaultSelectorRelevance]);
 
   @override
-  Future sort(CompletionRequest request,
+  Future sort(DartCompletionRequest request,
       Iterable<CompletionSuggestion> suggestions) {
     _update(request, suggestions);
     return new Future.value();
@@ -92,7 +92,7 @@
   void _updateInvocationRelevance(DartType type, LibraryElement libElem,
       Iterable<CompletionSuggestion> suggestions) {
     String typeName = type.name;
-    List<String> selectors = selectorRelevance['${libElem.name}.${typeName}'];
+    List<String> selectors = selectorRelevance['${libElem.name}.$typeName'];
     if (selectors != null) {
       for (CompletionSuggestion suggestion in suggestions) {
         protocol.Element element = suggestion.element;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index a635b8c..2289a92 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -13,23 +13,33 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_plugin.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
 import 'package:analysis_server/src/services/completion/completion_core.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/context.dart'
     show AnalysisFutureHelper, AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
 
 /**
  * [DartCompletionManager] determines if a completion request is Dart specific
  * and forwards those requests to all [DartCompletionContributor]s.
  */
 class DartCompletionManager implements CompletionContributor {
+  /**
+   * The [contributionSorter] is a long-lived object that isn't allowed
+   * to maintain state between calls to [DartContributionSorter#sort(...)].
+   */
+  static DartContributionSorter contributionSorter = new CommonUsageSorter();
+
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       CompletionRequest request) async {
@@ -37,13 +47,40 @@
       return EMPTY_LIST;
     }
 
-    // Request Dart specific completions from each contributor
     DartCompletionRequestImpl dartRequest =
         await DartCompletionRequestImpl.from(request);
-    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
-    for (DartCompletionContributor c in dartCompletionPlugin.contributors) {
-      suggestions.addAll(await c.computeSuggestions(dartRequest));
+    ReplacementRange range =
+        new ReplacementRange.compute(dartRequest.offset, dartRequest.target);
+    (request as CompletionRequestImpl)
+      ..replacementOffset = range.offset
+      ..replacementLength = range.length;
+
+    // Don't suggest in comments.
+    if (dartRequest.target.isCommentText) {
+      return EMPTY_LIST;
     }
+
+    // Request Dart specific completions from each contributor
+    Map<String, CompletionSuggestion> suggestionMap =
+        <String, CompletionSuggestion>{};
+    for (DartCompletionContributor contributor
+        in dartCompletionPlugin.contributors) {
+      List<CompletionSuggestion> contributorSuggestions =
+          await contributor.computeSuggestions(dartRequest);
+
+      for (CompletionSuggestion newSuggestion in contributorSuggestions) {
+        var oldSuggestion = suggestionMap.putIfAbsent(
+            newSuggestion.completion, () => newSuggestion);
+        if (newSuggestion != oldSuggestion &&
+            newSuggestion.relevance > oldSuggestion.relevance) {
+          suggestionMap[newSuggestion.completion] = newSuggestion;
+        }
+      }
+    }
+
+    // Adjust suggestion relevance before returning
+    List<CompletionSuggestion> suggestions = suggestionMap.values.toList();
+    await contributionSorter.sort(dartRequest, suggestions);
     return suggestions;
   }
 }
@@ -54,52 +91,9 @@
 class DartCompletionRequestImpl extends CompletionRequestImpl
     implements DartCompletionRequest {
   /**
-   * Return a [Future] that completes with a newly created completion request
-   * based on the given [request].
+   * The [LibraryElement] representing dart:core
    */
-  static Future<DartCompletionRequest> from(CompletionRequest request) async {
-    Source source = request.source;
-    AnalysisContext context = request.context;
-    CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
-
-    Source libSource;
-    if (unit.directives.any((d) => d is PartOfDirective)) {
-      List<Source> libraries = context.getLibrariesContaining(source);
-      if (libraries.isNotEmpty) {
-        libSource = libraries[0];
-      }
-    } else {
-      libSource = source;
-    }
-
-    // Most (all?) contributors need declarations in scope to be resolved
-    if (libSource != null) {
-      unit = await new AnalysisFutureHelper<CompilationUnit>(context,
-              new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
-          .computeAsync();
-    }
-
-    return new DartCompletionRequestImpl._(
-        request.context,
-        request.resourceProvider,
-        request.searchEngine,
-        libSource,
-        request.source,
-        request.offset,
-        unit);
-  }
-
-  DartCompletionRequestImpl._(
-      AnalysisContext context,
-      ResourceProvider resourceProvider,
-      SearchEngine searchEngine,
-      this.librarySource,
-      Source source,
-      int offset,
-      CompilationUnit unit)
-      : super(context, resourceProvider, searchEngine, source, offset) {
-    _updateTargets(unit);
-  }
+  LibraryElement _coreLib;
 
   /**
    * The [DartType] for Object in dart:core
@@ -117,11 +111,30 @@
   @override
   CompletionTarget target;
 
+  DartCompletionRequestImpl._(
+      AnalysisContext context,
+      ResourceProvider resourceProvider,
+      SearchEngine searchEngine,
+      this.librarySource,
+      Source source,
+      int offset,
+      CompilationUnit unit)
+      : super(context, resourceProvider, searchEngine, source, offset) {
+    _updateTargets(unit);
+  }
+
+  @override
+  LibraryElement get coreLib {
+    if (_coreLib == null) {
+      Source coreUri = context.sourceFactory.forUri('dart:core');
+      _coreLib = context.computeLibraryElement(coreUri);
+    }
+    return _coreLib;
+  }
+
   @override
   bool get includeIdentifiers {
-    if (_opType == null) {
-      _opType = new OpType.forCompletion(target, offset);
-    }
+    opType; // <<< ensure _opType is initialized
     return !_opType.isPrefixed &&
         (_opType.includeReturnValueSuggestions ||
             _opType.includeTypeNameSuggestions ||
@@ -145,13 +158,19 @@
   @override
   InterfaceType get objectType {
     if (_objectType == null) {
-      Source coreUri = context.sourceFactory.forUri('dart:core');
-      LibraryElement coreLib = context.getLibraryElement(coreUri);
       _objectType = coreLib.getType('Object').type;
     }
     return _objectType;
   }
 
+  OpType get opType {
+    if (_opType == null) {
+      _opType = new OpType.forCompletion(target, offset);
+    }
+    return _opType;
+  }
+
+  // For internal use only
   @override
   Future<List<Directive>> resolveDirectives() async {
     CompilationUnit libUnit;
@@ -229,4 +248,109 @@
       }
     }
   }
+
+  /**
+   * Return a [Future] that completes with a newly created completion request
+   * based on the given [request].
+   */
+  static Future<DartCompletionRequest> from(CompletionRequest request) async {
+    Source source = request.source;
+    AnalysisContext context = request.context;
+    CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
+
+    Source libSource;
+    if (unit.directives.any((d) => d is PartOfDirective)) {
+      List<Source> libraries = context.getLibrariesContaining(source);
+      if (libraries.isNotEmpty) {
+        libSource = libraries[0];
+      }
+    } else {
+      libSource = source;
+    }
+
+    // Most (all?) contributors need declarations in scope to be resolved
+    if (libSource != null) {
+      unit = await new AnalysisFutureHelper<CompilationUnit>(context,
+              new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
+          .computeAsync();
+    }
+
+    DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._(
+        request.context,
+        request.resourceProvider,
+        request.searchEngine,
+        libSource,
+        request.source,
+        request.offset,
+        unit);
+
+    // Resolve the expression in which the completion occurs
+    // to properly determine if identifiers should be suggested
+    // rather than invocations.
+    if (dartRequest.target.maybeFunctionalArgument()) {
+      AstNode node = dartRequest.target.containingNode.parent;
+      if (node is Expression) {
+        await dartRequest.resolveExpression(node);
+      }
+    }
+
+    return dartRequest;
+  }
+}
+
+/**
+ * Utility class for computing the code completion replacement range
+ */
+class ReplacementRange {
+  int offset;
+  int length;
+
+  ReplacementRange(this.offset, this.length);
+
+  factory ReplacementRange.compute(int requestOffset, CompletionTarget target) {
+    bool isKeywordOrIdentifier(Token token) =>
+        token.type == TokenType.KEYWORD || token.type == TokenType.IDENTIFIER;
+
+    //TODO(danrubel) Ideally this needs to be pushed down into the contributors
+    // but that implies that each suggestion can have a different
+    // replacement offsent/length which would mean an API change
+
+    var entity = target.entity;
+    Token token = entity is AstNode ? entity.beginToken : entity;
+    if (token != null && requestOffset < token.offset) {
+      token = token.previous;
+    }
+    if (token != null) {
+      if (requestOffset == token.offset && !isKeywordOrIdentifier(token)) {
+        // If the insertion point is at the beginning of the current token
+        // and the current token is not an identifier
+        // then check the previous token to see if it should be replaced
+        token = token.previous;
+      }
+      if (token != null && isKeywordOrIdentifier(token)) {
+        if (token.offset <= requestOffset && requestOffset <= token.end) {
+          // Replacement range for typical identifier completion
+          return new ReplacementRange(token.offset, token.length);
+        }
+      }
+      if (token is StringToken) {
+        SimpleStringLiteral uri = new SimpleStringLiteral(token, token.lexeme);
+        Token previous = token.previous;
+        if (previous is KeywordToken) {
+          Keyword keyword = previous.keyword;
+          if (keyword == Keyword.IMPORT ||
+              keyword == Keyword.EXPORT ||
+              keyword == Keyword.PART) {
+            int start = uri.contentsOffset;
+            var end = uri.contentsEnd;
+            if (start <= requestOffset && requestOffset <= end) {
+              // Replacement range for import URI
+              return new ReplacementRange(start, end - start);
+            }
+          }
+        }
+      }
+    }
+    return new ReplacementRange(requestOffset, 0);
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart b/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart
index 8279be3..667b883 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/contribution_sorter.dart
@@ -7,7 +7,7 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 
 /**
  * The abstract class [DartContributionSorter] defines the behavior of objects
@@ -21,6 +21,6 @@
    * this method is called to adjust the relevance of those suggestions.
    * Return a [Future] that completes when the suggestions have been updated.
    */
-  Future sort(
-      CompletionRequest request, Iterable<CompletionSuggestion> suggestions);
+  Future sort(DartCompletionRequest request,
+      Iterable<CompletionSuggestion> suggestions);
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
new file mode 100644
index 0000000..e25dc18
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -0,0 +1,96 @@
+// 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 services.completion.contributor.dart.imported_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+import 'package:analyzer/src/generated/resolver.dart';
+
+/**
+ * A contributor for calculating suggestions for imported top level members.
+ */
+class ImportedReferenceContributor extends DartCompletionContributor {
+  DartCompletionRequest request;
+  OpType optype;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    this.request = request;
+    this.optype = (request as DartCompletionRequestImpl).opType;
+
+    // Traverse dart:core
+    List<CompletionSuggestion> suggestions =
+        _buildSuggestions(request.coreLib.exportNamespace);
+
+    // Traverse imports
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        ImportElement importElem = directive.element;
+        LibraryElement libElem = importElem?.importedLibrary;
+        if (libElem != null) {
+          suggestions.addAll(_buildSuggestions(libElem.exportNamespace,
+              prefix: importElem.prefix?.name,
+              showNames: showNamesIn(importElem),
+              hiddenNames: hiddenNamesIn(importElem)));
+        }
+      }
+    }
+
+    return suggestions;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(Namespace namespace,
+      {String prefix, List<String> showNames, List<String> hiddenNames}) {
+    LibraryElementSuggestionBuilder visitor =
+        new LibraryElementSuggestionBuilder(request, optype, prefix);
+    for (Element elem in namespace.definedNames.values) {
+      if (showNames != null && !showNames.contains(elem.name)) {
+        continue;
+      }
+      if (hiddenNames != null && hiddenNames.contains(elem.name)) {
+        continue;
+      }
+      elem.accept(visitor);
+    }
+    return visitor.suggestions;
+  }
+}
+
+List<String> showNamesIn(ImportElement importElem) {
+  for (NamespaceCombinator combinator in importElem.combinators) {
+    if (combinator is ShowElementCombinator) {
+      return combinator.shownNames;
+    }
+  }
+  return null;
+}
+
+List<String> hiddenNamesIn(ImportElement importElem) {
+  for (NamespaceCombinator combinator in importElem.combinators) {
+    if (combinator is HideElementCombinator) {
+      return combinator.hiddenNames;
+    }
+  }
+  return null;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
new file mode 100644
index 0000000..40f0af7
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -0,0 +1,104 @@
+// 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 services.completion.contributor.dart.inherited_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating suggestions for inherited references.
+ */
+class InheritedReferenceContributor extends DartCompletionContributor
+    with ElementSuggestionBuilder {
+  @override
+  LibraryElement containingLibrary;
+
+  @override
+  CompletionSuggestionKind kind;
+
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+    ClassDeclaration classDecl = _enclosingClass(request.target);
+    if (classDecl == null || classDecl.element == null) {
+      return EMPTY_LIST;
+    }
+
+    containingLibrary = request.libraryElement;
+    bool isFunctionalArgument = request.target.isFunctionalArgument();
+    kind = isFunctionalArgument
+        ? CompletionSuggestionKind.IDENTIFIER
+        : CompletionSuggestionKind.INVOCATION;
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+    for (InterfaceType type in classDecl.element.allSupertypes) {
+      if (!isFunctionalArgument) {
+        for (PropertyAccessorElement elem in type.accessors) {
+          if (elem.isGetter) {
+            if (optype.includeReturnValueSuggestions) {
+              addSuggestion(elem);
+            }
+          } else {
+            if (optype.includeVoidReturnSuggestions) {
+              addSuggestion(elem);
+            }
+          }
+        }
+      }
+      for (MethodElement elem in type.methods) {
+        if (elem.returnType == null) {
+          addSuggestion(elem);
+        } else if (!elem.returnType.isVoid) {
+          if (optype.includeReturnValueSuggestions) {
+            addSuggestion(elem);
+          }
+        } else {
+          if (optype.includeVoidReturnSuggestions) {
+            addSuggestion(elem);
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * Return the class containing the target
+ * or `null` if the target is in a static method or field
+ * or not in a class.
+ */
+ClassDeclaration _enclosingClass(CompletionTarget target) {
+  AstNode node = target.containingNode;
+  while (node != null) {
+    if (node is ClassDeclaration) {
+      return node;
+    }
+    if (node is MethodDeclaration) {
+      if (node.isStatic) {
+        return null;
+      }
+    }
+    if (node is FieldDeclaration) {
+      if (node.isStatic) {
+        return null;
+      }
+    }
+    node = node.parent;
+  }
+  return null;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 28de09b..9892a10 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -27,9 +27,6 @@
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    if (request.target.isCommentText) {
-      return EMPTY_LIST;
-    }
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
     request.target.containingNode
         .accept(new _KeywordVisitor(request, suggestions));
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
new file mode 100644
index 0000000..296f03b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -0,0 +1,286 @@
+// 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 services.completion.contributor.dart.label;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+ * A contributor for calculating label suggestions.
+ */
+class LabelContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    if (!optype.isPrefixed) {
+      if (optype.includeStatementLabelSuggestions ||
+          optype.includeCaseLabelSuggestions) {
+        new _LabelVisitor(request, optype.includeStatementLabelSuggestions,
+                optype.includeCaseLabelSuggestions, suggestions)
+            .visit(request.target.containingNode);
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * A visitor for collecting suggestions for break and continue labels.
+ */
+class _LabelVisitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final List<CompletionSuggestion> suggestions;
+
+  /**
+   * True if statement labels should be included as suggestions.
+   */
+  final bool includeStatementLabels;
+
+  /**
+   * True if case labels should be included as suggestions.
+   */
+  final bool includeCaseLabels;
+
+  _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
+      this.includeCaseLabels, this.suggestions)
+      : super(request.offset),
+        request = request;
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    // ignored
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
+      CompletionSuggestion suggestion = _addSuggestion(label.label);
+      if (suggestion != null) {
+        suggestion.element = createLocalElement(
+            request.source, protocol.ElementKind.LABEL, label.label,
+            returnType: NO_RETURN_TYPE);
+      }
+    }
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+    // ignored
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    // ignored
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {
+    // ignored
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    // ignored
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    // Labels are only accessible within the local function, so stop visiting
+    // once we reach a function boundary.
+    finished();
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    // Labels are only accessible within the local function, so stop visiting
+    // once we reach a function boundary.
+    finished();
+  }
+
+  CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
+    if (id != null) {
+      String completion = id.name;
+      if (completion != null && completion.length > 0 && completion != '_') {
+        CompletionSuggestion suggestion = new CompletionSuggestion(
+            CompletionSuggestionKind.IDENTIFIER,
+            DART_RELEVANCE_DEFAULT,
+            completion,
+            completion.length,
+            0,
+            false,
+            false);
+        suggestions.add(suggestion);
+        return suggestion;
+      }
+    }
+    return null;
+  }
+}
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
+}
+
+/**
+* Create a new suggestion for the given field.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalFieldSuggestion(
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
+  TypeName type = fieldDecl.fields.type;
+  return createLocalSuggestion(
+      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
+      classDecl: fieldDecl.parent,
+      element: createLocalElement(
+          source, protocol.ElementKind.FIELD, varDecl.name,
+          returnType: type, isDeprecated: deprecated));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
+    bool isDeprecated, int defaultRelevance, TypeName returnType,
+    {ClassDeclaration classDecl, protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index 7ecbc64..c7b9590 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -8,8 +8,8 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
index 791c122..194e741 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -8,8 +8,8 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
new file mode 100644
index 0000000..9b4bca9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_constructor_contributor.dart
@@ -0,0 +1,281 @@
+// 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 services.completion.contributor.dart.constructor;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
+}
+
+/**
+* Create a new suggestion for the given field.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalFieldSuggestion(
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
+  TypeName type = fieldDecl.fields.type;
+  return createLocalSuggestion(
+      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
+      classDecl: fieldDecl.parent,
+      element: createLocalElement(
+          source, protocol.ElementKind.FIELD, varDecl.name,
+          returnType: type, isDeprecated: deprecated));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion createLocalSuggestion(SimpleIdentifier id,
+    bool isDeprecated, int defaultRelevance, TypeName returnType,
+    {ClassDeclaration classDecl, protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      CompletionSuggestionKind.INVOCATION,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
+
+/**
+ * A contributor for calculating constructor suggestions
+ * for declarations in the local file.
+ */
+class LocalConstructorContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    if (!optype.isPrefixed) {
+      if (optype.includeConstructorSuggestions) {
+        _Visitor visitor = new _Visitor(request, suggestions);
+        visitor.visit(request.target.containingNode);
+      }
+    }
+    return suggestions;
+  }
+}
+
+/**
+ * A visitor for collecting constructor suggestions.
+ */
+class _Visitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final List<CompletionSuggestion> suggestions;
+
+  _Visitor(DartCompletionRequest request, this.suggestions)
+      : super(request.offset),
+        request = request;
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    bool found = false;
+    for (ClassMember member in declaration.members) {
+      if (member is ConstructorDeclaration) {
+        found = true;
+        _addSuggestion(declaration, member);
+      }
+    }
+    if (!found) {
+      _addSuggestion(declaration, null);
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {}
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {}
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {}
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {}
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {}
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {}
+
+  /**
+   * For the given class and constructor,
+   * add a suggestion of the form B(...) or B.name(...).
+   * If the given constructor is `null`
+   * then add a default constructor suggestion.
+   */
+  void _addSuggestion(
+      ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) {
+    String completion = classDecl.name.name;
+    SimpleIdentifier elemId;
+
+    // Build a suggestion for explicitly declared constructor
+    if (constructorDecl != null) {
+      elemId = constructorDecl.name;
+      ConstructorElement elem = constructorDecl.element;
+      if (elemId != null) {
+        String name = elemId.name;
+        if (name != null && name.length > 0) {
+          completion = '$completion.$name';
+        }
+      }
+      if (elem != null) {
+        CompletionSuggestion suggestion =
+            createSuggestion(elem, completion: completion);
+        if (suggestion != null) {
+          suggestions.add(suggestion);
+        }
+      }
+    }
+
+    // Build a suggestion for an implicit constructor
+    else {
+      protocol.Element element = createLocalElement(
+          request.source, protocol.ElementKind.CONSTRUCTOR, elemId,
+          parameters: '()');
+      element.returnType = classDecl.name.name;
+      CompletionSuggestion suggestion = new CompletionSuggestion(
+          CompletionSuggestionKind.INVOCATION,
+          DART_RELEVANCE_DEFAULT,
+          completion,
+          completion.length,
+          0,
+          false,
+          false,
+          declaringType: classDecl.name.name,
+          element: element,
+          parameterNames: [],
+          parameterTypes: [],
+          requiredParameterCount: 0,
+          hasNamedParameters: false);
+      suggestions.add(suggestion);
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
similarity index 94%
rename from pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
rename to pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
index 360774a..964c6b4 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_declaration_visitor.dart
@@ -4,7 +4,6 @@
 
 library services.completion.dart.local.declaration.visitor;
 
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
@@ -21,11 +20,6 @@
 
   final int offset;
 
-  /**
-   * `true` if local inherited types should be visited.
-   */
-  bool includeLocalInheritedTypes = true;
-
   LocalDeclarationVisitor(this.offset);
 
   void declaredClass(ClassDeclaration declaration);
@@ -119,12 +113,6 @@
   @override
   void visitClassDeclaration(ClassDeclaration node) {
     _visitClassDeclarationMembers(node);
-    // imported types are handled by the imported reference contributor
-    if (includeLocalInheritedTypes) {
-      visitInheritedTypes(node, localDeclaration: (ClassDeclaration classNode) {
-        _visitClassDeclarationMembers(classNode);
-      });
-    }
     visitNode(node);
   }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
new file mode 100644
index 0000000..02878a0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -0,0 +1,185 @@
+// 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 services.completion.contributor.dart.local_lib;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
+    show createSuggestion, ElementSuggestionBuilder;
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating suggestions for top level members
+ * in the library in which the completion is requested
+ * but outside the file in which the completion is requested.
+ */
+class LocalLibraryContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+    LibraryElementSuggestionBuilder visitor =
+        new LibraryElementSuggestionBuilder(request, optype);
+    if (request.librarySource != request.source) {
+      request.libraryElement.definingCompilationUnit.accept(visitor);
+    }
+    for (Directive directive in directives) {
+      if (directive is PartDirective) {
+        CompilationUnitElement partElem = directive.element;
+        if (partElem != null && partElem.source != request.source) {
+          partElem.accept(visitor);
+        }
+      }
+    }
+    return visitor.suggestions;
+  }
+}
+
+/**
+ * A visitor for building suggestions based upon the elements defined by
+ * a source file contained in the same library but not the same as
+ * the source in which the completions are being requested.
+ */
+class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
+    with ElementSuggestionBuilder {
+  final DartCompletionRequest request;
+  final OpType optype;
+  CompletionSuggestionKind kind;
+  final String prefix;
+  List<String> showNames;
+  List<String> hiddenNames;
+
+  LibraryElementSuggestionBuilder(this.request, this.optype, [this.prefix]) {
+    this.kind = request.target.isFunctionalArgument()
+        ? CompletionSuggestionKind.IDENTIFIER
+        : optype.suggestKind;
+  }
+
+  @override
+  LibraryElement get containingLibrary => request.libraryElement;
+
+  @override
+  void visitClassElement(ClassElement element) {
+    if (optype.includeTypeNameSuggestions) {
+      addSuggestion(element, prefix: prefix, relevance: DART_RELEVANCE_DEFAULT);
+    }
+    if (optype.includeConstructorSuggestions) {
+      _addConstructorSuggestions(element, DART_RELEVANCE_DEFAULT);
+    }
+  }
+
+  @override
+  void visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  void visitElement(Element element) {
+    // ignored
+  }
+
+  @override
+  void visitFunctionElement(FunctionElement element) {
+    // Do not suggest operators or local functions
+    if (element.isOperator) {
+      return;
+    }
+    if (element.enclosingElement is! CompilationUnitElement) {
+      return;
+    }
+    int relevance = element.library == containingLibrary
+        ? DART_RELEVANCE_LOCAL_FUNCTION
+        : DART_RELEVANCE_DEFAULT;
+    DartType returnType = element.returnType;
+    if (returnType != null && returnType.isVoid) {
+      if (optype.includeVoidReturnSuggestions) {
+        addSuggestion(element, prefix: prefix, relevance: relevance);
+      }
+    } else {
+      if (optype.includeReturnValueSuggestions) {
+        addSuggestion(element, prefix: prefix, relevance: relevance);
+      }
+    }
+  }
+
+  @override
+  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    if (optype.includeTypeNameSuggestions) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, prefix: prefix, relevance: relevance);
+    }
+  }
+
+  @override
+  void visitLibraryElement(LibraryElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  void visitPropertyAccessorElement(PropertyAccessorElement element) {
+    int relevance;
+    if (element.library == containingLibrary) {
+      if (element.enclosingElement is ClassElement) {
+        relevance = DART_RELEVANCE_LOCAL_FIELD;
+      } else {
+        relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+      }
+    } else {
+      relevance = DART_RELEVANCE_DEFAULT;
+    }
+    addSuggestion(element, prefix: prefix, relevance: relevance);
+  }
+
+  @override
+  void visitTopLevelVariableElement(TopLevelVariableElement element) {
+    if (optype.includeReturnValueSuggestions) {
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, prefix: prefix, relevance: relevance);
+    }
+  }
+
+  /**
+   * Add constructor suggestions for the given class.
+   */
+  void _addConstructorSuggestions(ClassElement classElem, int relevance) {
+    String className = classElem.name;
+    for (ConstructorElement constructor in classElem.constructors) {
+      if (!constructor.isPrivate) {
+        CompletionSuggestion suggestion =
+            createSuggestion(constructor, relevance: relevance);
+        if (suggestion != null) {
+          String name = suggestion.completion;
+          name = name.length > 0 ? '$className.$name' : className;
+          if (prefix != null && prefix.length > 0) {
+            name = '$prefix.$name';
+          }
+          suggestion.completion = name;
+          suggestion.selectionOffset = suggestion.completion.length;
+          suggestions.add(suggestion);
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
new file mode 100644
index 0000000..4fb7c97
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_reference_contributor.dart
@@ -0,0 +1,450 @@
+// 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 services.completion.contributor.dart.local_ref;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
+    show DartCompletionRequestImpl;
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart'
+    show LocalDeclarationVisitor;
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind, Location;
+
+const DYNAMIC = 'dynamic';
+
+final TypeName NO_RETURN_TYPE = new TypeName(
+    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
+
+/**
+ * A contributor for calculating suggestions for declarations in the local
+ * file and containing library.
+ */
+class LocalReferenceContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    OpType optype = (request as DartCompletionRequestImpl).opType;
+
+    // Collect suggestions from the specific child [AstNode] that contains
+    // the completion offset and all of its parents recursively.
+    if (!optype.isPrefixed) {
+      if (optype.includeReturnValueSuggestions ||
+          optype.includeTypeNameSuggestions ||
+          optype.includeVoidReturnSuggestions) {
+        _LocalVisitor visitor =
+            new _LocalVisitor(request, request.offset, optype);
+        AstNode node = request.target.containingNode;
+
+        // Do not suggest local vars within the current expression
+        while (node is Expression) {
+          node = node.parent;
+        }
+
+        // Do not suggest loop variable of a ForEachStatement
+        // when completing the expression of the ForEachStatement
+        if (node is ForEachStatement) {
+          node = node.parent;
+        }
+
+        visitor.visit(node);
+        return visitor.suggestions;
+      }
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * A visitor for collecting suggestions from the most specific child [AstNode]
+ * that contains the completion offset to the [CompilationUnit].
+ */
+class _LocalVisitor extends LocalDeclarationVisitor {
+  final DartCompletionRequest request;
+  final OpType optype;
+  final Map<String, CompletionSuggestion> suggestionMap =
+      <String, CompletionSuggestion>{};
+  int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
+  bool targetIsFunctionalArgument;
+
+  _LocalVisitor(this.request, int offset, this.optype) : super(offset) {
+    // Suggestions for inherited members provided by InheritedReferenceContributor
+    targetIsFunctionalArgument = request.target.isFunctionalArgument();
+
+    // If user typed identifier starting with '_'
+    // then do not suppress the relevance of private members
+    var contents = request.context.getContents(request.source);
+    if (contents != null) {
+      String data = contents.data;
+      int offset = request.offset;
+      if (data != null && 0 < offset && offset <= data.length) {
+        bool isIdentifierChar(int index) {
+          int code = data.codeUnitAt(index);
+          return isLetterOrDigit(code) || code == CHAR_UNDERSCORE;
+        }
+        if (isIdentifierChar(offset - 1)) {
+          while (offset > 0 && isIdentifierChar(offset - 1)) {
+            --offset;
+          }
+          if (data.codeUnitAt(offset) == CHAR_UNDERSCORE) {
+            privateMemberRelevance = null;
+          }
+        }
+      }
+    }
+  }
+
+  List<CompletionSuggestion> get suggestions => suggestionMap.values.toList();
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(
+          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS,
+          isAbstract: declaration.isAbstract,
+          isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(declaration.name, NO_RETURN_TYPE,
+          protocol.ElementKind.CLASS_TYPE_ALIAS,
+          isAbstract: true, isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredEnum(EnumDeclaration declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      _addLocalSuggestion(
+          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM,
+          isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    if (optype.includeReturnValueSuggestions &&
+        (!optype.inStaticMethodBody || fieldDecl.isStatic)) {
+      bool deprecated = _isDeprecated(fieldDecl) || _isDeprecated(varDecl);
+      TypeName typeName = fieldDecl.fields.type;
+      _addLocalSuggestion(varDecl.name, typeName, protocol.ElementKind.FIELD,
+          isDeprecated: deprecated,
+          relevance: DART_RELEVANCE_LOCAL_FIELD,
+          classDecl: fieldDecl.parent);
+    }
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    if (optype.includeReturnValueSuggestions ||
+        optype.includeVoidReturnSuggestions) {
+      TypeName typeName = declaration.returnType;
+      protocol.ElementKind elemKind;
+      int relevance = DART_RELEVANCE_DEFAULT;
+      if (declaration.isGetter) {
+        elemKind = protocol.ElementKind.GETTER;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else if (declaration.isSetter) {
+        if (!optype.includeVoidReturnSuggestions) {
+          return;
+        }
+        elemKind = protocol.ElementKind.SETTER;
+        typeName = NO_RETURN_TYPE;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else {
+        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
+          return;
+        }
+        elemKind = protocol.ElementKind.FUNCTION;
+        relevance = DART_RELEVANCE_LOCAL_FUNCTION;
+      }
+      _addLocalSuggestion(declaration.name, typeName, elemKind,
+          isDeprecated: _isDeprecated(declaration),
+          param: declaration.functionExpression.parameters,
+          relevance: relevance);
+    }
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    if (optype.includeTypeNameSuggestions) {
+      // TODO (danrubel) determine parameters and return type
+      _addLocalSuggestion(declaration.name, declaration.returnType,
+          protocol.ElementKind.FUNCTION_TYPE_ALIAS,
+          isAbstract: true, isDeprecated: _isDeprecated(declaration));
+    }
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    // ignored
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier id, TypeName typeName) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE,
+          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
+    }
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    if ((optype.includeReturnValueSuggestions ||
+            optype.includeVoidReturnSuggestions) &&
+        (!optype.inStaticMethodBody || declaration.isStatic)) {
+      protocol.ElementKind elemKind;
+      FormalParameterList param;
+      TypeName typeName = declaration.returnType;
+      int relevance = DART_RELEVANCE_DEFAULT;
+      if (declaration.isGetter) {
+        elemKind = protocol.ElementKind.GETTER;
+        param = null;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else if (declaration.isSetter) {
+        if (!optype.includeVoidReturnSuggestions) {
+          return;
+        }
+        elemKind = protocol.ElementKind.SETTER;
+        typeName = NO_RETURN_TYPE;
+        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
+      } else {
+        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
+          return;
+        }
+        elemKind = protocol.ElementKind.METHOD;
+        param = declaration.parameters;
+        relevance = DART_RELEVANCE_LOCAL_METHOD;
+      }
+      _addLocalSuggestion(declaration.name, typeName, elemKind,
+          isAbstract: declaration.isAbstract,
+          isDeprecated: _isDeprecated(declaration),
+          classDecl: declaration.parent,
+          param: param,
+          relevance: relevance);
+    }
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier id, TypeName typeName) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(id, typeName, protocol.ElementKind.PARAMETER,
+          relevance: DART_RELEVANCE_PARAMETER);
+    }
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    if (optype.includeReturnValueSuggestions) {
+      _addLocalSuggestion(
+          varDecl.name, varList.type, protocol.ElementKind.TOP_LEVEL_VARIABLE,
+          isDeprecated: _isDeprecated(varList) || _isDeprecated(varDecl),
+          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    }
+  }
+
+  void _addParameterInfo(
+      CompletionSuggestion suggestion, FormalParameterList parameters) {
+    var paramList = parameters.parameters;
+    suggestion.parameterNames = paramList
+        .map((FormalParameter param) => param.identifier.name)
+        .toList();
+    suggestion.parameterTypes = paramList.map((FormalParameter param) {
+      TypeName type = null;
+      if (param is DefaultFormalParameter) {
+        NormalFormalParameter child = param.parameter;
+        if (child is SimpleFormalParameter) {
+          type = child.type;
+        } else if (child is FieldFormalParameter) {
+          type = child.type;
+        }
+      }
+      if (param is SimpleFormalParameter) {
+        type = param.type;
+      } else if (param is FieldFormalParameter) {
+        type = param.type;
+      }
+      if (type == null) {
+        return 'dynamic';
+      }
+      Identifier typeId = type.name;
+      if (typeId == null) {
+        return 'dynamic';
+      }
+      return typeId.name;
+    }).toList();
+    suggestion.requiredParameterCount = paramList
+        .where((FormalParameter param) => param is! DefaultFormalParameter)
+        .length;
+    suggestion.hasNamedParameters = paramList
+        .any((FormalParameter param) => param.kind == ParameterKind.NAMED);
+  }
+
+  void _addLocalSuggestion(
+      SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
+      {bool isAbstract: false,
+      bool isDeprecated: false,
+      ClassDeclaration classDecl,
+      FormalParameterList param,
+      int relevance: DART_RELEVANCE_DEFAULT}) {
+    CompletionSuggestionKind kind = targetIsFunctionalArgument
+        ? CompletionSuggestionKind.IDENTIFIER
+        : optype.suggestKind;
+    CompletionSuggestion suggestion = _createLocalSuggestion(
+        id, kind, isDeprecated, relevance, typeName,
+        classDecl: classDecl);
+    if (suggestion != null) {
+      if (privateMemberRelevance != null &&
+          suggestion.completion.startsWith('_')) {
+        suggestion.relevance = privateMemberRelevance;
+      }
+      suggestionMap.putIfAbsent(suggestion.completion, () => suggestion);
+      suggestion.element = _createLocalElement(request.source, elemKind, id,
+          isAbstract: isAbstract,
+          isDeprecated: isDeprecated,
+          parameters: param != null ? param.toSource() : null,
+          returnType: typeName);
+      if ((elemKind == protocol.ElementKind.METHOD ||
+              elemKind == protocol.ElementKind.FUNCTION) &&
+          param != null) {
+        _addParameterInfo(suggestion, param);
+      }
+    }
+  }
+
+  bool _isVoid(TypeName returnType) {
+    if (returnType != null) {
+      Identifier id = returnType.name;
+      if (id != null && id.name == 'void') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+* Create a new protocol Element for inclusion in a completion suggestion.
+*/
+protocol.Element _createLocalElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
+    {String parameters,
+    TypeName returnType,
+    bool isAbstract: false,
+    bool isDeprecated: false}) {
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
+  int flags = protocol.Element.makeFlags(
+      isAbstract: isAbstract,
+      isDeprecated: isDeprecated,
+      isPrivate: Identifier.isPrivateName(name));
+  return new protocol.Element(kind, name, flags,
+      location: location,
+      parameters: parameters,
+      returnType: _nameForType(returnType));
+}
+
+/**
+* Create a new suggestion based upon the given information.
+* Return the new suggestion or `null` if it could not be created.
+*/
+CompletionSuggestion _createLocalSuggestion(
+    SimpleIdentifier id,
+    CompletionSuggestionKind kind,
+    bool isDeprecated,
+    int defaultRelevance,
+    TypeName returnType,
+    {ClassDeclaration classDecl,
+    protocol.Element element}) {
+  if (id == null) {
+    return null;
+  }
+  String completion = id.name;
+  if (completion == null || completion.length <= 0 || completion == '_') {
+    return null;
+  }
+  CompletionSuggestion suggestion = new CompletionSuggestion(
+      kind,
+      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
+      completion,
+      completion.length,
+      0,
+      isDeprecated,
+      false,
+      returnType: _nameForType(returnType),
+      element: element);
+  if (classDecl != null) {
+    SimpleIdentifier classId = classDecl.name;
+    if (classId != null) {
+      String className = classId.name;
+      if (className != null && className.length > 0) {
+        suggestion.declaringType = className;
+      }
+    }
+  }
+  return suggestion;
+}
+
+/**
+* Return `true` if the @deprecated annotation is present
+*/
+bool _isDeprecated(AnnotatedNode node) {
+  if (node != null) {
+    NodeList<Annotation> metadata = node.metadata;
+    if (metadata != null) {
+      return metadata.any((Annotation a) {
+        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
+      });
+    }
+  }
+  return false;
+}
+
+/**
+* Return the name for the given type.
+*/
+String _nameForType(TypeName type) {
+  if (type == NO_RETURN_TYPE) {
+    return null;
+  }
+  if (type == null) {
+    return DYNAMIC;
+  }
+  Identifier id = type.name;
+  if (id == null) {
+    return DYNAMIC;
+  }
+  String name = id.name;
+  if (name == null || name.length <= 0) {
+    return DYNAMIC;
+  }
+  TypeArgumentList typeArgs = type.typeArguments;
+  if (typeArgs != null) {
+    //TODO (danrubel) include type arguments
+  }
+  return name;
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 86640d9..760274e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -8,9 +8,10 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
 
 /**
  * A contributor for calculating named constructor suggestions
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
similarity index 96%
rename from pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
rename to pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 2ab41e3..e61ebbe 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.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 services.completion.dart.invocation;
+library services.completion.dart.override;
 
 import 'dart:async';
 
@@ -13,8 +13,8 @@
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -22,7 +22,7 @@
  * A completion contributor used to suggest replacing partial identifiers inside
  * a class declaration with templates for inherited members.
  */
-class InheritedContributor implements DartCompletionContributor {
+class OverrideContributor implements DartCompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
@@ -59,27 +59,6 @@
   }
 
   /**
-   * If the target looks like a partial identifier inside a class declaration
-   * then return that identifier, otherwise return `null`.
-   */
-  SimpleIdentifier _getTargetId(CompletionTarget target) {
-    AstNode node = target.containingNode;
-    if (node is ClassDeclaration) {
-      Object entity = target.entity;
-      if (entity is FieldDeclaration) {
-        NodeList<VariableDeclaration> variables = entity.fields.variables;
-        if (variables.length == 1) {
-          SimpleIdentifier targetId = variables[0].name;
-          if (targetId.name.isEmpty) {
-            return targetId;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
    * Return a template for an override of the given [element] in the given
    * [source]. If selected, the template will replace [targetId].
    */
@@ -140,6 +119,27 @@
   }
 
   /**
+   * If the target looks like a partial identifier inside a class declaration
+   * then return that identifier, otherwise return `null`.
+   */
+  SimpleIdentifier _getTargetId(CompletionTarget target) {
+    AstNode node = target.containingNode;
+    if (node is ClassDeclaration) {
+      Object entity = target.entity;
+      if (entity is FieldDeclaration) {
+        NodeList<VariableDeclaration> variables = entity.fields.variables;
+        if (variables.length == 1) {
+          SimpleIdentifier targetId = variables[0].name;
+          if (targetId.name.isEmpty) {
+            return targetId;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
    * Return `true` if the given [classElement] directly declares a member with
    * the given [memberName].
    */
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index d1d2816..3ed05b3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -8,8 +8,9 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 0e395fa..2a537bf 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -7,11 +7,14 @@
 import 'package:analysis_server/src/protocol_server.dart' as protocol;
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/utilities/documentation.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:path/path.dart' as path;
-import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 
 const String DYNAMIC = 'dynamic';
 
@@ -42,6 +45,12 @@
       0,
       isDeprecated,
       false);
+
+  // Attach docs.
+  String doc = removeDartDocDelimiters(element.documentationComment);
+  suggestion.docComplete = doc;
+  suggestion.docSummary = getDartDocSummary(doc);
+
   suggestion.element = protocol.convertElement(element);
   Element enclosingElement = element.enclosingElement;
   if (enclosingElement is ClassElement) {
@@ -107,9 +116,15 @@
   final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
 
   /**
-   * Return the kind of suggestions that should be built.
+   * A set of existing completions used to prevent duplicate suggestions.
    */
-  CompletionSuggestionKind get kind;
+  final Set<String> _completions = new Set<String>();
+
+  /**
+   * A map of element names to suggestions for synthetic getters and setters.
+   */
+  final Map<String, CompletionSuggestion> _syntheticMap =
+      <String, CompletionSuggestion>{};
 
   /**
    * Return the library in which the completion is requested.
@@ -117,6 +132,11 @@
   LibraryElement get containingLibrary;
 
   /**
+   * Return the kind of suggestions that should be built.
+   */
+  CompletionSuggestionKind get kind;
+
+  /**
    * Add a suggestion based upon the given element.
    */
   void addSuggestion(Element element,
@@ -126,12 +146,6 @@
         return;
       }
     }
-    if (prefix == null && element.isSynthetic) {
-      if ((element is PropertyAccessorElement) ||
-          element is FieldElement && !_isSpecialEnumField(element)) {
-        return;
-      }
-    }
     String completion = element.displayName;
     if (prefix != null && prefix.length > 0) {
       if (completion == null || completion.length <= 0) {
@@ -146,22 +160,45 @@
     CompletionSuggestion suggestion = createSuggestion(element,
         completion: completion, kind: kind, relevance: relevance);
     if (suggestion != null) {
-      suggestions.add(suggestion);
-    }
-  }
+      if (element.isSynthetic && element is PropertyAccessorElement) {
+        String cacheKey;
+        if (element.isGetter) {
+          cacheKey = element.name;
+        }
+        if (element.isSetter) {
+          cacheKey = element.name;
+          cacheKey = cacheKey.substring(0, cacheKey.length - 1);
+        }
+        if (cacheKey != null) {
+          CompletionSuggestion existingSuggestion = _syntheticMap[cacheKey];
 
-  /**
-   * Determine if the given element is one of the synthetic enum accessors
-   * for which we should generate a suggestion.
-   */
-  bool _isSpecialEnumField(FieldElement element) {
-    Element parent = element.enclosingElement;
-    if (parent is ClassElement && parent.isEnum) {
-      if (element.name == 'values') {
-        return true;
+          // Pair getter/setter by updating the existing suggestion
+          if (existingSuggestion != null) {
+            CompletionSuggestion getter =
+                element.isGetter ? suggestion : existingSuggestion;
+            protocol.ElementKind elemKind =
+                element.enclosingElement is ClassElement
+                    ? protocol.ElementKind.FIELD
+                    : protocol.ElementKind.TOP_LEVEL_VARIABLE;
+            existingSuggestion.element = new protocol.Element(
+                elemKind,
+                existingSuggestion.element.name,
+                existingSuggestion.element.flags,
+                location: getter.element.location,
+                typeParameters: getter.element.typeParameters,
+                parameters: null,
+                returnType: getter.returnType);
+            return;
+          }
+
+          // Cache lone getter/setter so that it can be paired
+          _syntheticMap[cacheKey] = suggestion;
+        }
+      }
+      if (_completions.add(suggestion.completion)) {
+        suggestions.add(suggestion);
       }
     }
-    return false;
   }
 }
 
@@ -220,7 +257,10 @@
   @override
   visitFunctionElement(FunctionElement element) {
     if (!typesOnly) {
-      addSuggestion(element);
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_FUNCTION
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, relevance: relevance);
     }
   }
 
@@ -234,7 +274,10 @@
   @override
   visitTopLevelVariableElement(TopLevelVariableElement element) {
     if (!typesOnly) {
-      addSuggestion(element);
+      int relevance = element.library == containingLibrary
+          ? DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE
+          : DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, relevance: relevance);
     }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 8915a65..257527b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -8,10 +8,11 @@
 import 'dart:collection';
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 import '../../../protocol_server.dart'
     show CompletionSuggestion, CompletionSuggestionKind;
@@ -280,6 +281,44 @@
   Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
 
   /**
+   * Return completion suggestions for 'dot' completions on the given [type].
+   * If the 'dot' completion is a super expression, then [containingMethodName]
+   * is the name of the method in which the completion is requested.
+   */
+  void buildSuggestions(InterfaceType type, String containingMethodName) {
+    // Visit all of the types in the class hierarchy, collecting possible
+    // completions.  If multiple elements are found that complete to the same
+    // identifier, addSuggestion will discard all but the first (with a few
+    // exceptions to handle getter/setter pairs).
+    List<InterfaceType> types = _getTypeOrdering(type);
+    for (InterfaceType targetType in types) {
+      for (MethodElement method in targetType.methods) {
+        // Exclude static methods when completion on an instance
+        if (!method.isStatic) {
+          // Boost the relevance of a super expression
+          // calling a method of the same name as the containing method
+          _addSuggestion(method,
+              relevance: method.name == containingMethodName
+                  ? DART_RELEVANCE_HIGH
+                  : DART_RELEVANCE_DEFAULT);
+        }
+      }
+      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
+        if (!propertyAccessor.isStatic) {
+          if (propertyAccessor.isSynthetic) {
+            // Avoid visiting a field twice
+            if (propertyAccessor.isGetter) {
+              _addSuggestion(propertyAccessor.variable);
+            }
+          } else {
+            _addSuggestion(propertyAccessor);
+          }
+        }
+      }
+    }
+  }
+
+  /**
    * Add a suggestion based upon the given element, provided that it is not
    * shadowed by a previously added suggestion.
    */
@@ -336,44 +375,6 @@
   }
 
   /**
-   * Return completion suggestions for 'dot' completions on the given [type].
-   * If the 'dot' completion is a super expression, then [containingMethodName]
-   * is the name of the method in which the completion is requested.
-   */
-  void buildSuggestions(InterfaceType type, String containingMethodName) {
-    // Visit all of the types in the class hierarchy, collecting possible
-    // completions.  If multiple elements are found that complete to the same
-    // identifier, addSuggestion will discard all but the first (with a few
-    // exceptions to handle getter/setter pairs).
-    List<InterfaceType> types = _getTypeOrdering(type);
-    for (InterfaceType targetType in types) {
-      for (MethodElement method in targetType.methods) {
-        // Exclude static methods when completion on an instance
-        if (!method.isStatic) {
-          // Boost the relevance of a super expression
-          // calling a method of the same name as the containing method
-          _addSuggestion(method,
-              relevance: method.name == containingMethodName
-                  ? DART_RELEVANCE_HIGH
-                  : DART_RELEVANCE_DEFAULT);
-        }
-      }
-      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
-        if (!propertyAccessor.isStatic) {
-          if (propertyAccessor.isSynthetic) {
-            // Avoid visiting a field twice
-            if (propertyAccessor.isGetter) {
-              _addSuggestion(propertyAccessor.variable);
-            }
-          } else {
-            _addSuggestion(propertyAccessor);
-          }
-        }
-      }
-    }
-  }
-
-  /**
    * Get a list of [InterfaceType]s that should be searched to find the
    * possible completions for an object having type [type].
    */
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
deleted file mode 100644
index be84372..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ /dev/null
@@ -1,395 +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.
-
-library services.completion.dart.cache;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * The `DartCompletionCache` contains cached information from a prior code
- * completion operation.
- */
-class DartCompletionCache extends CompletionCache {
-  /**
-   * A hash of the import directives
-   * or `null` if nothing has been cached.
-   */
-  String _importKey;
-
-  /**
-   * Type suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedTypeSuggestions;
-
-  /**
-   * Suggestions for methods and functions that have void return type,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedVoidReturnSuggestions;
-
-  /**
-   * Other suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> otherImportedSuggestions;
-
-  /**
-   * Suggestions for constructors
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> importedConstructorSuggestions;
-
-  /**
-   * A collection of all imported completions
-   * or `null` if nothing has been cached.
-   */
-  HashSet<String> _importedCompletions;
-
-  /**
-   * A map of simple identifier to imported class element
-   * or `null` if nothing has been cached.
-   */
-  Map<String, ClassElement> importedClassMap;
-
-  /**
-   * The [ClassElement] for Object.
-   */
-  ClassElement _objectClassElement;
-
-  DartCompletionCache(AnalysisContext context, Source source)
-      : super(context, source);
-
-  /**
-   * Return a hash of the import directives for the cached import info
-   * or `null` if nothing has been cached.
-   */
-  String get importKey => _importKey;
-
-  /**
-   * Return the [ClassElement] for Object.
-   */
-  ClassElement get objectClassElement {
-    if (_objectClassElement == null) {
-      Source coreUri = context.sourceFactory.forUri('dart:core');
-      LibraryElement coreLib = context.getLibraryElement(coreUri);
-      _objectClassElement = coreLib.getType('Object');
-    }
-    return _objectClassElement;
-  }
-
-  /**
-   * Given a resolved compilation unit, compute suggestions based upon the
-   * imports and other dart files (e.g. "part" files) in the library containing
-   * the given compilation unit. The returned future completes when the cache
-   * is populated.
-   *
-   * If [shouldWaitForLowPrioritySuggestions] is `true` then the returned
-   * future will complete when the cache is fully populated. If `false`,
-   * the returned future will complete sooner, but the cache will not include
-   * the lower priority suggestions added as a result of a global search.
-   * In this case, those lower priority suggestions will be added later
-   * when the index has been updated and the global search completes.
-   */
-  Future<bool> computeImportInfo(CompilationUnit unit,
-      SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
-    importedTypeSuggestions = <CompletionSuggestion>[];
-    otherImportedSuggestions = <CompletionSuggestion>[];
-    importedConstructorSuggestions = <CompletionSuggestion>[];
-    importedVoidReturnSuggestions = <CompletionSuggestion>[];
-    importedClassMap = new Map<String, ClassElement>();
-    _importedCompletions = new HashSet<String>();
-
-    // Assert that the compilation unit is resolved
-    // and represents the expected source
-    assert(unit.element.source == source);
-
-    // Exclude elements from local library
-    // because they are provided by LocalReferenceContributor
-    Set<LibraryElement> excludedLibs = new Set<LibraryElement>();
-    excludedLibs.add(unit.element.enclosingElement);
-
-    // Determine the compilation unit defining the library containing
-    // this compilation unit
-    List<Source> libraries = context.getLibrariesContaining(source);
-    assert(libraries != null);
-    Source libSource = libraries.length > 0 ? libraries[0] : null;
-    Future<CompilationUnit> futureLibUnit = _computeLibUnit(libSource, unit);
-
-    // Include implicitly imported dart:core elements
-    _addDartCoreSuggestions();
-
-    // Include explicitly imported and part elements
-    Future futureImportsCached = futureLibUnit.then((CompilationUnit libUnit) {
-      _addImportedElemSuggestions(libSource, libUnit, excludedLibs);
-      // Don't wait for search of lower relevance results to complete.
-      // Set key indicating results are ready, and lower relevance results
-      // will be added to the cache when the search completes.
-      _importKey = _computeImportKey(unit);
-      return true;
-    });
-
-    // Add non-imported elements as low relevance
-    // after the imported element suggestions have been added
-    Future<bool> futureAllCached = futureImportsCached.then((_) {
-      return searchEngine
-          .searchTopLevelDeclarations('')
-          .then((List<SearchMatch> matches) {
-        _addNonImportedElementSuggestions(matches, excludedLibs);
-        return true;
-      });
-    });
-
-    return shouldWaitForLowPrioritySuggestions
-        ? futureAllCached
-        : futureImportsCached;
-  }
-
-  /**
-   * Return `true` if the import information is cached for the given
-   * compilation unit.
-   */
-  bool isImportInfoCached(CompilationUnit unit) =>
-      _importKey != null && _importKey == _computeImportKey(unit);
-
-  /**
-   * Add constructor suggestions for the given class.
-   */
-  void _addConstructorSuggestions(
-      ClassElement classElem, int relevance, Source importForSource) {
-    String className = classElem.name;
-    for (ConstructorElement constructor in classElem.constructors) {
-      if (!constructor.isPrivate) {
-        CompletionSuggestion suggestion = createSuggestion(constructor,
-            relevance: relevance, importForSource: importForSource);
-        if (suggestion != null) {
-          String name = suggestion.completion;
-          name = name.length > 0 ? '$className.$name' : className;
-          suggestion.completion = name;
-          suggestion.selectionOffset = suggestion.completion.length;
-          importedConstructorSuggestions.add(suggestion);
-        }
-      }
-    }
-  }
-
-  /**
-   * Add suggestions for implicitly imported elements in dart:core.
-   */
-  void _addDartCoreSuggestions() {
-    Source coreUri = context.sourceFactory.forUri('dart:core');
-    LibraryElement coreLib = context.getLibraryElement(coreUri);
-    if (coreLib == null) {
-      // If the core library has not been analyzed yet, then we cannot add any
-      // suggestions from it.
-      return;
-    }
-    Namespace coreNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
-    coreNamespace.definedNames.forEach((String name, Element elem) {
-      if (elem is ClassElement) {
-        importedClassMap[name] = elem;
-      }
-      _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
-    });
-  }
-
-  /**
-   * Add suggestions for explicitly imported and part elements in the given
-   * library. Add libraries that should not have their elements suggested
-   * even as low priority to [excludedLibs].
-   */
-  void _addImportedElemSuggestions(Source libSource, CompilationUnit libUnit,
-      Set<LibraryElement> excludedLibs) {
-    if (libUnit != null) {
-      libUnit.directives.forEach((Directive directive) {
-        if (directive is ImportDirective) {
-          ImportElement importElem = directive.element;
-          if (importElem != null && importElem.importedLibrary != null) {
-            if (directive.prefix == null) {
-              Namespace importNamespace = new NamespaceBuilder()
-                  .createImportNamespaceForDirective(importElem);
-              // Include top level elements
-              importNamespace.definedNames.forEach((String name, Element elem) {
-                if (elem is ClassElement) {
-                  importedClassMap[name] = elem;
-                }
-                _addSuggestion(elem, DART_RELEVANCE_DEFAULT);
-              });
-            } else {
-              // Exclude elements from prefixed imports
-              // because they are provided by PrefixedElementContributor
-              // Suggested by LibraryPrefixContributor
-              // _addLibraryPrefixSuggestion(importElem);
-              // excludedLibs.add(importElem.importedLibrary);
-            }
-          }
-        } else if (directive is PartDirective) {
-          CompilationUnitElement partElem = directive.element;
-          if (partElem != null && partElem.source != source) {
-            partElem.accept(new _NonLocalElementCacheVisitor(this));
-          }
-        }
-      });
-      if (libSource != source) {
-        libUnit.element.accept(new _NonLocalElementCacheVisitor(this));
-      }
-    }
-  }
-
-  /**
-   * Add suggestions for all top level elements in the context
-   * excluding those elemnents for which suggestions have already been added.
-   */
-  void _addNonImportedElementSuggestions(
-      List<SearchMatch> matches, Set<LibraryElement> excludedLibs) {
-    // Exclude internal Dart SDK libraries
-    for (var lib in context.sourceFactory.dartSdk.sdkLibraries) {
-      if (lib.isInternal) {
-        Source libUri = context.sourceFactory.forUri(lib.shortName);
-        if (libUri != null) {
-          LibraryElement libElem = context.getLibraryElement(libUri);
-          if (libElem != null) {
-            excludedLibs.add(libElem);
-          }
-        }
-      }
-    }
-
-    AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
-    matches.forEach((SearchMatch match) {
-      if (match.kind == MatchKind.DECLARATION) {
-        Element element = match.element;
-        if ((element.context == context || element.context == sdkContext) &&
-            element.isPublic &&
-            !excludedLibs.contains(element.library) &&
-            !_importedCompletions.contains(element.displayName)) {
-          _addSuggestion(element, DART_RELEVANCE_LOW, importForSource: source);
-        }
-      }
-    });
-  }
-
-  /**
-   * Add a suggestion for the given element.
-   */
-  void _addSuggestion(Element element, int relevance,
-      {Source importForSource}) {
-    if (element is ExecutableElement) {
-      // Do not suggest operators or local functions
-      if (element.isOperator) {
-        return;
-      }
-      if (element is FunctionElement) {
-        if (element.enclosingElement is! CompilationUnitElement) {
-          return;
-        }
-      }
-    }
-
-    CompletionSuggestion suggestion = createSuggestion(element,
-        relevance: relevance, importForSource: importForSource);
-
-    if (suggestion != null) {
-      if (element is ExecutableElement) {
-        DartType returnType = element.returnType;
-        if (returnType != null && returnType.isVoid) {
-          importedVoidReturnSuggestions.add(suggestion);
-        } else {
-          otherImportedSuggestions.add(suggestion);
-        }
-      } else if (element is FunctionTypeAliasElement) {
-        importedTypeSuggestions.add(suggestion);
-      } else if (element is ClassElement) {
-        importedTypeSuggestions.add(suggestion);
-        _addConstructorSuggestions(element, relevance, importForSource);
-      } else {
-        otherImportedSuggestions.add(suggestion);
-      }
-      _importedCompletions.add(suggestion.completion);
-    }
-  }
-
-  /**
-   * Compute the hash of the imports for the given compilation unit.
-   */
-  String _computeImportKey(CompilationUnit unit) {
-    StringBuffer sb = new StringBuffer();
-    unit.directives.forEach((Directive directive) {
-      sb.write(directive.toSource());
-    });
-    return sb.toString();
-  }
-
-  /**
-   * Compute the library unit for the given library source,
-   * where the [unit] is the resolved compilation unit associated with [source].
-   */
-  Future<CompilationUnit> _computeLibUnit(
-      Source libSource, CompilationUnit unit) {
-    // If the sources are the same then we already have the library unit
-    if (libSource == source) {
-      return new Future.value(unit);
-    }
-    // If [source] is a part, then compute the library unit
-    if (libSource != null) {
-      return context.computeResolvedCompilationUnitAsync(libSource, libSource);
-    }
-    return new Future.value(null);
-  }
-}
-
-/**
- * A visitor for building suggestions based upon the elements defined by
- * a source file contained in the same library but not the same as
- * the source in which the completions are being requested.
- */
-class _NonLocalElementCacheVisitor extends GeneralizingElementVisitor {
-  final DartCompletionCache cache;
-
-  _NonLocalElementCacheVisitor(this.cache);
-
-  @override
-  void visitClassElement(ClassElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  void visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  void visitFunctionElement(FunctionElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-
-  @override
-  void visitTopLevelVariableElement(TopLevelVariableElement element) {
-    cache._addSuggestion(element, DART_RELEVANCE_DEFAULT);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
index 4f793ec..92bd9b0 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
@@ -9,41 +9,14 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
     show AnalysisRequest, CompletionContributor, CompletionRequest;
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
 import 'package:analysis_server/src/services/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
-export 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart'
-    show
-        DART_RELEVANCE_COMMON_USAGE,
-        DART_RELEVANCE_DEFAULT,
-        DART_RELEVANCE_HIGH,
-        DART_RELEVANCE_INHERITED_ACCESSOR,
-        DART_RELEVANCE_INHERITED_FIELD,
-        DART_RELEVANCE_INHERITED_METHOD,
-        DART_RELEVANCE_KEYWORD,
-        DART_RELEVANCE_LOCAL_ACCESSOR,
-        DART_RELEVANCE_LOCAL_FIELD,
-        DART_RELEVANCE_LOCAL_FUNCTION,
-        DART_RELEVANCE_LOCAL_METHOD,
-        DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE,
-        DART_RELEVANCE_LOCAL_VARIABLE,
-        DART_RELEVANCE_LOW,
-        DART_RELEVANCE_NAMED_PARAMETER,
-        DART_RELEVANCE_PARAMETER;
-
 /**
  * The base class for contributing code completion suggestions.
  */
@@ -71,46 +44,16 @@
  * Manages code completion for a given Dart file completion request.
  */
 class DartCompletionManager extends CompletionManager {
-  /**
-   * The [defaultContributionSorter] is a long-lived object that isn't allowed
-   * to maintain state between calls to [ContributionSorter#sort(...)].
-   */
-  static DartContributionSorter defaultContributionSorter =
-      new CommonUsageSorter();
-
   final SearchEngine searchEngine;
-  final DartCompletionCache cache;
-  List<DartCompletionContributor> contributors;
   Iterable<CompletionContributor> newContributors;
-  DartContributionSorter contributionSorter;
 
   DartCompletionManager(
-      AnalysisContext context, this.searchEngine, Source source, this.cache,
-      [this.contributors, this.newContributors, this.contributionSorter])
+      AnalysisContext context, this.searchEngine, Source source,
+      [this.newContributors])
       : super(context, source) {
-    if (contributors == null) {
-      contributors = [
-        // LocalReferenceContributor before ImportedReferenceContributor
-        // because local suggestions take precedence
-        // and can hide other suggestions with the same name
-        new LocalReferenceContributor(),
-        new ImportedReferenceContributor(),
-        //new KeywordContributor(),
-        //new ArgListContributor(),
-        // new CombinatorContributor(),
-        // new PrefixedElementContributor(),
-        //new UriContributor(),
-        // TODO(brianwilkerson) Use the completion contributor extension point
-        // to add the contributor below (and eventually, all the contributors).
-//        new NewCompletionWrapper(new InheritedContributor())
-      ];
-    }
     if (newContributors == null) {
       newContributors = <CompletionContributor>[];
     }
-    if (contributionSorter == null) {
-      contributionSorter = defaultContributionSorter;
-    }
   }
 
   /**
@@ -121,19 +64,8 @@
       SearchEngine searchEngine,
       Source source,
       Iterable<CompletionContributor> newContributors) {
-    return new DartCompletionManager(context, searchEngine, source,
-        new DartCompletionCache(context, source), null, newContributors);
-  }
-
-  @override
-  Future<bool> computeCache() {
-    return waitForAnalysis().then((CompilationUnit unit) {
-      if (unit != null && !cache.isImportInfoCached(unit)) {
-        return cache.computeImportInfo(unit, searchEngine, true);
-      } else {
-        return new Future.value(false);
-      }
-    });
+    return new DartCompletionManager(
+        context, searchEngine, source, newContributors);
   }
 
   /**
@@ -143,30 +75,7 @@
    */
   List<DartCompletionContributor> computeFast(
       DartCompletionRequest request, CompletionPerformance performance) {
-    return performance.logElapseTime('computeFast', () {
-      CompilationUnit unit = context.parseCompilationUnit(source);
-      request.unit = unit;
-      request.target = new CompletionTarget.forOffset(unit, request.offset);
-      if (request.offset < 0 || request.offset > unit.end) {
-        request.replacementOffset = request.offset;
-        request.replacementLength = 0;
-        sendResults(request, true);
-        return [];
-      }
-
-      ReplacementRange range =
-          new ReplacementRange.compute(request.offset, request.target);
-      request.replacementOffset = range.offset;
-      request.replacementLength = range.length;
-
-      List<DartCompletionContributor> todo = new List.from(contributors);
-      todo.removeWhere((DartCompletionContributor c) {
-        return performance.logElapseTime('computeFast ${c.runtimeType}', () {
-          return c.computeFast(request);
-        });
-      });
-      return todo;
-    });
+    return [];
   }
 
   /**
@@ -193,65 +102,17 @@
     performance.logElapseTime('computeSuggestions');
     performance.logStartTime('waitForAnalysis');
 
-    if (todo.isEmpty) {
-      // TODO(danrubel) current sorter requires no additional analysis,
-      // but need to handle the returned future the same way that futures
-      // returned from contributors are handled once this method is refactored
-      // to be async.
-      /* await */ contributionSorter.sort(request, request.suggestions);
-      // TODO (danrubel) if request is obsolete
-      // (processAnalysisRequest returns false)
-      // then send empty results
-      sendResults(request, true);
-    }
-
-    // Compute the other suggestions
-    return waitForAnalysis().then((CompilationUnit unit) {
-      if (controller.isClosed) {
-        return;
-      }
-      performance.logElapseTime('waitForAnalysis');
-      if (unit == null) {
-        sendResults(request, true);
-        return;
-      }
-      performance.logElapseTime('computeFull', () {
-        request.unit = unit;
-        // TODO(paulberry): Do we need to invoke _ReplacementOffsetBuilder
-        // again?
-        request.target = new CompletionTarget.forOffset(unit, request.offset);
-        int count = todo.length;
-        todo.forEach((DartCompletionContributor c) {
-          String name = c.runtimeType.toString();
-          String completeTag = 'computeFull $name complete';
-          performance.logStartTime(completeTag);
-          performance.logElapseTime('computeFull $name', () {
-            c.computeFull(request).then((bool changed) {
-              performance.logElapseTime(completeTag);
-              bool last = --count == 0;
-              if (changed || last) {
-                // TODO(danrubel) current sorter requires no additional analysis,
-                // but need to handle the returned future the same way that futures
-                // returned from contributors are handled once this method is refactored
-                // to be async.
-                /* await */ contributionSorter.sort(
-                    request, request.suggestions);
-                // TODO (danrubel) if request is obsolete
-                // (processAnalysisRequest returns false)
-                // then send empty results
-                sendResults(request, last);
-              }
-            });
-          });
-        });
-      });
-    });
+    // TODO (danrubel) if request is obsolete
+    // (processAnalysisRequest returns false)
+    // then send empty results
+    sendResults(request, true);
+    return new Future.value();
   }
 
   @override
   void computeSuggestions(CompletionRequest completionRequest) {
     DartCompletionRequest request =
-        new DartCompletionRequest.from(completionRequest, cache);
+        new DartCompletionRequest.from(completionRequest);
     CompletionPerformance performance = new CompletionPerformance();
     performance.logElapseTime('compute', () {
       List<DartCompletionContributor> todo = computeFast(request, performance);
@@ -301,45 +162,6 @@
  */
 class DartCompletionRequest extends CompletionRequestImpl {
   /**
-   * Cached information from a prior code completion operation.
-   */
-  final DartCompletionCache cache;
-
-  /**
-   * The compilation unit in which the completion was requested. This unit
-   * may or may not be resolved when [DartCompletionContributor.computeFast]
-   * is called but is resolved when [DartCompletionContributor.computeFull].
-   */
-  CompilationUnit unit;
-
-  /**
-   * The completion target.  This determines what part of the parse tree
-   * will receive the newly inserted text.
-   */
-  CompletionTarget target;
-
-  /**
-   * Information about the types of suggestions that should be included.
-   */
-  OpType _optype;
-
-  /**
-   * The offset of the start of the text to be replaced.
-   * This will be different than the offset used to request the completion
-   * suggestions if there was a portion of an identifier before the original
-   * offset. In particular, the replacementOffset will be the offset of the
-   * beginning of said identifier.
-   */
-  int replacementOffset;
-
-  /**
-   * The length of the text to be replaced if the remainder of the identifier
-   * containing the cursor is to be replaced when the suggestion is applied
-   * (that is, the number of characters in the existing identifier).
-   */
-  int replacementLength;
-
-  /**
    * The list of suggestions to be sent to the client.
    */
   final List<CompletionSuggestion> _suggestions = <CompletionSuggestion>[];
@@ -354,36 +176,12 @@
       ResourceProvider resourceProvider,
       SearchEngine searchEngine,
       Source source,
-      int offset,
-      this.cache)
+      int offset)
       : super(context, resourceProvider, searchEngine, source, offset);
 
-  factory DartCompletionRequest.from(
-          CompletionRequestImpl request, DartCompletionCache cache) =>
+  factory DartCompletionRequest.from(CompletionRequestImpl request) =>
       new DartCompletionRequest(request.context, request.resourceProvider,
-          request.searchEngine, request.source, request.offset, cache);
-
-  /**
-   * Return the original text from the [replacementOffset] to the [offset]
-   * that can be used to filter the suggestions on the server side.
-   */
-  String get filterText {
-    return context
-        .getContents(source)
-        .data
-        .substring(replacementOffset, offset);
-  }
-
-  /**
-   * Information about the types of suggestions that should be included.
-   * The [target] must be set first.
-   */
-  OpType get optype {
-    if (_optype == null) {
-      _optype = new OpType.forCompletion(target, offset);
-    }
-    return _optype;
-  }
+          request.searchEngine, request.source, request.offset);
 
   /**
    * The list of suggestions to be sent to the client.
@@ -399,91 +197,4 @@
       _suggestions.add(suggestion);
     }
   }
-
-  /**
-   * Convert all [CompletionSuggestionKind.INVOCATION] suggestions
-   * to [CompletionSuggestionKind.IDENTIFIER] suggestions.
-   */
-  void convertInvocationsToIdentifiers() {
-    for (int index = _suggestions.length - 1; index >= 0; --index) {
-      CompletionSuggestion suggestion = _suggestions[index];
-      if (suggestion.kind == CompletionSuggestionKind.INVOCATION) {
-        // Create a copy rather than just modifying the existing suggestion
-        // because [DartCompletionCache] may be caching that suggestion
-        // for future completion requests
-        _suggestions[index] = new CompletionSuggestion(
-            CompletionSuggestionKind.IDENTIFIER,
-            suggestion.relevance,
-            suggestion.completion,
-            suggestion.selectionOffset,
-            suggestion.selectionLength,
-            suggestion.isDeprecated,
-            suggestion.isPotential,
-            declaringType: suggestion.declaringType,
-            parameterNames: suggestion.parameterNames,
-            parameterTypes: suggestion.parameterTypes,
-            requiredParameterCount: suggestion.requiredParameterCount,
-            hasNamedParameters: suggestion.hasNamedParameters,
-            returnType: suggestion.returnType,
-            element: suggestion.element);
-      }
-    }
-  }
-}
-
-/**
- * Utility class for computing the code completion replacement range
- */
-class ReplacementRange {
-  int offset;
-  int length;
-
-  ReplacementRange(this.offset, this.length);
-
-  factory ReplacementRange.compute(int requestOffset, CompletionTarget target) {
-    bool isKeywordOrIdentifier(Token token) =>
-        token.type == TokenType.KEYWORD || token.type == TokenType.IDENTIFIER;
-
-    //TODO(danrubel) Ideally this needs to be pushed down into the contributors
-    // but that implies that each suggestion can have a different
-    // replacement offsent/length which would mean an API change
-
-    var entity = target.entity;
-    Token token = entity is AstNode ? entity.beginToken : entity;
-    if (token != null && requestOffset < token.offset) {
-      token = token.previous;
-    }
-    if (token != null) {
-      if (requestOffset == token.offset && !isKeywordOrIdentifier(token)) {
-        // If the insertion point is at the beginning of the current token
-        // and the current token is not an identifier
-        // then check the previous token to see if it should be replaced
-        token = token.previous;
-      }
-      if (token != null && isKeywordOrIdentifier(token)) {
-        if (token.offset <= requestOffset && requestOffset <= token.end) {
-          // Replacement range for typical identifier completion
-          return new ReplacementRange(token.offset, token.length);
-        }
-      }
-      if (token is StringToken) {
-        SimpleStringLiteral uri = new SimpleStringLiteral(token, token.lexeme);
-        Token previous = token.previous;
-        if (previous is KeywordToken) {
-          Keyword keyword = previous.keyword;
-          if (keyword == Keyword.IMPORT ||
-              keyword == Keyword.EXPORT ||
-              keyword == Keyword.PART) {
-            int start = uri.contentsOffset;
-            var end = uri.contentsEnd;
-            if (start <= requestOffset && requestOffset <= end) {
-              // Replacement range for import URI
-              return new ReplacementRange(start, end - start);
-            }
-          }
-        }
-      }
-    }
-    return new ReplacementRange(requestOffset, 0);
-  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
deleted file mode 100644
index f2a9cfa..0000000
--- a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
+++ /dev/null
@@ -1,268 +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.
-
-library services.completion.contributor.dart.toplevel;
-
-import 'dart:async';
-import 'dart:collection';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-/**
- * A contributor for calculating imported class and top level variable
- * `completion.getSuggestions` request results.
- */
-class ImportedReferenceContributor extends DartCompletionContributor {
-  bool shouldWaitForLowPrioritySuggestions;
-  bool suggestionsComputed;
-  _ImportedSuggestionBuilder builder;
-
-  ImportedReferenceContributor(
-      {this.shouldWaitForLowPrioritySuggestions: false});
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    // Don't suggest in comments.
-    if (request.target.isCommentText) {
-      return true;
-    }
-
-    OpType optype = request.optype;
-    if (!optype.isPrefixed) {
-      if (optype.includeReturnValueSuggestions ||
-          optype.includeTypeNameSuggestions ||
-          optype.includeVoidReturnSuggestions ||
-          optype.includeConstructorSuggestions) {
-        builder = new _ImportedSuggestionBuilder(request, optype);
-        builder.shouldWaitForLowPrioritySuggestions =
-            shouldWaitForLowPrioritySuggestions;
-        // If target is an argument in an argument list
-        // then suggestions may need to be adjusted
-        suggestionsComputed =
-            builder.computeFast(request.target.containingNode);
-        return suggestionsComputed && request.target.argIndex == null;
-      }
-    }
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) async {
-    if (builder != null) {
-      if (!suggestionsComputed) {
-        bool result = await builder.computeFull(request.target.containingNode);
-        _updateSuggestions(request);
-        return result;
-      }
-      _updateSuggestions(request);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * If target is a function argument, suggest identifiers not invocations
-   */
-  void _updateSuggestions(DartCompletionRequest request) {
-    if (request.target.isFunctionalArgument()) {
-      request.convertInvocationsToIdentifiers();
-    }
-  }
-}
-
-/**
- * [_ImportedSuggestionBuilder] traverses the imports and builds suggestions
- * based upon imported elements.
- */
-class _ImportedSuggestionBuilder extends ElementSuggestionBuilder
-    implements SuggestionBuilder {
-  bool shouldWaitForLowPrioritySuggestions;
-  final DartCompletionRequest request;
-  final OpType optype;
-  DartCompletionCache cache;
-
-  _ImportedSuggestionBuilder(this.request, this.optype) {
-    cache = request.cache;
-  }
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  /**
-   * If the needed information is cached, then add suggestions and return `true`
-   * else return `false` indicating that additional work is necessary.
-   */
-  bool computeFast(AstNode node) {
-    CompilationUnit unit = request.unit;
-    if (cache.isImportInfoCached(unit)) {
-      _addSuggestions(node);
-      return true;
-    }
-    return false;
-  }
-
-  /**
-   * Compute suggested based upon imported elements.
-   */
-  Future<bool> computeFull(AstNode node) {
-    Future<bool> addSuggestions(_) {
-      _addSuggestions(node);
-      return new Future.value(true);
-    }
-
-    Future future = null;
-    if (!cache.isImportInfoCached(request.unit)) {
-      future = cache.computeImportInfo(request.unit, request.searchEngine,
-          shouldWaitForLowPrioritySuggestions);
-    }
-    if (future != null) {
-      return future.then(addSuggestions);
-    }
-    return addSuggestions(true);
-  }
-
-  /**
-   * Add constructor and library prefix suggestions from the cache.
-   * To reduce the number of suggestions sent to the client,
-   * filter the suggestions based upon the first character typed.
-   * If no characters are available to use for filtering,
-   * then exclude all low priority suggestions.
-   */
-  void _addConstructorSuggestions() {
-    String filterText = request.filterText;
-    if (filterText.length > 1) {
-      filterText = filterText.substring(0, 1);
-    }
-    DartCompletionCache cache = request.cache;
-    _addFilteredSuggestions(filterText, cache.importedConstructorSuggestions);
-  }
-
-  /**
-   * Add imported element suggestions.
-   */
-  void _addElementSuggestions(List<Element> elements,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    for (Element elem in elements) {
-      if (elem is! ClassElement) {
-        if (optype.includeOnlyTypeNameSuggestions) {
-          return;
-        }
-        if (elem is ExecutableElement) {
-          DartType returnType = elem.returnType;
-          if (returnType != null && returnType.isVoid) {
-            if (!optype.includeVoidReturnSuggestions) {
-              return;
-            }
-          }
-        }
-      }
-      addSuggestion(elem, relevance: relevance);
-    }
-    ;
-  }
-
-  /**
-   * Add suggestions which start with the given text.
-   */
-  _addFilteredSuggestions(
-      String filterText, List<CompletionSuggestion> unfiltered) {
-    //TODO (danrubel) Revisit this filtering once paged API has been added
-    unfiltered.forEach((CompletionSuggestion suggestion) {
-      if (filterText.length > 0) {
-        if (suggestion.completion.startsWith(filterText)) {
-          request.addSuggestion(suggestion);
-        }
-      } else {
-        if (suggestion.relevance != DART_RELEVANCE_LOW) {
-          request.addSuggestion(suggestion);
-        }
-      }
-    });
-  }
-
-  /**
-   * Add suggestions for any inherited imported members.
-   */
-  void _addInheritedSuggestions(AstNode node) {
-    var classDecl = node.getAncestor((p) => p is ClassDeclaration);
-    if (classDecl is ClassDeclaration && !optype.inStaticMethodBody) {
-      // Build a list of inherited types that are imported
-      // and include any inherited imported members
-      List<String> inheritedTypes = new List<String>();
-      // local declarations are handled by the local reference contributor
-      visitInheritedTypes(classDecl, importedTypeName: (String typeName) {
-        inheritedTypes.add(typeName);
-      });
-      HashSet<String> visited = new HashSet<String>();
-      while (inheritedTypes.length > 0) {
-        String name = inheritedTypes.removeLast();
-        ClassElement elem = cache.importedClassMap[name];
-        if (visited.add(name) && elem != null) {
-          _addElementSuggestions(elem.fields,
-              relevance: DART_RELEVANCE_INHERITED_FIELD);
-          _addElementSuggestions(elem.accessors,
-              relevance: DART_RELEVANCE_INHERITED_ACCESSOR);
-          _addElementSuggestions(elem.methods,
-              relevance: DART_RELEVANCE_INHERITED_METHOD);
-          elem.allSupertypes.forEach((InterfaceType type) {
-            if (visited.add(type.name) && type.element != null) {
-              _addElementSuggestions(type.element.fields,
-                  relevance: DART_RELEVANCE_INHERITED_FIELD);
-              _addElementSuggestions(type.element.accessors,
-                  relevance: DART_RELEVANCE_INHERITED_ACCESSOR);
-              _addElementSuggestions(type.element.methods,
-                  relevance: DART_RELEVANCE_INHERITED_METHOD);
-            }
-          });
-        }
-      }
-    }
-  }
-
-  /**
-   * Add suggested based upon imported elements.
-   */
-  void _addSuggestions(AstNode node) {
-    if (optype.includeConstructorSuggestions) {
-      _addConstructorSuggestions();
-    }
-    if (optype.includeReturnValueSuggestions ||
-        optype.includeTypeNameSuggestions ||
-        optype.includeVoidReturnSuggestions) {
-      _addInheritedSuggestions(node);
-      _addTopLevelSuggestions();
-    }
-  }
-
-  /**
-   * Add top level suggestions from the cache.
-   * To reduce the number of suggestions sent to the client,
-   * filter the suggestions based upon the first character typed.
-   * If no characters are available to use for filtering,
-   * then exclude all low priority suggestions.
-   */
-  void _addTopLevelSuggestions() {
-    String filterText = request.filterText;
-    if (filterText.length > 1) {
-      filterText = filterText.substring(0, 1);
-    }
-    DartCompletionCache cache = request.cache;
-    if (optype.includeTypeNameSuggestions) {
-      _addFilteredSuggestions(filterText, cache.importedTypeSuggestions);
-    }
-    if (optype.includeReturnValueSuggestions) {
-      _addFilteredSuggestions(filterText, cache.otherImportedSuggestions);
-    }
-    if (optype.includeVoidReturnSuggestions) {
-      _addFilteredSuggestions(filterText, cache.importedVoidReturnSuggestions);
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
deleted file mode 100644
index 6753a40..0000000
--- a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
+++ /dev/null
@@ -1,601 +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.
-
-library services.completion.contributor.dart.local;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
-/**
- * A contributor for calculating `completion.getSuggestions` request results
- * for the local library in which the completion is requested.
- */
-class LocalReferenceContributor extends DartCompletionContributor {
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    // Don't suggest in comments.
-    if (request.target.isCommentText) {
-      return true;
-    }
-
-    OpType optype = request.optype;
-
-    // Collect suggestions from the specific child [AstNode] that contains
-    // the completion offset and all of its parents recursively.
-    if (!optype.isPrefixed) {
-      if (optype.includeReturnValueSuggestions ||
-          optype.includeTypeNameSuggestions ||
-          optype.includeVoidReturnSuggestions) {
-        _LocalVisitor localVisitor =
-            new _LocalVisitor(request, request.offset, optype);
-        localVisitor.visit(request.target.containingNode);
-      }
-      if (optype.includeStatementLabelSuggestions ||
-          optype.includeCaseLabelSuggestions) {
-        _LabelVisitor labelVisitor = new _LabelVisitor(
-            request,
-            optype.includeStatementLabelSuggestions,
-            optype.includeCaseLabelSuggestions);
-        labelVisitor.visit(request.target.containingNode);
-      }
-      if (optype.includeConstructorSuggestions) {
-        new _ConstructorVisitor(request).visit(request.target.containingNode);
-      }
-    }
-
-    // If target is an argument in an argument list
-    // then suggestions may need to be adjusted
-    return request.target.argIndex == null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    _updateSuggestions(request);
-    return new Future.value(false);
-  }
-
-  /**
-   * If target is a function argument, suggest identifiers not invocations
-   */
-  void _updateSuggestions(DartCompletionRequest request) {
-    if (request.target.isFunctionalArgument()) {
-      request.convertInvocationsToIdentifiers();
-    }
-  }
-}
-
-/**
- * A visitor for collecting constructor suggestions.
- */
-class _ConstructorVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-
-  _ConstructorVisitor(DartCompletionRequest request)
-      : super(request.offset),
-        request = request;
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    bool found = false;
-    for (ClassMember member in declaration.members) {
-      if (member is ConstructorDeclaration) {
-        found = true;
-        _addSuggestion(declaration, member);
-      }
-    }
-    if (!found) {
-      _addSuggestion(declaration, null);
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {}
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {}
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {}
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {}
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {}
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {}
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {}
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {}
-
-  /**
-   * For the given class and constructor,
-   * add a suggestion of the form B(...) or B.name(...).
-   * If the given constructor is `null`
-   * then add a default constructor suggestion.
-   */
-  CompletionSuggestion _addSuggestion(
-      ClassDeclaration classDecl, ConstructorDeclaration constructorDecl) {
-    SimpleIdentifier elemId;
-    String completion = classDecl.name.name;
-    if (constructorDecl != null) {
-      elemId = constructorDecl.name;
-      if (elemId != null) {
-        String name = elemId.name;
-        if (name != null && name.length > 0) {
-          completion = '$completion.$name';
-        }
-      }
-    }
-    bool deprecated = constructorDecl != null && isDeprecated(constructorDecl);
-    List<String> parameterNames = new List<String>();
-    List<String> parameterTypes = new List<String>();
-    int requiredParameterCount = 0;
-    bool hasNamedParameters = false;
-    StringBuffer paramBuf = new StringBuffer();
-    paramBuf.write('(');
-    int paramCount = 0;
-    if (constructorDecl != null) {
-      for (FormalParameter param in constructorDecl.parameters.parameters) {
-        if (paramCount > 0) {
-          paramBuf.write(', ');
-        }
-        String paramName;
-        String typeName;
-        if (param is NormalFormalParameter) {
-          paramName = param.identifier.name;
-          typeName = _nameForParamType(param);
-          ++requiredParameterCount;
-        } else if (param is DefaultFormalParameter) {
-          NormalFormalParameter childParam = param.parameter;
-          paramName = childParam.identifier.name;
-          typeName = _nameForParamType(childParam);
-          if (param.kind == ParameterKind.NAMED) {
-            hasNamedParameters = true;
-          }
-          if (paramCount == requiredParameterCount) {
-            paramBuf.write(hasNamedParameters ? '{' : '[');
-          }
-        }
-        parameterNames.add(paramName);
-        parameterTypes.add(typeName);
-        paramBuf.write(typeName);
-        paramBuf.write(' ');
-        paramBuf.write(paramName);
-        ++paramCount;
-      }
-    }
-    if (paramCount > requiredParameterCount) {
-      paramBuf.write(hasNamedParameters ? '}' : ']');
-    }
-    paramBuf.write(')');
-    protocol.Element element = createElement(
-        request.source, protocol.ElementKind.CONSTRUCTOR, elemId,
-        parameters: paramBuf.toString());
-    element.returnType = classDecl.name.name;
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.INVOCATION,
-        deprecated ? DART_RELEVANCE_LOW : DART_RELEVANCE_DEFAULT,
-        completion,
-        completion.length,
-        0,
-        deprecated,
-        false,
-        declaringType: classDecl.name.name,
-        element: element,
-        parameterNames: parameterNames,
-        parameterTypes: parameterTypes,
-        requiredParameterCount: requiredParameterCount,
-        hasNamedParameters: hasNamedParameters);
-    request.addSuggestion(suggestion);
-    return suggestion;
-  }
-
-  /**
-   * Determine the name of the type for the given constructor parameter.
-   */
-  String _nameForParamType(NormalFormalParameter param) {
-    if (param is SimpleFormalParameter) {
-      return nameForType(param.type);
-    }
-    SimpleIdentifier id = param.identifier;
-    if (param is FieldFormalParameter && id != null) {
-      String fieldName = id.name;
-      AstNode classDecl = param.getAncestor((p) => p is ClassDeclaration);
-      if (classDecl is ClassDeclaration) {
-        for (ClassMember member in classDecl.members) {
-          if (member is FieldDeclaration) {
-            for (VariableDeclaration field in member.fields.variables) {
-              if (field.name.name == fieldName) {
-                return nameForType(member.fields.type);
-              }
-            }
-          }
-        }
-      }
-    }
-    return DYNAMIC;
-  }
-}
-
-/**
- * A visitor for collecting suggestions for break and continue labels.
- */
-class _LabelVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-
-  /**
-   * True if statement labels should be included as suggestions.
-   */
-  final bool includeStatementLabels;
-
-  /**
-   * True if case labels should be included as suggestions.
-   */
-  final bool includeCaseLabels;
-
-  _LabelVisitor(DartCompletionRequest request, this.includeStatementLabels,
-      this.includeCaseLabels)
-      : super(request.offset),
-        request = request;
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    // ignored
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
-      CompletionSuggestion suggestion = _addSuggestion(label.label);
-      if (suggestion != null) {
-        suggestion.element = createElement(
-            request.source, protocol.ElementKind.LABEL, label.label,
-            returnType: NO_RETURN_TYPE);
-      }
-    }
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
-    // ignored
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    // ignored
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {
-    // ignored
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    // ignored
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression node) {
-    // Labels are only accessible within the local function, so stop visiting
-    // once we reach a function boundary.
-    finished();
-  }
-
-  @override
-  void visitMethodDeclaration(MethodDeclaration node) {
-    // Labels are only accessible within the local function, so stop visiting
-    // once we reach a function boundary.
-    finished();
-  }
-
-  CompletionSuggestion _addSuggestion(SimpleIdentifier id) {
-    if (id != null) {
-      String completion = id.name;
-      if (completion != null && completion.length > 0 && completion != '_') {
-        CompletionSuggestion suggestion = new CompletionSuggestion(
-            CompletionSuggestionKind.IDENTIFIER,
-            DART_RELEVANCE_DEFAULT,
-            completion,
-            completion.length,
-            0,
-            false,
-            false);
-        request.addSuggestion(suggestion);
-        return suggestion;
-      }
-    }
-    return null;
-  }
-}
-
-/**
- * A visitor for collecting suggestions from the most specific child [AstNode]
- * that contains the completion offset to the [CompilationUnit].
- */
-class _LocalVisitor extends LocalDeclarationVisitor {
-  final DartCompletionRequest request;
-  final OpType optype;
-  int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
-
-  _LocalVisitor(this.request, int offset, this.optype) : super(offset) {
-    includeLocalInheritedTypes = !optype.inStaticMethodBody;
-    if (request.replacementLength > 0) {
-      var contents = request.context.getContents(request.source);
-      if (contents != null &&
-          contents.data != null &&
-          contents.data.startsWith('_', request.replacementOffset)) {
-        // If user typed identifier starting with '_'
-        // then do not suppress the relevance of private members
-        privateMemberRelevance = null;
-      }
-    }
-  }
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(
-          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.CLASS,
-          isAbstract: declaration.isAbstract,
-          isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(declaration.name, NO_RETURN_TYPE,
-          protocol.ElementKind.CLASS_TYPE_ALIAS,
-          isAbstract: true, isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredEnum(EnumDeclaration declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      _addSuggestion(
-          declaration.name, NO_RETURN_TYPE, protocol.ElementKind.ENUM,
-          isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (optype.includeReturnValueSuggestions &&
-        (!optype.inStaticMethodBody || fieldDecl.isStatic)) {
-      CompletionSuggestion suggestion =
-          createFieldSuggestion(request.source, fieldDecl, varDecl);
-      if (suggestion != null) {
-        request.addSuggestion(suggestion);
-      }
-    }
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    if (optype.includeReturnValueSuggestions ||
-        optype.includeVoidReturnSuggestions) {
-      TypeName typeName = declaration.returnType;
-      protocol.ElementKind elemKind;
-      int relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
-        if (!optype.includeVoidReturnSuggestions) {
-          return;
-        }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
-          return;
-        }
-        elemKind = protocol.ElementKind.FUNCTION;
-        relevance = DART_RELEVANCE_LOCAL_FUNCTION;
-      }
-      _addSuggestion(declaration.name, typeName, elemKind,
-          isDeprecated: isDeprecated(declaration),
-          param: declaration.functionExpression.parameters,
-          relevance: relevance);
-    }
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (optype.includeTypeNameSuggestions) {
-      // TODO (danrubel) determine parameters and return type
-      _addSuggestion(declaration.name, declaration.returnType,
-          protocol.ElementKind.FUNCTION_TYPE_ALIAS,
-          isAbstract: true, isDeprecated: isDeprecated(declaration));
-    }
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    // ignored
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier id, TypeName typeName) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(id, typeName, protocol.ElementKind.LOCAL_VARIABLE,
-          relevance: DART_RELEVANCE_LOCAL_VARIABLE);
-    }
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    if ((optype.includeReturnValueSuggestions ||
-            optype.includeVoidReturnSuggestions) &&
-        (!optype.inStaticMethodBody || declaration.isStatic)) {
-      protocol.ElementKind elemKind;
-      FormalParameterList param;
-      TypeName typeName = declaration.returnType;
-      int relevance = DART_RELEVANCE_DEFAULT;
-      if (declaration.isGetter) {
-        elemKind = protocol.ElementKind.GETTER;
-        param = null;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else if (declaration.isSetter) {
-        if (!optype.includeVoidReturnSuggestions) {
-          return;
-        }
-        elemKind = protocol.ElementKind.SETTER;
-        typeName = NO_RETURN_TYPE;
-        relevance = DART_RELEVANCE_LOCAL_ACCESSOR;
-      } else {
-        if (!optype.includeVoidReturnSuggestions && _isVoid(typeName)) {
-          return;
-        }
-        elemKind = protocol.ElementKind.METHOD;
-        param = declaration.parameters;
-        relevance = DART_RELEVANCE_LOCAL_METHOD;
-      }
-      _addSuggestion(declaration.name, typeName, elemKind,
-          isAbstract: declaration.isAbstract,
-          isDeprecated: isDeprecated(declaration),
-          classDecl: declaration.parent,
-          param: param,
-          relevance: relevance);
-    }
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier id, TypeName typeName) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(id, typeName, protocol.ElementKind.PARAMETER,
-          relevance: DART_RELEVANCE_PARAMETER);
-    }
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (optype.includeReturnValueSuggestions) {
-      _addSuggestion(
-          varDecl.name, varList.type, protocol.ElementKind.TOP_LEVEL_VARIABLE,
-          isDeprecated: isDeprecated(varList) || isDeprecated(varDecl),
-          relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
-    }
-  }
-
-  void _addParameterInfo(
-      CompletionSuggestion suggestion, FormalParameterList parameters) {
-    var paramList = parameters.parameters;
-    suggestion.parameterNames = paramList
-        .map((FormalParameter param) => param.identifier.name)
-        .toList();
-    suggestion.parameterTypes = paramList.map((FormalParameter param) {
-      TypeName type = null;
-      if (param is DefaultFormalParameter) {
-        NormalFormalParameter child = param.parameter;
-        if (child is SimpleFormalParameter) {
-          type = child.type;
-        } else if (child is FieldFormalParameter) {
-          type = child.type;
-        }
-      }
-      if (param is SimpleFormalParameter) {
-        type = param.type;
-      } else if (param is FieldFormalParameter) {
-        type = param.type;
-      }
-      if (type == null) {
-        return 'dynamic';
-      }
-      Identifier typeId = type.name;
-      if (typeId == null) {
-        return 'dynamic';
-      }
-      return typeId.name;
-    }).toList();
-    suggestion.requiredParameterCount = paramList
-        .where((FormalParameter param) => param is! DefaultFormalParameter)
-        .length;
-    suggestion.hasNamedParameters = paramList
-        .any((FormalParameter param) => param.kind == ParameterKind.NAMED);
-  }
-
-  void _addSuggestion(
-      SimpleIdentifier id, TypeName typeName, protocol.ElementKind elemKind,
-      {bool isAbstract: false,
-      bool isDeprecated: false,
-      ClassDeclaration classDecl,
-      FormalParameterList param,
-      int relevance: DART_RELEVANCE_DEFAULT}) {
-    CompletionSuggestion suggestion = createSuggestion(
-        id, isDeprecated, relevance, typeName,
-        classDecl: classDecl);
-    if (suggestion != null) {
-      if (privateMemberRelevance != null &&
-          suggestion.completion.startsWith('_')) {
-        suggestion.relevance = privateMemberRelevance;
-      }
-      request.addSuggestion(suggestion);
-      suggestion.element = createElement(request.source, elemKind, id,
-          isAbstract: isAbstract,
-          isDeprecated: isDeprecated,
-          parameters: param != null ? param.toSource() : null,
-          returnType: typeName);
-      if ((elemKind == protocol.ElementKind.METHOD ||
-              elemKind == protocol.ElementKind.FUNCTION) &&
-          param != null) {
-        _addParameterInfo(suggestion, param);
-      }
-    }
-  }
-
-  bool _isVoid(TypeName returnType) {
-    if (returnType != null) {
-      Identifier id = returnType.name;
-      if (id != null && id.name == 'void') {
-        return true;
-      }
-    }
-    return false;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
deleted file mode 100644
index 4981136..0000000
--- a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
+++ /dev/null
@@ -1,139 +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.
-
-library services.completion.suggestion.builder.local;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-const DYNAMIC = 'dynamic';
-
-final TypeName NO_RETURN_TYPE = new TypeName(
-    new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), null);
-
-/**
- * Create a new protocol Element for inclusion in a completion suggestion.
- */
-protocol.Element createElement(
-    Source source, protocol.ElementKind kind, SimpleIdentifier id,
-    {String parameters,
-    TypeName returnType,
-    bool isAbstract: false,
-    bool isDeprecated: false}) {
-  String name;
-  Location location;
-  if (id != null) {
-    name = id.name;
-    // TODO(danrubel) use lineInfo to determine startLine and startColumn
-    location = new Location(source.fullName, id.offset, id.length, 0, 0);
-  } else {
-    name = '';
-    location = new Location(source.fullName, -1, 0, 1, 0);
-  }
-  int flags = protocol.Element.makeFlags(
-      isAbstract: isAbstract,
-      isDeprecated: isDeprecated,
-      isPrivate: Identifier.isPrivateName(name));
-  return new protocol.Element(kind, name, flags,
-      location: location,
-      parameters: parameters,
-      returnType: nameForType(returnType));
-}
-
-/**
- * Create a new suggestion for the given field.
- * Return the new suggestion or `null` if it could not be created.
- */
-CompletionSuggestion createFieldSuggestion(
-    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-  bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
-  TypeName type = fieldDecl.fields.type;
-  return createSuggestion(
-      varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
-      classDecl: fieldDecl.parent,
-      element: createElement(source, protocol.ElementKind.FIELD, varDecl.name,
-          returnType: type, isDeprecated: deprecated));
-}
-
-/**
- * Create a new suggestion based upon the given information.
- * Return the new suggestion or `null` if it could not be created.
- */
-CompletionSuggestion createSuggestion(SimpleIdentifier id, bool isDeprecated,
-    int defaultRelevance, TypeName returnType,
-    {ClassDeclaration classDecl, protocol.Element element}) {
-  if (id == null) {
-    return null;
-  }
-  String completion = id.name;
-  if (completion == null || completion.length <= 0 || completion == '_') {
-    return null;
-  }
-  CompletionSuggestion suggestion = new CompletionSuggestion(
-      CompletionSuggestionKind.INVOCATION,
-      isDeprecated ? DART_RELEVANCE_LOW : defaultRelevance,
-      completion,
-      completion.length,
-      0,
-      isDeprecated,
-      false,
-      returnType: nameForType(returnType),
-      element: element);
-  if (classDecl != null) {
-    SimpleIdentifier classId = classDecl.name;
-    if (classId != null) {
-      String className = classId.name;
-      if (className != null && className.length > 0) {
-        suggestion.declaringType = className;
-      }
-    }
-  }
-  return suggestion;
-}
-
-/**
- * Return `true` if the @deprecated annotation is present
- */
-bool isDeprecated(AnnotatedNode node) {
-  if (node != null) {
-    NodeList<Annotation> metadata = node.metadata;
-    if (metadata != null) {
-      return metadata.any((Annotation a) {
-        return a.name is SimpleIdentifier && a.name.name == 'deprecated';
-      });
-    }
-  }
-  return false;
-}
-
-/**
- * Return the name for the given type.
- */
-String nameForType(TypeName type) {
-  if (type == NO_RETURN_TYPE) {
-    return null;
-  }
-  if (type == null) {
-    return DYNAMIC;
-  }
-  Identifier id = type.name;
-  if (id == null) {
-    return DYNAMIC;
-  }
-  String name = id.name;
-  if (name == null || name.length <= 0) {
-    return DYNAMIC;
-  }
-  TypeArgumentList typeArgs = type.typeArguments;
-  if (typeArgs != null) {
-    //TODO (danrubel) include type arguments
-  }
-  return name;
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
index 768b0d3..9acbf07 100644
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 
 /**
  * An [AstVisitor] for determining whether top level suggestions or invocation
@@ -57,6 +58,11 @@
   bool isPrefixed = false;
 
   /**
+   * The suggested completion kind.
+   */
+  CompletionSuggestionKind suggestKind = CompletionSuggestionKind.INVOCATION;
+
+  /**
    * Determine the suggestions that should be made based upon the given
    * [CompletionTarget] and [offset].
    */
@@ -206,6 +212,7 @@
     optype.includeReturnValueSuggestions = true;
     optype.includeTypeNameSuggestions = true;
     optype.includeVoidReturnSuggestions = true;
+    optype.suggestKind = CompletionSuggestionKind.IDENTIFIER;
   }
 
   void visitCompilationUnit(CompilationUnit node) {
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
deleted file mode 100644
index 4379e7f..0000000
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ /dev/null
@@ -1,189 +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.
-
-library services.completion.suggestion.builder;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
-    show createSuggestion;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-export 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
-    show createSuggestion;
-
-const String DYNAMIC = 'dynamic';
-
-/**
- * Call the given function with each non-null non-empty inherited type name
- * that is defined in the given class.
- */
-visitInheritedTypeNames(ClassDeclaration node, void inherited(String name)) {
-  void visit(TypeName type) {
-    if (type != null) {
-      Identifier id = type.name;
-      if (id != null) {
-        String name = id.name;
-        if (name != null && name.length > 0) {
-          inherited(name);
-        }
-      }
-    }
-  }
-
-  ExtendsClause extendsClause = node.extendsClause;
-  if (extendsClause != null) {
-    visit(extendsClause.superclass);
-  }
-  ImplementsClause implementsClause = node.implementsClause;
-  if (implementsClause != null) {
-    NodeList<TypeName> interfaces = implementsClause.interfaces;
-    if (interfaces != null) {
-      interfaces.forEach((TypeName type) {
-        visit(type);
-      });
-    }
-  }
-  WithClause withClause = node.withClause;
-  if (withClause != null) {
-    NodeList<TypeName> mixinTypes = withClause.mixinTypes;
-    if (mixinTypes != null) {
-      mixinTypes.forEach((TypeName type) {
-        visit(type);
-      });
-    }
-  }
-}
-
-/**
- * Starting with the given class node, traverse the inheritance hierarchy
- * calling the given functions with each non-null non-empty inherited class
- * declaration. For each locally defined declaration, call [localDeclaration].
- * For each class identifier in the hierarchy that is not defined locally,
- * call the [importedTypeName] function.
- */
-void visitInheritedTypes(ClassDeclaration node,
-    {void localDeclaration(ClassDeclaration classNode),
-    void importedTypeName(String typeName)}) {
-  CompilationUnit unit = node.getAncestor((p) => p is CompilationUnit);
-  List<ClassDeclaration> todo = new List<ClassDeclaration>();
-  todo.add(node);
-  Set<String> visited = new Set<String>();
-  while (todo.length > 0) {
-    node = todo.removeLast();
-    visitInheritedTypeNames(node, (String name) {
-      if (visited.add(name)) {
-        var classNode = unit.declarations.firstWhere((member) {
-          if (member is ClassDeclaration) {
-            SimpleIdentifier id = member.name;
-            if (id != null && id.name == name) {
-              return true;
-            }
-          }
-          return false;
-        }, orElse: () => null);
-        if (classNode is ClassDeclaration) {
-          if (localDeclaration != null) {
-            localDeclaration(classNode);
-          }
-          todo.add(classNode);
-        } else {
-          if (importedTypeName != null) {
-            importedTypeName(name);
-          }
-        }
-      }
-    });
-  }
-}
-
-/**
- * Common mixin for sharing behavior
- */
-abstract class ElementSuggestionBuilder {
-  /**
-   * Return the kind of suggestions that should be built.
-   */
-  CompletionSuggestionKind get kind;
-
-  /**
-   * Return the request on which the builder is operating.
-   */
-  DartCompletionRequest get request;
-
-  /**
-   * Add a suggestion based upon the given element.
-   */
-  void addSuggestion(Element element,
-      {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      LibraryElement elementLibrary = element.library;
-      CompilationUnitElement unitElem = request.unit.element;
-      if (unitElem == null) {
-        return;
-      }
-      LibraryElement unitLibrary = unitElem.library;
-      if (elementLibrary != unitLibrary) {
-        return;
-      }
-    }
-    if (prefix == null && element.isSynthetic) {
-      if ((element is PropertyAccessorElement) ||
-          element is FieldElement && !_isSpecialEnumField(element)) {
-        return;
-      }
-    }
-    String completion = element.displayName;
-    if (prefix != null && prefix.length > 0) {
-      if (completion == null || completion.length <= 0) {
-        completion = prefix;
-      } else {
-        completion = '$prefix.$completion';
-      }
-    }
-    if (completion == null || completion.length <= 0) {
-      return;
-    }
-    CompletionSuggestion suggestion = createSuggestion(element,
-        completion: completion, kind: kind, relevance: relevance);
-    if (suggestion != null) {
-      request.addSuggestion(suggestion);
-    }
-  }
-
-  /**
-   * Determine if the given element is one of the synthetic enum accessors
-   * for which we should generate a suggestion.
-   */
-  bool _isSpecialEnumField(FieldElement element) {
-    Element parent = element.enclosingElement;
-    if (parent is ClassElement && parent.isEnum) {
-      if (element.name == 'values') {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * Common interface implemented by suggestion builders.
- */
-abstract class SuggestionBuilder {
-  /**
-   * Compute suggestions and return `true` if building is complete,
-   * or `false` if [computeFull] should be called.
-   */
-  bool computeFast(AstNode node);
-
-  /**
-   * Return a future that computes the suggestions given a fully resolved AST.
-   * The future returns `true` if suggestions were added, else `false`.
-   */
-  Future<bool> computeFull(AstNode node);
-}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 00c48a3..a683638 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -17,8 +17,9 @@
 import 'package:analysis_server/src/services/correction/statement_analyzer.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -962,7 +963,7 @@
         variableList.type != null ? _getNodeText(variableList.type) + ' ' : '';
     String getterCode = '$eol2  ${typeNameCode}get $name => _$name;';
     String setterCode = '$eol2'
-        '  void set $name(${typeNameCode}$name) {$eol'
+        '  void set $name($typeNameCode$name) {$eol'
         '    _$name = $name;$eol'
         '  }';
     _addInsertEdit(fieldDeclaration.end, getterCode + setterCode);
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 18465d0..50d437c 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -24,9 +24,13 @@
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -35,6 +39,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
 import 'package:path/path.dart';
 
 /**
@@ -235,15 +240,19 @@
     if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
       _addFix_createConstructor_named();
     }
-    if (errorCode == StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
+    if (errorCode ==
+            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
         errorCode ==
             StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR ||
         errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
+            StaticWarningCode
+                .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS) {
       // make class abstract
       _addFix_makeEnclosingClassAbstract();
       // implement methods
@@ -1451,7 +1460,7 @@
             sdkSourceFactory.resolveUri(unitSource, libraryUri);
         // prepare LibraryElement
         LibraryElement libraryElement =
-            context.getLibraryElement(librarySource);
+            context.getResult(librarySource, LIBRARY_ELEMENT1);
         if (libraryElement == null) {
           continue;
         }
@@ -1484,7 +1493,7 @@
         }
         // prepare LibraryElement
         LibraryElement libraryElement =
-            context.getLibraryElement(librarySource);
+            context.getResult(librarySource, LIBRARY_ELEMENT8);
         if (libraryElement == null) {
           continue;
         }
diff --git a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
index 5234405..1c80559 100644
--- a/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
+++ b/pkg/analysis_server/lib/src/services/correction/name_suggestion.dart
@@ -5,8 +5,9 @@
 library services.src.correction.name_suggestion;
 
 import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 List<String> _KNOWN_METHOD_NAME_PREFIXES = ['get', 'is', 'to'];
 
diff --git a/pkg/analysis_server/lib/src/services/correction/namespace.dart b/pkg/analysis_server/lib/src/services/correction/namespace.dart
index 1ca99ba..f1086fc 100644
--- a/pkg/analysis_server/lib/src/services/correction/namespace.dart
+++ b/pkg/analysis_server/lib/src/services/correction/namespace.dart
@@ -4,8 +4,8 @@
 
 library services.src.correction.namespace;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/correction/source_range.dart b/pkg/analysis_server/lib/src/services/correction/source_range.dart
index 779dde7..bf52759 100644
--- a/pkg/analysis_server/lib/src/services/correction/source_range.dart
+++ b/pkg/analysis_server/lib/src/services/correction/source_range.dart
@@ -4,8 +4,8 @@
 
 library services.src.correction.source_range_factory;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index e7c8361..c25f77a 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -9,8 +9,8 @@
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 434c3fe..33a3105 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -12,9 +12,9 @@
     show doSourceChange_addElementEdit;
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
-import 'package:analysis_server/src/services/search/element_visitors.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -667,20 +667,9 @@
     AstNode enclosingNode = findNode(offset);
     Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
     if (enclosingBlock != null) {
-      SourceRange newRange = rangeStartEnd(offset, enclosingBlock.end);
-      ExecutableElement enclosingExecutable =
-          getEnclosingExecutableElement(enclosingNode);
-      if (enclosingExecutable != null) {
-        visitChildren(enclosingExecutable, (Element element) {
-          if (element is LocalElement) {
-            SourceRange elementRange = element.visibleRange;
-            if (elementRange != null && elementRange.intersects(newRange)) {
-              conflicts.add(element.displayName);
-            }
-          }
-          return true;
-        });
-      }
+      _CollectReferencedUnprefixedNames visitor = new _CollectReferencedUnprefixedNames();
+      enclosingBlock.accept(visitor);
+      return visitor.names;
     }
     return conflicts;
   }
@@ -726,7 +715,7 @@
       result.offset = prevDirective.end;
       String eol = endOfLine;
       if (prevDirective is LibraryDirective) {
-        result.prefix = "${eol}${eol}";
+        result.prefix = "$eol$eol";
       } else {
         result.prefix = eol;
       }
@@ -753,7 +742,7 @@
       if (prevDirective is PartDirective) {
         result.prefix = eol;
       } else {
-        result.prefix = "${eol}${eol}";
+        result.prefix = "$eol$eol";
       }
       return result;
     }
@@ -1133,7 +1122,7 @@
       }
       // update line
       if (right) {
-        line = "${indent}${line}";
+        line = "$indent$line";
       } else {
         line = removeStart(line, indent);
       }
@@ -1204,7 +1193,7 @@
       lineOffset += line.length + eol.length;
       // update line indent
       if (!inString) {
-        line = "${newIndent}${removeStart(line, oldIndent)}";
+        line = "$newIndent${removeStart(line, oldIndent)}";
       }
       // append line
       sb.write(line);
@@ -1299,11 +1288,9 @@
       String expressionSource = getNodeText(isExpression.expression);
       String typeSource = getNodeText(isExpression.type);
       if (isExpression.notOperator == null) {
-        return _InvertedCondition
-            ._simple("${expressionSource} is! ${typeSource}");
+        return _InvertedCondition._simple("$expressionSource is! $typeSource");
       } else {
-        return _InvertedCondition
-            ._simple("${expressionSource} is ${typeSource}");
+        return _InvertedCondition._simple("$expressionSource is $typeSource");
       }
     }
     if (expression is PrefixExpression) {
@@ -1438,6 +1425,26 @@
       tokens.length == 1 && tokens[0].type == type;
 }
 
+class _CollectReferencedUnprefixedNames extends RecursiveAstVisitor {
+  final Set<String> names = new Set<String>();
+
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (!_isPrefixed(node)) {
+      names.add(node.name);
+    }
+  }
+
+  static bool _isPrefixed(SimpleIdentifier node) {
+    AstNode parent = node.parent;
+    return parent is ConstructorName && parent.name == node ||
+        parent is MethodInvocation &&
+            parent.methodName == node &&
+            parent.realTarget != null ||
+        parent is PrefixedIdentifier && parent.identifier == node ||
+        parent is PropertyAccess && parent.target == node;
+  }
+}
+
 /**
  * A container with a source and its precedence.
  */
@@ -1460,7 +1467,7 @@
       _InvertedCondition left, String operation, _InvertedCondition right) {
     // TODO(scheglov) consider merging with "_binary()" after testing
     return new _InvertedCondition(
-        1 << 20, "${left._source}${operation}${right._source}");
+        1 << 20, "${left._source}$operation${right._source}");
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart b/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
index e55993d..0c30918 100644
--- a/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
+++ b/pkg/analysis_server/lib/src/services/dependencies/library_dependencies.dart
@@ -4,8 +4,8 @@
 
 library services.dependencies.library;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -42,13 +42,6 @@
     return _dependencies;
   }
 
-  Map<AnalysisContext, Folder> _reverse(Map<Folder, AnalysisContext> map) {
-    Map<AnalysisContext, Folder> reverseMap =
-        new Map<AnalysisContext, Folder>();
-    map.forEach((Folder f, AnalysisContext c) => reverseMap[c] = f);
-    return reverseMap;
-  }
-
   void _addDependencies(LibraryElement libraryElement) {
     if (libraryElement == null) {
       return;
@@ -66,4 +59,11 @@
           (ExportElement export) => _addDependencies(export.exportedLibrary));
     }
   }
+
+  Map<AnalysisContext, Folder> _reverse(Map<Folder, AnalysisContext> map) {
+    Map<AnalysisContext, Folder> reverseMap =
+        new Map<AnalysisContext, Folder>();
+    map.forEach((Folder f, AnalysisContext c) => reverseMap[c] = f);
+    return reverseMap;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index cad43a2..d86b322 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -8,7 +8,7 @@
 
 import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
@@ -307,7 +307,7 @@
     if (isResolved) {
       flagsStr += ' resolved';
     }
-    return '[${offset} - ${(offset + length)}) $flagsStr in ${indexable}';
+    return '[$offset - ${offset + length}) $flagsStr in $indexable';
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/index/index_contributor.dart b/pkg/analysis_server/lib/src/services/index/index_contributor.dart
index fdcd8fa..b5eee6b 100644
--- a/pkg/analysis_server/lib/src/services/index/index_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/index/index_contributor.dart
@@ -12,8 +12,9 @@
 import 'package:analysis_server/src/services/index/index_store.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/index_store.dart b/pkg/analysis_server/lib/src/services/index/index_store.dart
index 18f80bc..f5bebe1 100644
--- a/pkg/analysis_server/lib/src/services/index/index_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/index_store.dart
@@ -6,7 +6,7 @@
 
 import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/index/indexable_element.dart b/pkg/analysis_server/lib/src/services/index/indexable_element.dart
index df10370..916a099 100644
--- a/pkg/analysis_server/lib/src/services/index/indexable_element.dart
+++ b/pkg/analysis_server/lib/src/services/index/indexable_element.dart
@@ -7,7 +7,7 @@
 import 'dart:collection';
 
 import 'package:analysis_server/src/provisional/index/index_core.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analysis_server/lib/src/services/index/local_index.dart b/pkg/analysis_server/lib/src/services/index/local_index.dart
index 115b3e1..34c0e76 100644
--- a/pkg/analysis_server/lib/src/services/index/local_index.dart
+++ b/pkg/analysis_server/lib/src/services/index/local_index.dart
@@ -9,7 +9,7 @@
 import 'package:analysis_server/src/provisional/index/index_core.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
index 85dedd2..86e463b 100644
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
@@ -15,8 +15,8 @@
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:analysis_server/src/services/index/store/collection.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show CompilationUnit;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -168,7 +168,7 @@
     String unitName = unit.fullName;
     int libraryNameIndex = site.encodeString(libraryName);
     int unitNameIndex = site.encodeString(unitName);
-    return 'DartUnitElement_${libraryNameIndex}_${unitNameIndex}.index';
+    return 'DartUnitElement_${libraryNameIndex}_$unitNameIndex.index';
   }
 
   void _recordLibraryWithUnit(
@@ -271,7 +271,7 @@
       _DataInputStream stream = new _DataInputStream(bytes);
       return _readNode(stream);
     }).catchError((exception, stackTrace) {
-      _logger.logError('Exception during reading index file ${name}',
+      _logger.logError('Exception during reading index file $name',
           new CaughtException(exception, stackTrace));
     });
   }
@@ -305,7 +305,7 @@
         return _fileManager.write(name, bytes);
       });
     }).catchError((exception, stackTrace) {
-      _logger.logError('Exception during reading index file ${name}',
+      _logger.logError('Exception during reading index file $name',
           new CaughtException(exception, stackTrace));
     });
   }
@@ -349,8 +349,7 @@
     {
       int version = stream.readInt();
       if (version != _VERSION) {
-        throw new StateError(
-            'Version ${_VERSION} expected, but ${version} found.');
+        throw new StateError('Version $_VERSION expected, but $version found.');
       }
     }
     // context
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
index aabe616..51db1c2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_getter_to_method.dart
@@ -14,7 +14,7 @@
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
index 0bcf9c2..59803be 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/convert_method_to_getter.dart
@@ -13,8 +13,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index f238cd5..ca90fd2 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -17,8 +17,8 @@
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -76,11 +76,7 @@
   @override
   Future<RefactoringStatus> checkFinalConditions() {
     RefactoringStatus result = new RefactoringStatus();
-    if (excludedVariableNames.contains(name)) {
-      result.addWarning(format(
-          "A variable with name '{0}' is already defined in the visible scope.",
-          name));
-    }
+    result.addStatus(checkName());
     return new Future.value(result);
   }
 
@@ -105,7 +101,13 @@
 
   @override
   RefactoringStatus checkName() {
-    return validateVariableName(name);
+    RefactoringStatus result = new RefactoringStatus();
+    result.addStatus(validateVariableName(name));
+    if (excludedVariableNames.contains(name)) {
+      result.addError(
+          format("The name '{0}' is already used in the scope.", name));
+    }
+    return result;
   }
 
   @override
@@ -232,6 +234,21 @@
         node is Expression || node is ArgumentList;
         node = node.parent) {
       AstNode parent = node.parent;
+      // stop at void method invocations
+      if (node is MethodInvocation) {
+        MethodInvocation invocation = node;
+        Element element = invocation.methodName.bestElement;
+        if (element is ExecutableElement &&
+            element.returnType != null &&
+            element.returnType.isVoid) {
+          if (rootExpression == null) {
+            return new RefactoringStatus.fatal(
+                'Cannot extract the void expression.',
+                newLocation_fromNode(node));
+          }
+          break;
+        }
+      }
       // skip ArgumentList
       if (node is ArgumentList) {
         continue;
@@ -281,7 +298,8 @@
     }
     // part of string literal
     if (coveringNode is StringLiteral) {
-      if (selectionRange.offset > coveringNode.offset &&
+      if (selectionRange.length != 0 &&
+          selectionRange.offset > coveringNode.offset &&
           selectionRange.end < coveringNode.end) {
         stringLiteralPart = selectionStr;
         return new RefactoringStatus();
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
index e83082b..6135237 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -20,8 +20,9 @@
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart' show ExitDetector;
@@ -219,10 +220,10 @@
   Future<SourceChange> createChange() async {
     SourceChange change = new SourceChange(refactoringName);
     // replace occurrences with method invocation
-    for (_Occurrence occurence in _occurrences) {
-      SourceRange range = occurence.range;
+    for (_Occurrence occurrence in _occurrences) {
+      SourceRange range = occurrence.range;
       // may be replacement of duplicates disabled
-      if (!extractAll && !occurence.isSelection) {
+      if (!extractAll && !occurrence.isSelection) {
         continue;
       }
       // prepare invocation source
@@ -236,7 +237,7 @@
           // single variable assignment / return statement
           if (_returnVariableName != null) {
             String occurrenceName =
-                occurence._parameterOldToOccurrenceName[_returnVariableName];
+                occurrence._parameterOldToOccurrenceName[_returnVariableName];
             // may be declare variable
             if (!_parametersMap.containsKey(_returnVariableName)) {
               if (variableType.isEmpty) {
@@ -272,7 +273,7 @@
             // argument name
             {
               String argumentName =
-                  occurence._parameterOldToOccurrenceName[parameter.id];
+                  occurrence._parameterOldToOccurrenceName[parameter.id];
               sb.write(argumentName);
             }
           }
@@ -307,7 +308,7 @@
         String returnExpressionSource = _getMethodBodySource();
         // closure
         if (_selectionFunctionExpression != null) {
-          declarationSource = '${name}${returnExpressionSource}';
+          declarationSource = '$name$returnExpressionSource';
           if (_selectionFunctionExpression.body is ExpressionFunctionBody) {
             declarationSource += ';';
           }
@@ -332,17 +333,16 @@
           declarationSource = '$annotations$signature$asyncKeyword {$eol';
           declarationSource += returnExpressionSource;
           if (_returnVariableName != null) {
-            declarationSource +=
-                '${prefix}  return ${_returnVariableName};$eol';
+            declarationSource += '$prefix  return $_returnVariableName;$eol';
           }
-          declarationSource += '${prefix}}';
+          declarationSource += '$prefix}';
         }
       }
       // insert declaration
       if (declarationSource != null) {
         int offset = _parentMember.end;
-        SourceEdit edit = new SourceEdit(
-            offset, 0, '${eol}${eol}${prefix}${declarationSource}');
+        SourceEdit edit =
+            new SourceEdit(offset, 0, '$eol$eol$prefix$declarationSource');
         doSourceChange_addElementEdit(change, unitElement, edit);
       }
     }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
index f0a345a..1fe699a 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_local.dart
@@ -13,8 +13,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
index 7c7e6356..3b3c786 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -16,8 +16,8 @@
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -523,7 +523,7 @@
             ref._methodExpressionPart, _refUtils, usage, target, arguments);
         if (getExpressionPrecedence(ref._methodExpression) <
             getExpressionParentPrecedence(usage)) {
-          source = "(${source})";
+          source = "($source)";
         }
         // do replace
         SourceRange methodUsageRange = rangeNode(usage);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index d5663403..4a25e6d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -12,8 +12,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:path/path.dart' as pathos;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index baeab25..5bf3194 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -24,9 +24,9 @@
 import 'package:analysis_server/src/services/refactoring/rename_local.dart';
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
index fbff2f6..f435ff9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring_internal.dart
@@ -11,7 +11,7 @@
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -101,5 +101,5 @@
   }
 
   @override
-  String toString() => '${file}@${range}';
+  String toString() => '$file@$range';
 }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index a9bdb74..ec36d00 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -13,7 +13,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 12d8aee..6080479 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -16,8 +16,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show Identifier;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index d5c489a..460896e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -16,7 +16,7 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -59,7 +59,7 @@
       // append declaration
       references.add(_createDeclarationReference());
       // update references
-      String replacement = newName.isEmpty ? '' : '.${newName}';
+      String replacement = newName.isEmpty ? '' : '.$newName';
       for (SourceReference reference in references) {
         reference.addEdit(change, replacement);
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
index 4dcd752..d82a56d 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_import.dart
@@ -14,8 +14,8 @@
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -60,7 +60,7 @@
       } else {
         if (prefix == null) {
           SourceRange range = rangeStartLength(element.uriEnd, 0);
-          edit = newSourceEdit_range(range, " as ${newName}");
+          edit = newSourceEdit_range(range, " as $newName");
         } else {
           int offset = element.prefixOffset;
           int length = prefix.nameLength;
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
index 7776b00..71c9026 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_label.dart
@@ -11,7 +11,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 /**
  * A [Refactoring] for renaming [LabelElement]s.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
index 54b6948..831fadb 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_library.dart
@@ -12,7 +12,7 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 
 /**
  * A [Refactoring] for renaming [LibraryElement]s.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
index 2d1b221..4f1f150 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_local.dart
@@ -14,8 +14,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -142,7 +142,7 @@
           haveIntersectingRanges(refactoring.element, nodeElement)) {
         conflictingLocals.add(nodeElement);
         String nodeKind = nodeElement.kind.displayName;
-        String message = "Duplicate ${nodeKind} '$newName'.";
+        String message = "Duplicate $nodeKind '$newName'.";
         result.addError(message, newLocation_fromElement(nodeElement));
         return;
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
index 8ab7de3..4f59af7 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_unit_member.dart
@@ -15,8 +15,8 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' show Identifier;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 
 /**
@@ -26,7 +26,8 @@
 Future<RefactoringStatus> validateCreateFunction(
     SearchEngine searchEngine, LibraryElement library, String name) {
   return new _RenameUnitMemberValidator.forCreate(
-      searchEngine, library, ElementKind.FUNCTION, name).validate();
+          searchEngine, library, ElementKind.FUNCTION, name)
+      .validate();
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/search/element_visitors.dart b/pkg/analysis_server/lib/src/services/search/element_visitors.dart
index d7338d0..5448f3f 100644
--- a/pkg/analysis_server/lib/src/services/search/element_visitors.dart
+++ b/pkg/analysis_server/lib/src/services/search/element_visitors.dart
@@ -4,7 +4,8 @@
 
 library services.search.element_visitors;
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 
 /**
  * Uses [processor] to visit all of the children of [element].
diff --git a/pkg/analysis_server/lib/src/services/search/hierarchy.dart b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
index 496a4c0..f3ad992 100644
--- a/pkg/analysis_server/lib/src/services/search/hierarchy.dart
+++ b/pkg/analysis_server/lib/src/services/search/hierarchy.dart
@@ -9,7 +9,8 @@
 
 import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /**
  * Returns direct children of [parent].
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 4e294bd..dbae817 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -8,7 +8,7 @@
 
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
index 1e89981..12681f7 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine_internal.dart
@@ -11,7 +11,8 @@
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index 24c922d..aa6a406 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -9,7 +9,9 @@
 
 import 'package:analysis_server/src/status/get_handler.dart';
 import 'package:analysis_server/src/status/tree_writer.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 
 /**
  * A visitor that will produce an HTML representation of an element structure.
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 23126f9..360ad0d 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -26,12 +26,13 @@
 import 'package:analysis_server/src/status/element_writer.dart';
 import 'package:analysis_server/src/status/validator.dart';
 import 'package:analysis_server/src/utilities/average.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -57,6 +58,141 @@
  */
 typedef void HtmlGenerator(StringBuffer buffer);
 
+class ElementCounter extends RecursiveElementVisitor {
+  Map<Type, int> counts = new HashMap<Type, int>();
+  int elementsWithDocs = 0;
+  int totalDocSpan = 0;
+
+  void visit(Element element) {
+    SourceRange docRange = element.docRange;
+    if (docRange != null) {
+      ++elementsWithDocs;
+      totalDocSpan += docRange.length;
+    }
+
+    Type type = element.runtimeType;
+    if (counts[type] == null) {
+      counts[type] = 1;
+    } else {
+      counts[type]++;
+    }
+  }
+
+  @override
+  visitClassElement(ClassElement element) {
+    visit(element);
+    super.visitClassElement(element);
+  }
+
+  @override
+  visitCompilationUnitElement(CompilationUnitElement element) {
+    visit(element);
+    super.visitCompilationUnitElement(element);
+  }
+
+  @override
+  visitConstructorElement(ConstructorElement element) {
+    visit(element);
+    super.visitConstructorElement(element);
+  }
+
+  @override
+  visitExportElement(ExportElement element) {
+    visit(element);
+    super.visitExportElement(element);
+  }
+
+  @override
+  visitFieldElement(FieldElement element) {
+    visit(element);
+    super.visitFieldElement(element);
+  }
+
+  @override
+  visitFieldFormalParameterElement(FieldFormalParameterElement element) {
+    visit(element);
+    super.visitFieldFormalParameterElement(element);
+  }
+
+  @override
+  visitFunctionElement(FunctionElement element) {
+    visit(element);
+    super.visitFunctionElement(element);
+  }
+
+  @override
+  visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    visit(element);
+    super.visitFunctionTypeAliasElement(element);
+  }
+
+  @override
+  visitImportElement(ImportElement element) {
+    visit(element);
+    super.visitImportElement(element);
+  }
+
+  @override
+  visitLabelElement(LabelElement element) {
+    visit(element);
+    super.visitLabelElement(element);
+  }
+
+  @override
+  visitLibraryElement(LibraryElement element) {
+    visit(element);
+    super.visitLibraryElement(element);
+  }
+
+  @override
+  visitLocalVariableElement(LocalVariableElement element) {
+    visit(element);
+    super.visitLocalVariableElement(element);
+  }
+
+  @override
+  visitMethodElement(MethodElement element) {
+    visit(element);
+    super.visitMethodElement(element);
+  }
+
+  @override
+  visitMultiplyDefinedElement(MultiplyDefinedElement element) {
+    visit(element);
+    super.visitMultiplyDefinedElement(element);
+  }
+
+  @override
+  visitParameterElement(ParameterElement element) {
+    visit(element);
+    super.visitParameterElement(element);
+  }
+
+  @override
+  visitPrefixElement(PrefixElement element) {
+    visit(element);
+    super.visitPrefixElement(element);
+  }
+
+  @override
+  visitPropertyAccessorElement(PropertyAccessorElement element) {
+    visit(element);
+    super.visitPropertyAccessorElement(element);
+  }
+
+  @override
+  visitTopLevelVariableElement(TopLevelVariableElement element) {
+    visit(element);
+    super.visitTopLevelVariableElement(element);
+  }
+
+  @override
+  visitTypeParameterElement(TypeParameterElement element) {
+    visit(element);
+    super.visitTypeParameterElement(element);
+  }
+}
+
 /**
  * Instances of the class [GetHandler] handle GET requests.
  */
@@ -1693,6 +1829,13 @@
     var json = response.toJson()[Response.RESULT];
     List contexts = json['contexts'];
     contexts.sort((first, second) => first['name'].compareTo(second['name']));
+
+    // Track visited libraries.
+    Set<LibraryElement> libraries = new HashSet<LibraryElement>();
+
+    // Count SDK elements separately.
+    ElementCounter sdkCounter = new ElementCounter();
+
     for (var context in contexts) {
       buffer.write('<p><h3>');
       buffer.write(context['name']);
@@ -1706,10 +1849,52 @@
       buffer.write('<p>workItemQueueLength: ');
       buffer.write(context['workItemQueueLength']);
       buffer.write('</p>');
-      buffer.write('<p>workItemQueueLengthAverage: ');
-      buffer.write(context['workItemQueueLengthAverage']);
-      buffer.write('</p>');
+
+      AnalysisServer server = _server.analysisServer;
+
+      if (server != null) {
+        Folder folder = _findFolder(server, context['name']);
+        InternalAnalysisContext ac = _server.analysisServer.folderMap[folder];
+        ElementCounter counter = new ElementCounter();
+
+        for (Source source in ac.librarySources) {
+          LibraryElement libraryElement = ac.getLibraryElement(source);
+          if (libraries.add(libraryElement)) {
+            if (libraryElement != null) {
+              if (libraryElement.isInSdk) {
+                libraryElement.accept(sdkCounter);
+              } else {
+                libraryElement.accept(counter);
+              }
+            }
+          }
+        }
+        buffer.write('<p>element count: ');
+        buffer.write(
+            counter.counts.values.fold(0, (prev, element) => prev + element));
+        buffer.write('</p>');
+        buffer.write('<p>  (w/docs): ');
+        buffer.write(counter.elementsWithDocs);
+        buffer.write('</p>');
+        buffer.write('<p>total doc span: ');
+        buffer.write(counter.totalDocSpan);
+        buffer.write('</p>');
+      }
     }
+
+    buffer.write('<p><h3>');
+    buffer.write('SDK');
+    buffer.write('</h3></p>');
+    buffer.write('<p>element count: ');
+    buffer.write(
+        sdkCounter.counts.values.fold(0, (prev, element) => prev + element));
+    buffer.write('</p>');
+    buffer.write('<p>  (w/docs): ');
+    buffer.write(sdkCounter.elementsWithDocs);
+    buffer.write('</p>');
+    buffer.write('<p>total doc span: ');
+    buffer.write(sdkCounter.totalDocSpan);
+    buffer.write('</p>');
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index c862a8b..d50a78e 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -7,8 +7,9 @@
 import 'dart:convert';
 
 import 'package:analysis_server/src/status/get_handler.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
index dccf996..10dc8ac 100644
--- a/pkg/analysis_server/lib/src/status/validator.dart
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -6,11 +6,12 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisEngine, AnalysisResult, CacheState, ChangeSet;
 import 'package:analyzer/src/generated/error.dart';
diff --git a/pkg/analysis_server/lib/src/utilities/average.dart b/pkg/analysis_server/lib/src/utilities/average.dart
index a738d39..a20ad88 100644
--- a/pkg/analysis_server/lib/src/utilities/average.dart
+++ b/pkg/analysis_server/lib/src/utilities/average.dart
@@ -26,5 +26,5 @@
   }
 
   @override
-  String toString() => 'average: ${value}';
+  String toString() => 'average: $value';
 }
diff --git a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
index 56fc80f..bac921d 100644
--- a/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
+++ b/pkg/analysis_server/lib/src/utilities/change_builder_dart.dart
@@ -10,8 +10,9 @@
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/utilities/change_builder_core.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/lib/src/utilities/documentation.dart b/pkg/analysis_server/lib/src/utilities/documentation.dart
new file mode 100644
index 0000000..8e8e696
--- /dev/null
+++ b/pkg/analysis_server/lib/src/utilities/documentation.dart
@@ -0,0 +1,69 @@
+// 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 analysis_server.src.utilities.documentation;
+
+String getDartDocSummary(String str) {
+  if (str == null) {
+    return null;
+  }
+  List<String> lines = str.split('\n');
+  StringBuffer sb = new StringBuffer();
+  bool firstLine = true;
+  for (String line in lines) {
+    if (sb.length != 0 && line.isEmpty) {
+      return sb.toString();
+    }
+    if (!firstLine) {
+      sb.write('\n');
+    }
+    firstLine = false;
+    sb.write(line);
+  }
+  return sb.toString();
+}
+
+/**
+ * Converts [str] from a Dart Doc string with slashes and stars to a plain text
+ * representation of the comment.
+ */
+String removeDartDocDelimiters(String str) {
+  if (str == null) {
+    return null;
+  }
+  // remove /** */
+  if (str.startsWith('/**')) {
+    str = str.substring(3);
+  }
+  if (str.endsWith("*/")) {
+    str = str.substring(0, str.length - 2);
+  }
+  str = str.trim();
+  // remove leading '* ' and '/// '
+  List<String> lines = str.split('\n');
+  StringBuffer sb = new StringBuffer();
+  bool firstLine = true;
+  for (String line in lines) {
+    line = line.trim();
+    if (line.startsWith("*")) {
+      line = line.substring(1);
+      if (line.startsWith(" ")) {
+        line = line.substring(1);
+      }
+    } else if (line.startsWith("///")) {
+      line = line.substring(3);
+      if (line.startsWith(" ")) {
+        line = line.substring(1);
+      }
+    }
+    if (!firstLine) {
+      sb.write('\n');
+    }
+    firstLine = false;
+    sb.write(line);
+  }
+  str = sb.toString();
+  // done
+  return str;
+}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index d800ed4..dff1fd7 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,10 +6,10 @@
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.26.3 <0.27.0'
+  analyzer: ^0.27.0
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.2.0 <0.3.0'
-  linter: ^0.1.3+2
+  linter: ^0.1.10
   logging: any
   path: any
   plugin: <0.2.0
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index d96edc0..eded4062 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -4,11 +4,12 @@
 
 library testing.abstract_context;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart' show CaughtException;
 import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 757c819..4b0be0e 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -4,8 +4,8 @@
 
 library test.services.src.index.abstract_single_file;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index cc5befe..cc1a4e4 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -41,6 +41,35 @@
     createProject();
   }
 
+  test_class() async {
+    addTestFile('''
+class A<E> {}
+class I1<K, V> {}
+class I2<E> {}
+class M1 {}
+class M2<E> {}
+class B<T> extends A<T> with M1, M2<int> implements I1<int, String>, I2 {}
+''');
+    HoverInformation hover = await prepareHover('B<T>');
+    expect(
+        hover.elementDescription,
+        'class B<T> extends A<T> with M1, M2<int> '
+        'implements I1<int, String>, I2');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
+  test_class_abstract() async {
+    addTestFile('''
+class A {}
+abstract class B extends A {}
+''');
+    HoverInformation hover = await prepareHover('B extends');
+    expect(hover.elementDescription, 'abstract class B extends A');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
   test_dartdoc_clunky() async {
     addTestFile('''
 library my.library;
@@ -67,6 +96,16 @@
     expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
   }
 
+  test_enum() async {
+    addTestFile('''
+enum MyEnum {AAA, BBB, CCC}
+''');
+    HoverInformation hover = await prepareHover('MyEnum');
+    expect(hover.elementDescription, 'enum MyEnum');
+    expect(hover.staticType, isNull);
+    expect(hover.propagatedType, isNull);
+  }
+
   test_expression_function() async {
     addTestFile('''
 library my.library;
@@ -84,7 +123,7 @@
     expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
     expect(hover.elementKind, 'function');
     // types
-    expect(hover.staticType, '(int, String) → List<String>');
+    expect(hover.staticType, isNull);
     expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
@@ -128,7 +167,7 @@
     expect(hover.elementDescription, 'mmm(int a, String b) → List<String>');
     expect(hover.elementKind, 'method');
     // types
-    expect(hover.staticType, '(int, String) → List<String>');
+    expect(hover.staticType, isNull);
     expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
@@ -185,7 +224,7 @@
     expect(hover.parameter, isNull);
   }
 
-  test_expression_syntheticGetter() async {
+  test_expression_syntheticGetter_invocation() async {
     addTestFile('''
 library my.library;
 class A {
@@ -275,7 +314,7 @@
     expect(hover.elementDescription, 'A() → A');
     expect(hover.elementKind, 'constructor');
     // types
-    expect(hover.staticType, 'A');
+    expect(hover.staticType, isNull);
     expect(hover.propagatedType, isNull);
     // no parameter
     expect(hover.parameter, isNull);
@@ -300,7 +339,7 @@
       expect(hover.elementDescription, 'A() → A<String>');
       expect(hover.elementKind, 'constructor');
       // types
-      expect(hover.staticType, 'A<String>');
+      expect(hover.staticType, isNull);
       expect(hover.propagatedType, isNull);
       // no parameter
       expect(hover.parameter, isNull);
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 2e56daa..b1fd5f1 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -44,7 +44,7 @@
     }
     fail(
         'Expected to find target (file=$file; offset=$offset; length=$length) in\n'
-        '${testRegion} in\n'
+        '$testRegion in\n'
         '${testTargets.join('\n')}');
   }
 
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index 2465be3..ae7551e 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -71,6 +71,20 @@
   }
 
   /**
+   * Validates that there is no [Override] at the offset of [search].
+   *
+   * If [length] is not specified explicitly, then length of an identifier
+   * from [search] is used.
+   */
+  void assertNoOverride(String search, [int length = -1]) {
+    int offset = findOffset(search);
+    if (length == -1) {
+      length = findIdentifierLength(search);
+    }
+    findOverride(offset, length, false);
+  }
+
+  /**
    * Asserts that there are no overridden member from the superclass.
    */
   void assertNoSuperMember() {
@@ -137,6 +151,110 @@
     assertHasInterfaceMember('m() {} // in A');
   }
 
+  test_BAD_fieldByMethod() async {
+    addTestFile('''
+class A {
+  int fff; // in A
+}
+class B extends A {
+  fff() {} // in B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff() {} // in B');
+  }
+
+  test_BAD_getterByMethod() async {
+    addTestFile('''
+class A {
+  get fff => null;
+}
+class B extends A {
+  fff() {}
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff() {}');
+  }
+
+  test_BAD_getterBySetter() async {
+    addTestFile('''
+class A {
+  get fff => null;
+}
+class B extends A {
+  set fff(x) {}
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {}');
+  }
+
+  test_BAD_methodByField() async {
+    addTestFile('''
+class A {
+  fff() {} // in A
+}
+class B extends A {
+  int fff; // in B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff; // in B');
+  }
+
+  test_BAD_methodByGetter() async {
+    addTestFile('''
+class A {
+  fff() {}
+}
+class B extends A {
+  int get fff => null;
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff => null');
+  }
+
+  test_BAD_methodBySetter() async {
+    addTestFile('''
+class A {
+  fff(x) {} // A
+}
+class B extends A {
+  set fff(x) {} // B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {} // B');
+  }
+
+  test_BAD_setterByGetter() async {
+    addTestFile('''
+class A {
+  set fff(x) {}
+}
+class B extends A {
+  get fff => null;
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff => null;');
+  }
+
+  test_BAD_setterByMethod() async {
+    addTestFile('''
+class A {
+  set fff(x) {} // A
+}
+class B extends A {
+  fff(x) {} // B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('fff(x) {} // B');
+  }
+
   test_definedInInterface_ofInterface() async {
     addTestFile('''
 class A {
@@ -318,21 +436,6 @@
     assertNoInterfaceMembers();
   }
 
-  test_super_fieldByMethod() async {
-    addTestFile('''
-class A {
-  int fff; // in A
-}
-class B extends A {
-  fff() {} // in B
-}
-''');
-    await prepareOverrides();
-    assertHasOverride('fff() {} // in B');
-    assertHasSuperElement('fff; // in A');
-    assertNoInterfaceMembers();
-  }
-
   test_super_fieldBySetter() async {
     addTestFile('''
 class A {
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 619136b..a3e956a 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -16,9 +16,10 @@
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
     show AnalysisRequest, CompletionRequest, CompletionResult;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analysis_server/src/services/index/index.dart' show Index;
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
@@ -34,6 +35,7 @@
 import 'package:unittest/unittest.dart';
 
 import 'analysis_abstract.dart';
+import 'domain_completion_util.dart';
 import 'mock_sdk.dart';
 import 'mocks.dart';
 import 'utils.dart';
@@ -275,109 +277,7 @@
 }
 
 @reflectiveTest
-class CompletionTest extends AbstractAnalysisTest {
-  String completionId;
-  int completionOffset;
-  int replacementOffset;
-  int replacementLength;
-  List<CompletionSuggestion> suggestions = [];
-  bool suggestionsDone = false;
-
-  String addTestFile(String content, {int offset}) {
-    completionOffset = content.indexOf('^');
-    if (offset != null) {
-      expect(completionOffset, -1, reason: 'cannot supply offset and ^');
-      completionOffset = offset;
-      return super.addTestFile(content);
-    }
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    return super.addTestFile(content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1));
-  }
-
-  void assertHasResult(CompletionSuggestionKind kind, String completion,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      bool isPotential: false,
-      int selectionOffset}) {
-    var cs;
-    suggestions.forEach((s) {
-      if (s.completion == completion) {
-        if (cs == null) {
-          cs = s;
-        } else {
-          fail('expected exactly one $completion but found > 1');
-        }
-      }
-    });
-    if (cs == null) {
-      var completions = suggestions.map((s) => s.completion).toList();
-      fail('expected "$completion" but found\n $completions');
-    }
-    expect(cs.kind, equals(kind));
-    expect(cs.relevance, equals(relevance));
-    expect(cs.selectionOffset, selectionOffset ?? completion.length);
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-  }
-
-  void assertNoResult(String completion) {
-    if (suggestions.any((cs) => cs.completion == completion)) {
-      fail('did not expect completion: $completion');
-    }
-  }
-
-  void assertValidId(String id) {
-    expect(id, isNotNull);
-    expect(id.isNotEmpty, isTrue);
-  }
-
-  @override
-  Index createIndex() {
-    return createLocalMemoryIndex();
-  }
-
-  Future getSuggestions() {
-    return waitForTasksFinished().then((_) {
-      Request request = new CompletionGetSuggestionsParams(
-          testFile, completionOffset).toRequest('0');
-      Response response = handleSuccessfulRequest(request);
-      completionId = response.id;
-      assertValidId(completionId);
-      return pumpEventQueue().then((_) {
-        expect(suggestionsDone, isTrue);
-      });
-    });
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == COMPLETION_RESULTS) {
-      var params = new CompletionResultsParams.fromNotification(notification);
-      String id = params.id;
-      assertValidId(id);
-      if (id == completionId) {
-        expect(suggestionsDone, isFalse);
-        replacementOffset = params.replacementOffset;
-        replacementLength = params.replacementLength;
-        suggestionsDone = params.isLast;
-        expect(suggestionsDone, isNotNull);
-        suggestions = params.results;
-      }
-    } else if (notification.event == SERVER_ERROR) {
-      fail('server error: ${notification.toJson()}');
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
-    handler = new CompletionDomainHandler(server);
-  }
-
+class CompletionTest extends AbstractCompletionDomainTest {
   test_html() {
     testFile = '/project/web/test.html';
     addTestFile('''
@@ -501,15 +401,15 @@
   }
 
   test_invocation_sdk_relevancy_off() {
-    var originalSorter = DartCompletionManager.defaultContributionSorter;
+    var originalSorter = DartCompletionManager.contributionSorter;
     var mockSorter = new MockRelevancySorter();
-    DartCompletionManager.defaultContributionSorter = mockSorter;
+    DartCompletionManager.contributionSorter = mockSorter;
     addTestFile('main() {Map m; m.^}');
     return getSuggestions().then((_) {
       // Assert that the CommonUsageComputer has been replaced
       expect(suggestions.any((s) => s.relevance == DART_RELEVANCE_COMMON_USAGE),
           isFalse);
-      DartCompletionManager.defaultContributionSorter = originalSorter;
+      DartCompletionManager.contributionSorter = originalSorter;
       mockSorter.enabled = false;
     });
   }
@@ -532,6 +432,102 @@
     });
   }
 
+  test_inComment_block_beforeNode() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    /* text ^ */
+    print(42);
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inComment_endOfLine_beforeNode() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    // text ^
+    print(42);
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inComment_endOfLine_beforeToken() async {
+    addTestFile('''
+  main(aaa, bbb) {
+    // text ^
+  }
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc1() async {
+    addTestFile('''
+  /// ^
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc2() async {
+    addTestFile('''
+  /// Some text^
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    expect(suggestions, isEmpty);
+  }
+
+  test_inDartDoc_reference1() async {
+    addFile(
+        '/testA.dart',
+        '''
+  part of libA;
+  foo(bar) => 0;''');
+    addTestFile('''
+  library libA;
+  part "/testA.dart";
+  import "dart:math";
+  /// The [^]
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'min');
+  }
+
+  test_inDartDoc_reference2() async {
+    addTestFile('''
+  /// The [m^]
+  main(aaa, bbb) {}
+  ''');
+    await getSuggestions();
+    assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'main',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_inherited() {
+    addFile('/libA.dart', 'class A {m() {}}');
+    addTestFile('''
+import '/libA.dart';
+class B extends A {
+  x() {^}
+}
+''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
+    });
+  }
+
   test_keyword() {
     addTestFile('library A; cl^');
     return getSuggestions().then((_) {
@@ -554,6 +550,23 @@
     });
   }
 
+  test_local_override() {
+    addFile('/libA.dart', 'class A {m() {}}');
+    addTestFile('''
+import '/libA.dart';
+class B extends A {
+  m() {}
+  x() {^}
+}
+''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
+    });
+  }
+
   test_locals() {
     addTestFile('class A {var a; x() {var b;^}} class DateTime { }');
     return getSuggestions().then((_) {
@@ -572,12 +585,12 @@
 
   test_offset_past_eof() {
     addTestFile('main() { }', offset: 300);
-    return getSuggestions().then((_) {
-      expect(replacementOffset, equals(300));
-      expect(replacementLength, equals(0));
-      expect(suggestionsDone, true);
-      expect(suggestions.length, 0);
-    });
+    Request request =
+        new CompletionGetSuggestionsParams(testFile, completionOffset)
+            .toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response.id, '0');
+    expect(response.error.code, RequestErrorCode.INVALID_PARAMETER);
   }
 
   test_overrides() {
@@ -681,10 +694,6 @@
   }
 }
 
-class MockCache extends CompletionCache {
-  MockCache(AnalysisContext context, Source source) : super(context, source);
-}
-
 class MockCompletionManager implements CompletionManager {
   final AnalysisContext context;
   final Source source;
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
new file mode 100644
index 0000000..29cff99
--- /dev/null
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -0,0 +1,123 @@
+// 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 test.domain.completion;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/constants.dart';
+import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/index/index.dart' show Index;
+import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:unittest/unittest.dart';
+
+import 'analysis_abstract.dart';
+import 'mocks.dart';
+
+class AbstractCompletionDomainTest extends AbstractAnalysisTest {
+  String completionId;
+  int completionOffset;
+  int replacementOffset;
+  int replacementLength;
+  List<CompletionSuggestion> suggestions = [];
+  bool suggestionsDone = false;
+
+  String addTestFile(String content, {int offset}) {
+    completionOffset = content.indexOf('^');
+    if (offset != null) {
+      expect(completionOffset, -1, reason: 'cannot supply offset and ^');
+      completionOffset = offset;
+      return super.addTestFile(content);
+    }
+    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
+    int nextOffset = content.indexOf('^', completionOffset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    return super.addTestFile(content.substring(0, completionOffset) +
+        content.substring(completionOffset + 1));
+  }
+
+  void assertHasResult(CompletionSuggestionKind kind, String completion,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      bool isDeprecated: false,
+      bool isPotential: false,
+      int selectionOffset}) {
+    var cs;
+    suggestions.forEach((s) {
+      if (s.completion == completion) {
+        if (cs == null) {
+          cs = s;
+        } else {
+          fail('expected exactly one $completion but found > 1');
+        }
+      }
+    });
+    if (cs == null) {
+      var completions = suggestions.map((s) => s.completion).toList();
+      fail('expected "$completion" but found\n $completions');
+    }
+    expect(cs.kind, equals(kind));
+    expect(cs.relevance, equals(relevance));
+    expect(cs.selectionOffset, selectionOffset ?? completion.length);
+    expect(cs.selectionLength, equals(0));
+    expect(cs.isDeprecated, equals(isDeprecated));
+    expect(cs.isPotential, equals(isPotential));
+  }
+
+  void assertNoResult(String completion) {
+    if (suggestions.any((cs) => cs.completion == completion)) {
+      fail('did not expect completion: $completion');
+    }
+  }
+
+  void assertValidId(String id) {
+    expect(id, isNotNull);
+    expect(id.isNotEmpty, isTrue);
+  }
+
+  @override
+  Index createIndex() {
+    return createLocalMemoryIndex();
+  }
+
+  Future getSuggestions() {
+    return waitForTasksFinished().then((_) {
+      Request request =
+          new CompletionGetSuggestionsParams(testFile, completionOffset)
+              .toRequest('0');
+      Response response = handleSuccessfulRequest(request);
+      completionId = response.id;
+      assertValidId(completionId);
+      return pumpEventQueue().then((_) {
+        expect(suggestionsDone, isTrue);
+      });
+    });
+  }
+
+  void processNotification(Notification notification) {
+    if (notification.event == COMPLETION_RESULTS) {
+      var params = new CompletionResultsParams.fromNotification(notification);
+      String id = params.id;
+      assertValidId(id);
+      if (id == completionId) {
+        expect(suggestionsDone, isFalse);
+        replacementOffset = params.replacementOffset;
+        replacementLength = params.replacementLength;
+        suggestionsDone = params.isLast;
+        expect(suggestionsDone, isNotNull);
+        suggestions = params.results;
+      }
+    } else if (notification.event == SERVER_ERROR) {
+      fail('server error: ${notification.toJson()}');
+    }
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    createProject();
+    handler = new CompletionDomainHandler(server);
+  }
+}
diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
index b42cd9e..076ae9d 100644
--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
@@ -150,13 +150,13 @@
       tests.add(checkHover('topLevelVar;', 11, ['List', 'topLevelVar'],
           'top level variable', ['List']));
       tests.add(checkHover(
-          'func(', 4, ['func', 'int', 'param'], 'function', ['int', 'void'],
+          'func(', 4, ['func', 'int', 'param'], 'function', null,
           docRegexp: 'Documentation for func'));
-      tests.add(checkHover('int param', 3, ['int'], 'class', ['int'],
+      tests.add(checkHover('int param', 3, ['int'], 'class', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover('param)', 5, ['int', 'param'], 'parameter', ['int'],
           isLocal: true, docRegexp: 'Documentation for func'));
-      tests.add(checkHover('num localVar', 3, ['num'], 'class', ['num'],
+      tests.add(checkHover('num localVar', 3, ['num'], 'class', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover(
           'localVar =', 8, ['num', 'localVar'], 'local variable', ['num'],
@@ -164,10 +164,10 @@
       tests.add(checkHover('topLevelVar.length;', 11, ['List', 'topLevelVar'],
           'top level variable', ['List']));
       tests.add(checkHover(
-          'length;', 6, ['get', 'length', 'int'], 'getter', ['int'],
+          'length;', 6, ['get', 'length', 'int'], 'getter', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover(
-          'length =', 6, ['set', 'length', 'int'], 'setter', ['int'],
+          'length =', 6, ['set', 'length', 'int'], 'setter', null,
           isCore: true, docRegexp: '.*'));
       tests.add(checkHover('param;', 5, ['int', 'param'], 'parameter', ['int'],
           isLocal: true,
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index f4dcfeb..f05a775 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -582,7 +582,7 @@
     _pendingCommands[id] = completer;
     String line = JSON.encode(command);
     _recordStdio('SEND: $line');
-    _process.stdin.add(UTF8.encoder.convert("${line}\n"));
+    _process.stdin.add(UTF8.encoder.convert("$line\n"));
     return completer.future;
   }
 
@@ -613,7 +613,7 @@
       arguments.add('--observe');
       arguments.add('--pause-isolates-on-exit');
     }
-    if (Platform.packageRoot.isNotEmpty) {
+    if (Platform.packageRoot != null) {
       arguments.add('--package-root=${Platform.packageRoot}');
     }
     arguments.add('--checked');
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 5aaec99..1fbb426 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -269,7 +269,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index efc19fd..d47638f 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -15,11 +15,11 @@
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/operation/operation.dart';
 import 'package:analysis_server/src/operation/operation_analysis.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:typed_mock/typed_mock.dart';
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 35cf37d..2d0eddd 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -6,8 +6,10 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/plugin/protocol/protocol_dart.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
+import 'package:analyzer/src/dart/element/element.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index a210a94..24d03a3 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -9,8 +9,9 @@
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart' as engine;
+import 'package:analyzer/dart/element/type.dart' as engine;
 import 'package:analyzer/src/generated/ast.dart' as engine;
-import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/error.dart' as engine;
 import 'package:analyzer/src/generated/source.dart' as engine;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -129,11 +130,8 @@
         .run(convertElementKind, exceptions: {
       // TODO(paulberry): do any of the exceptions below constitute bugs?
       engine.ElementKind.DYNAMIC: ElementKind.UNKNOWN,
-      engine.ElementKind.EMBEDDED_HTML_SCRIPT: ElementKind.UNKNOWN,
       engine.ElementKind.ERROR: ElementKind.UNKNOWN,
       engine.ElementKind.EXPORT: ElementKind.UNKNOWN,
-      engine.ElementKind.EXTERNAL_HTML_SCRIPT: ElementKind.UNKNOWN,
-      engine.ElementKind.HTML: ElementKind.UNKNOWN,
       engine.ElementKind.IMPORT: ElementKind.UNKNOWN,
       engine.ElementKind.NAME: ElementKind.UNKNOWN,
       engine.ElementKind.UNIVERSE: ElementKind.UNKNOWN
diff --git a/pkg/analysis_server/test/services/completion/completion_computer_test.dart b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
deleted file mode 100644
index 3614852..0000000
--- a/pkg/analysis_server/test/services/completion/completion_computer_test.dart
+++ /dev/null
@@ -1,205 +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.
-
-library test.services.completion.suggestion;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/provisional/completion/completion_core.dart'
-    show CompletionRequest, CompletionResult;
-import 'package:analysis_server/src/services/completion/completion_core.dart';
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_single_unit.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(DartCompletionManagerTest);
-}
-
-/**
- * Returns a [Future] that completes after pumping the event queue [times]
- * times. By default, this should pump the event queue enough times to allow
- * any code to run, as long as it's not waiting on some external event.
- */
-Future pumpEventQueue([int times = 20]) {
-  if (times == 0) return new Future.value();
-  // We use a delayed future to allow microtask events to finish. The
-  // Future.value or Future() constructors use scheduleMicrotask themselves and
-  // would therefore not wait for microtask callbacks that are scheduled after
-  // invoking this method.
-  return new Future.delayed(Duration.ZERO, () => pumpEventQueue(times - 1));
-}
-
-@reflectiveTest
-class DartCompletionManagerTest extends AbstractSingleUnitTest {
-  Index index;
-  SearchEngineImpl searchEngine;
-  Source source;
-  DartCompletionManager manager;
-  MockCompletionContributor contributor1;
-  MockCompletionContributor contributor2;
-  CompletionSuggestion suggestion1;
-  CompletionSuggestion suggestion2;
-  bool _continuePerformingAnalysis = true;
-
-  void resolveLibrary() {
-    context.resolveCompilationUnit(
-        source, context.computeLibraryElement(source));
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    index = createLocalMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
-    source = addSource('/does/not/exist.dart', '');
-    manager =
-        new DartCompletionManager.create(context, searchEngine, source, []);
-    suggestion1 = new CompletionSuggestion(CompletionSuggestionKind.INVOCATION,
-        DART_RELEVANCE_DEFAULT, "suggestion1", 1, 1, false, false);
-    suggestion2 = new CompletionSuggestion(CompletionSuggestionKind.IDENTIFIER,
-        DART_RELEVANCE_DEFAULT, "suggestion2", 2, 2, false, false);
-    new Future(_performAnalysis);
-  }
-
-  @override
-  void tearDown() {
-    _continuePerformingAnalysis = false;
-  }
-
-  test_compute_fastAndFull() {
-    contributor1 = new MockCompletionContributor(suggestion1, null);
-    contributor2 = new MockCompletionContributor(null, suggestion2);
-    manager.contributors = [contributor1, contributor2];
-    int count = 0;
-    bool done = false;
-    CompletionRequest completionRequest =
-        new CompletionRequestImpl(context, provider, searchEngine, source, 0);
-    manager.results(completionRequest).listen((CompletionResult r) {
-      bool isLast = r is CompletionResultImpl ? r.isLast : true;
-      switch (++count) {
-        case 1:
-          contributor1.assertCalls(context, source, 0, searchEngine);
-          expect(contributor1.fastCount, equals(1));
-          expect(contributor1.fullCount, equals(0));
-          contributor2.assertCalls(context, source, 0, searchEngine);
-          expect(contributor2.fastCount, equals(1));
-          expect(contributor2.fullCount, equals(1));
-          expect(isLast, isTrue);
-          expect(r.suggestions, hasLength(2));
-          expect(r.suggestions, contains(suggestion1));
-          expect(r.suggestions, contains(suggestion2));
-          resolveLibrary();
-          break;
-        default:
-          fail('unexpected');
-      }
-    }, onDone: () {
-      done = true;
-      // There is only one notification
-      expect(count, equals(1));
-    });
-    return pumpEventQueue(250).then((_) {
-      expect(done, isTrue);
-    });
-  }
-
-  test_compute_fastOnly() {
-    contributor1 = new MockCompletionContributor(suggestion1, null);
-    contributor2 = new MockCompletionContributor(suggestion2, null);
-    manager.contributors = [contributor1, contributor2];
-    int count = 0;
-    bool done = false;
-    CompletionRequest completionRequest =
-        new CompletionRequestImpl(context, provider, searchEngine, source, 0);
-    manager.results(completionRequest).listen((CompletionResult r) {
-      bool isLast = r is CompletionResultImpl ? r.isLast : true;
-      switch (++count) {
-        case 1:
-          contributor1.assertCalls(context, source, 0, searchEngine);
-          expect(contributor1.fastCount, equals(1));
-          expect(contributor1.fullCount, equals(0));
-          contributor2.assertCalls(context, source, 0, searchEngine);
-          expect(contributor2.fastCount, equals(1));
-          expect(contributor2.fullCount, equals(0));
-          expect(isLast, isTrue);
-          expect(r.suggestions, hasLength(2));
-          expect(r.suggestions, contains(suggestion1));
-          expect(r.suggestions, contains(suggestion2));
-          break;
-        default:
-          fail('unexpected');
-      }
-    }, onDone: () {
-      done = true;
-      expect(count, equals(1));
-    });
-    return pumpEventQueue().then((_) {
-      expect(done, isTrue);
-    });
-  }
-
-  void _performAnalysis() {
-    if (!_continuePerformingAnalysis) {
-      return;
-    }
-    context.performAnalysisTask();
-    new Future(_performAnalysis);
-  }
-}
-
-class MockCompletionContributor extends DartCompletionContributor {
-  final CompletionSuggestion fastSuggestion;
-  final CompletionSuggestion fullSuggestion;
-  int fastCount = 0;
-  int fullCount = 0;
-  DartCompletionRequest request;
-
-  MockCompletionContributor(this.fastSuggestion, this.fullSuggestion);
-
-  assertCalls(AnalysisContext context, Source source, int offset,
-      SearchEngine searchEngine) {
-    expect(request.context, equals(context));
-    expect(request.source, equals(source));
-    expect(request.offset, equals(offset));
-    expect(request.searchEngine, equals(searchEngine));
-  }
-
-  assertFull(int fullCount) {
-    expect(this.fastCount, equals(1));
-    expect(this.fullCount, equals(fullCount));
-  }
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    this.request = request;
-    fastCount++;
-    if (fastSuggestion != null) {
-      request.addSuggestion(fastSuggestion);
-    }
-    return fastSuggestion != null;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    this.request = request;
-    fullCount++;
-    if (fullSuggestion != null) {
-      request.addSuggestion(fullSuggestion);
-    }
-    return new Future.value(fullSuggestion != null);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/completion_manager_test.dart
deleted file mode 100644
index 4ee538d..0000000
--- a/pkg/analysis_server/test/services/completion/completion_manager_test.dart
+++ /dev/null
@@ -1,48 +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.
-
-library test.services.completion.manager;
-
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../utils.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(CompletionManagerTest);
-}
-
-@reflectiveTest
-class CompletionManagerTest extends AbstractContextTest {
-  var perf = new CompletionPerformance();
-
-  test_dart() {
-    Source source = addSource('/does/not/exist.dart', '');
-    var manager = new CompletionManager.create(context, source, null, []);
-    expect(manager.runtimeType, DartCompletionManager);
-  }
-
-  test_html() {
-    Source source = addSource('/does/not/exist.html', '');
-    var manager = new CompletionManager.create(context, source, null, []);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-
-  test_null_context() {
-    Source source = addSource('/does/not/exist.dart', '');
-    var manager = new CompletionManager.create(null, source, null, []);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-
-  test_other() {
-    Source source = addSource('/does/not/exist.foo', '');
-    var manager = new CompletionManager.create(context, source, null, []);
-    expect(manager.runtimeType, NoOpCompletionManager);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart
deleted file mode 100644
index 7812fd8..0000000
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ /dev/null
@@ -1,4695 +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.
-
-library test.services.completion.util;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
-import 'package:analysis_server/src/services/completion/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-
-int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
-  String c1 = s1.completion.toLowerCase();
-  String c2 = s2.completion.toLowerCase();
-  return c1.compareTo(c2);
-}
-
-abstract class AbstractCompletionTest extends AbstractContextTest {
-  Index index;
-  SearchEngineImpl searchEngine;
-  DartCompletionContributor contributor;
-  String testFile = '/completionTest.dart';
-  Source testSource;
-  CompilationUnit testUnit;
-  int completionOffset;
-  AstNode completionNode;
-  bool computeFastResult;
-  DartCompletionRequest request;
-  DartCompletionCache cache;
-  DartCompletionManager _completionManager;
-
-  void addResolvedUnit(String file, String code) {
-    Source source = addSource(file, code);
-    CompilationUnit unit = resolveLibraryUnit(source);
-    index.index(context, unit);
-  }
-
-  void addTestSource(String content) {
-    expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    content = content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1);
-    testSource = addSource(testFile, content);
-    cache = new DartCompletionCache(context, testSource);
-    request = new DartCompletionRequest(
-        context, provider, searchEngine, testSource, completionOffset, cache);
-  }
-
-  void assertHasNoParameterInfo(CompletionSuggestion suggestion) {
-    expect(suggestion.parameterNames, isNull);
-    expect(suggestion.parameterTypes, isNull);
-    expect(suggestion.requiredParameterCount, isNull);
-    expect(suggestion.hasNamedParameters, isNull);
-  }
-
-  void assertHasParameterInfo(CompletionSuggestion suggestion) {
-    expect(suggestion.parameterNames, isNotNull);
-    expect(suggestion.parameterTypes, isNotNull);
-    expect(suggestion.parameterNames.length, suggestion.parameterTypes.length);
-    expect(suggestion.requiredParameterCount,
-        lessThanOrEqualTo(suggestion.parameterNames.length));
-    expect(suggestion.hasNamedParameters, isNotNull);
-  }
-
-  void assertNoSuggestions({CompletionSuggestionKind kind: null}) {
-    if (kind == null) {
-      if (request.suggestions.length > 0) {
-        failedCompletion('Expected no suggestions', request.suggestions);
-      }
-      return;
-    }
-    CompletionSuggestion suggestion = request.suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.kind == kind,
-        orElse: () => null);
-    if (suggestion != null) {
-      failedCompletion('did not expect completion: $completion\n  $suggestion');
-    }
-  }
-
-  CompletionSuggestion assertNotSuggested(String completion) {
-    CompletionSuggestion suggestion = request.suggestions.firstWhere(
-        (CompletionSuggestion cs) => cs.completion == completion,
-        orElse: () => null);
-    if (suggestion != null) {
-      failedCompletion('did not expect completion: $completion\n  $suggestion');
-    }
-    return null;
-  }
-
-  CompletionSuggestion assertSuggest(String completion,
-      {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      protocol.ElementKind elemKind: null,
-      bool isDeprecated: false,
-      bool isPotential: false,
-      String elemFile,
-      int elemOffset}) {
-    CompletionSuggestion cs =
-        getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
-    if (cs == null) {
-      failedCompletion(
-          'expected $completion $csKind $elemKind', request.suggestions);
-    }
-    expect(cs.kind, equals(csKind));
-    if (isDeprecated) {
-      expect(cs.relevance, equals(DART_RELEVANCE_LOW));
-    } else {
-      expect(cs.relevance, equals(relevance));
-    }
-    expect(cs.importUri, importUri);
-    expect(cs.selectionOffset, equals(completion.length));
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-    if (cs.element != null) {
-      expect(cs.element.location, isNotNull);
-      expect(cs.element.location.file, isNotNull);
-      expect(cs.element.location.offset, isNotNull);
-      expect(cs.element.location.length, isNotNull);
-      expect(cs.element.location.startColumn, isNotNull);
-      expect(cs.element.location.startLine, isNotNull);
-    }
-    if (elemFile != null) {
-      expect(cs.element.location.file, elemFile);
-    }
-    if (elemOffset != null) {
-      expect(cs.element.location.offset, elemOffset);
-    }
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestClass(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated,
-        elemFile: elemFile,
-        elemOffset: elemOffset);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CLASS));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestClassTypeAlias(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs =
-        assertSuggest(name, csKind: kind, relevance: relevance);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CLASS_TYPE_ALIAS));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      int elemOffset}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        relevance: relevance, importUri: importUri, elemOffset: elemOffset);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
-    int index = name.indexOf('.');
-    expect(element.name, index >= 0 ? name.substring(index + 1) : '');
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.FIELD,
-        isDeprecated: isDeprecated);
-    // The returnType represents the type of a field
-    expect(cs.returnType, type != null ? type : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FIELD));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    // The returnType represents the type of a field
-    expect(element.returnType, type != null ? type : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestFunction(String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: deprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FUNCTION));
-    expect(element.name, equals(name));
-    expect(element.isDeprecated, equals(deprecated));
-    String param = element.parameters;
-    expect(param, isNotNull);
-    expect(param[0], equals('('));
-    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestFunctionTypeAlias(
-      String name, String returnType, bool isDeprecated,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.FUNCTION_TYPE_ALIAS));
-    expect(element.name, equals(name));
-    expect(element.isDeprecated, equals(isDeprecated));
-    // TODO (danrubel) Determine why params are null
-//    String param = element.parameters;
-//    expect(param, isNotNull);
-//    expect(param[0], equals('('));
-//    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    // TODO (danrubel) Determine why param info is missing
-//    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.GETTER,
-        isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.GETTER));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestLabel(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.IDENTIFIER]) {
-    CompletionSuggestion cs =
-        assertSuggest(name, csKind: kind, relevance: relevance);
-    expect(cs.returnType, isNull);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.flags, 0);
-    expect(element.kind, equals(protocol.ElementKind.LABEL));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    // Library prefix should only be suggested by ImportedReferenceContributor
-    return assertNotSuggested(prefix);
-  }
-
-  CompletionSuggestion assertSuggestMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        isDeprecated: isDeprecated);
-    expect(cs.declaringType, equals(declaringType));
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.METHOD));
-    expect(element.name, equals(name));
-    String param = element.parameters;
-    expect(param, isNotNull);
-    expect(param[0], equals('('));
-    expect(param[param.length - 1], equals(')'));
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestParameter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_PARAMETER}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestSetter(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      String importUri,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind,
-        relevance: relevance,
-        importUri: importUri,
-        elemKind: protocol.ElementKind.SETTER);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.SETTER));
-    expect(element.name, equals(name));
-    // TODO (danrubel) assert setter param
-    //expect(element.parameters, isNull);
-    // TODO (danrubel) it would be better if this was always null
-    if (element.returnType != null) {
-      expect(element.returnType, 'dynamic');
-    }
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestTopLevelVar(String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: kind, relevance: relevance, importUri: importUri);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.TOP_LEVEL_VARIABLE));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  void assertSuggestTopLevelVarGetterSetter(String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is ImportedReferenceContributor) {
-      assertSuggestGetter(name, returnType);
-      assertSuggestSetter(name);
-    } else {
-      assertNotSuggested(name);
-    }
-  }
-
-  bool computeFast() {
-    expect(computeFastResult, isNull);
-    _completionManager = new DartCompletionManager(context, searchEngine,
-        testSource, cache, [contributor], [], new CommonUsageSorter({}));
-    var result =
-        _completionManager.computeFast(request, new CompletionPerformance());
-    expect(request.replacementOffset, isNotNull);
-    expect(request.replacementLength, isNotNull);
-    computeFastResult = result.isEmpty;
-    return computeFastResult;
-  }
-
-  Future computeFull(assertFunction(bool result), {bool fullAnalysis: true}) {
-    if (computeFastResult == null) {
-      computeFast();
-    }
-    if (computeFastResult) {
-      assertFunction(true);
-      return new Future.value(true);
-    } else {
-      resolve(fullAnalysis);
-      return contributor.computeFull(request).then(assertFunction);
-    }
-  }
-
-  void failedCompletion(String message,
-      [Iterable<CompletionSuggestion> completions]) {
-    StringBuffer sb = new StringBuffer(message);
-    if (completions != null) {
-      sb.write('\n  found');
-      completions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-    }
-    if (completionNode != null) {
-      sb.write('\n  in');
-      AstNode node = completionNode;
-      while (node != null) {
-        sb.write('\n    ${node.runtimeType}');
-        node = node.parent;
-      }
-    }
-    fail(sb.toString());
-  }
-
-  CompletionSuggestion getSuggest(
-      {String completion: null,
-      CompletionSuggestionKind csKind: null,
-      protocol.ElementKind elemKind: null}) {
-    CompletionSuggestion cs;
-    request.suggestions.forEach((CompletionSuggestion s) {
-      if (completion != null && completion != s.completion) {
-        return;
-      }
-      if (csKind != null && csKind != s.kind) {
-        return;
-      }
-      if (elemKind != null) {
-        protocol.Element element = s.element;
-        if (element == null || elemKind != element.kind) {
-          return;
-        }
-      }
-      if (cs == null) {
-        cs = s;
-      } else {
-        failedCompletion('expected exactly one $cs',
-            request.suggestions.where((s) => s.completion == completion));
-      }
-    });
-    return cs;
-  }
-
-  void resolve(bool fullAnalysis) {
-    // Index SDK
-    for (Source librarySource in context.librarySources) {
-      CompilationUnit unit =
-          context.getResolvedCompilationUnit2(librarySource, librarySource);
-      if (unit != null) {
-        index.index(context, unit);
-      }
-    }
-
-    var result = context.performAnalysisTask();
-    bool resolved = false;
-    while (result.hasMoreWork) {
-      // Update the index
-      result.changeNotices.forEach((ChangeNotice notice) {
-        CompilationUnit unit = notice.resolvedDartUnit;
-        if (unit != null) {
-          index.index(context, unit);
-        }
-      });
-
-      // If the unit has been resolved, then finish the completion
-      List<Source> libSourceList = context.getLibrariesContaining(testSource);
-      if (libSourceList.length > 0) {
-        LibraryElement library = context.getLibraryElement(libSourceList[0]);
-        if (library != null) {
-          CompilationUnit unit =
-              context.getResolvedCompilationUnit(testSource, library);
-          if (unit != null) {
-            request.unit = unit;
-            request.target =
-                new CompletionTarget.forOffset(unit, completionOffset);
-            resolved = true;
-            if (!fullAnalysis) {
-              break;
-            }
-          }
-        }
-      }
-
-      result = context.performAnalysisTask();
-    }
-    if (!resolved) {
-      fail('expected unit to be resolved');
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    index = createLocalMemoryIndex();
-    searchEngine = new SearchEngineImpl(index);
-    setUpContributor();
-  }
-
-  void setUpContributor();
-}
-
-/**
- * Common tests for `ImportedTypeContributorTest`, `InvocationContributorTest`,
- * and `LocalContributorTest`.
- */
-abstract class AbstractSelectorSuggestionTest extends AbstractCompletionTest {
-  /**
-   * Assert that the ImportedReferenceContributor uses cached results
-   * to produce identical suggestions to the original set of suggestions.
-   */
-  void assertCachedCompute(_) {
-    // Subclasses override
-  }
-
-  CompletionSuggestion assertSuggestEnum(String completion,
-      {bool isDeprecated: false}) {
-    CompletionSuggestion suggestion =
-        assertSuggest(completion, isDeprecated: isDeprecated);
-    expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, protocol.ElementKind.ENUM);
-    return suggestion;
-  }
-
-  CompletionSuggestion assertSuggestEnumConst(String completion,
-      {bool isDeprecated: false}) {
-    CompletionSuggestion suggestion =
-        assertSuggest(completion, isDeprecated: isDeprecated);
-    expect(suggestion.isDeprecated, isDeprecated);
-    expect(suggestion.element.kind, protocol.ElementKind.ENUM_CONSTANT);
-    return suggestion;
-  }
-
-  CompletionSuggestion assertSuggestImportedClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      String elemFile}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedField(String name, String type,
-      {int relevance: DART_RELEVANCE_INHERITED_FIELD}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedFunctionTypeAlias(
-      String name, String returnType,
-      [bool isDeprecated = false,
-      int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_METHOD}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedSetter(String name,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestImportedTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationClass(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationSetter(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestInvocationTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT]) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalClassTypeAlias(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalConstructor(String name,
-      {int elemOffset}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalField(String name, String type,
-      {int relevance: DART_RELEVANCE_LOCAL_FIELD, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalFunction(
-      String name, String returnType,
-      {bool deprecated: false,
-      int relevance: DART_RELEVANCE_LOCAL_FUNCTION,
-      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalFunctionTypeAlias(
-      String name, String returnType,
-      {bool deprecated: false, int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_METHOD, bool deprecated: false}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalSetter(String name,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalTopLevelVar(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestLocalVariable(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
-    return assertNotSuggested(name);
-  }
-
-  CompletionSuggestion assertSuggestNonLocalClass(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    return assertSuggestImportedClass(name, relevance: relevance, kind: kind);
-  }
-
-  Future computeFull(assertFunction(bool result), {bool fullAnalysis: true}) {
-    return super
-        .computeFull(assertFunction, fullAnalysis: fullAnalysis)
-        .then(assertCachedCompute);
-  }
-
-  test_ArgumentList() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_imported_function() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      expect(arg) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_InstanceCreationExpression_functionalArg() {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {new A(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_InstanceCreationExpression_typedefArg() {
-    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      typedef Funct();
-      class A { A(Funct f) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar() => true;
-      void main() {new A(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_local_function() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      expect(arg) { }
-      class B { }
-      String bar() => true;
-      void main() {expect(^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_local_method() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import '/libA.dart'
-      class B {
-        expect(arg) { }
-        void foo() {expect(^)}}
-      String bar() => true;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertSuggestLocalClass('B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_MethodInvocation_functionalArg() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { }
-      String bar(f()) => true;
-      void main() {bar(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestLocalFunction('bar', 'String',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_MethodInvocation_methodArg() {
-    // ArgumentList  MethodInvocation  ExpressionStatement  Block
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      class A { A(f()) { } }
-      bool hasLength(int expected) { }
-      void baz() { }''');
-    addTestSource('''
-      import 'dart:async';
-      import '/libA.dart';
-      class B { String bar(f()) => true; }
-      void main() {new B().bar(^);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
-      assertSuggestImportedFunction('hasLength', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedFunction('identical', 'bool',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestLocalClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('A',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertSuggestImportedClass('Object',
-          kind: CompletionSuggestionKind.IDENTIFIER);
-      assertNotSuggested('main');
-      assertNotSuggested('baz');
-      assertNotSuggested('print');
-    });
-  }
-
-  test_ArgumentList_namedParam() {
-    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
-    // ExpressionStatement
-    addSource(
-        '/libA.dart',
-        '''
-      library A;
-      bool hasLength(int expected) { }''');
-    addTestSource('''
-      import '/libA.dart'
-      String bar() => true;
-      void main() {expect(foo: ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('bar', 'String');
-      assertSuggestImportedFunction('hasLength', 'bool');
-      assertNotSuggested('main');
-    });
-  }
-
-  test_AsExpression() {
-    // SimpleIdentifier  TypeName  AsExpression
-    addTestSource('''
-      class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_AssignmentExpression_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int ^b = 1;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_AssignmentExpression_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int b = ^}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_AssignmentExpression_type() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        ^ b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-      // the user may be either (1) entering a type for the assignment
-      // or (2) starting a new statement.
-      // Consider suggesting only types
-      // if only spaces separates the 1st and 2nd identifiers.
-      //assertNotSuggested('a');
-      //assertNotSuggested('main');
-      //assertNotSuggested('identical');
-    });
-  }
-
-  test_AssignmentExpression_type_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        ^
-        b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // Allow non-types preceding an identifier on LHS of assignment
-      // if newline follows first identifier
-      // because user is probably starting a new statement
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestImportedFunction('identical', 'bool');
-    });
-  }
-
-  test_AssignmentExpression_type_partial() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        int^ b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
-      // the user may be either (1) entering a type for the assignment
-      // or (2) starting a new statement.
-      // Consider suggesting only types
-      // if only spaces separates the 1st and 2nd identifiers.
-      //assertNotSuggested('a');
-      //assertNotSuggested('main');
-      //assertNotSuggested('identical');
-    });
-  }
-
-  test_AssignmentExpression_type_partial_newline() {
-    // SimpleIdentifier  TypeName  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addTestSource('''
-      class A {} main() {
-        int a;
-        i^
-        b = 1;}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('int');
-      // Allow non-types preceding an identifier on LHS of assignment
-      // if newline follows first identifier
-      // because user is probably starting a new statement
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestImportedFunction('identical', 'bool');
-    });
-  }
-
-  test_AwaitExpression() {
-    // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main() async {A a; await ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'A');
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_BinaryExpression_LHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = ^ + 2;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('b');
-    });
-  }
-
-  test_BinaryExpression_RHS() {
-    // SimpleIdentifier  BinaryExpression  VariableDeclaration
-    // VariableDeclarationList  VariableDeclarationStatement
-    addTestSource('main() {int a = 1, b = 2 + ^;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'int');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_Block() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          ^ var r;
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X', elemFile: testFile);
-      assertSuggestLocalClass('Z');
-      assertSuggestLocalMethod('a', 'X', null);
-      assertSuggestLocalMethod('b', 'X', 'void');
-      assertSuggestLocalFunction('localF', null);
-      assertSuggestLocalVariable('f', null);
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A', elemFile: '/testAB.dart');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertSuggestLocalFunction('D2', 'Z');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedFunction('min', 'num');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      if (contributor is ImportedReferenceContributor) {
-        // TODO(danrubel) should be top level var suggestion
-        assertSuggestGetter('T1', 'String');
-      }
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertSuggestLocalTopLevelVar('T5', 'int');
-      assertSuggestLocalTopLevelVar('_T6', null,
-          relevance: DART_RELEVANCE_DEFAULT);
-      assertNotSuggested('==');
-      assertSuggestLocalGetter('T7', 'String');
-      assertSuggestLocalSetter('T8');
-      assertSuggestLocalGetter('clog', 'int');
-      assertSuggestLocalSetter('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          final ^
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final2() {
-    addTestSource('main() {final S^ v;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Block_final3() {
-    addTestSource('main() {final ^ v;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Block_final_final() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          final ^
-          final var f;
-          localF(int arg1) { }
-          {var x;}
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_final_var() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          final ^
-          var f;
-          localF(int arg1) { }
-          {var x;}
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertNotSuggested('a');
-      assertNotSuggested('b');
-      assertNotSuggested('localF');
-      assertNotSuggested('f');
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-      assertNotSuggested('partT8');
-
-      assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
-      assertNotSuggested('partBoo');
-      // hidden element suggested as low relevance
-      // but imported results are partially filtered
-      //assertSuggestImportedClass('D', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedFunction(
-      //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('D2');
-      assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('min');
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('T1');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      assertNotSuggested('T5');
-      assertNotSuggested('_T6');
-      assertNotSuggested('==');
-      assertNotSuggested('T7');
-      assertNotSuggested('T8');
-      assertNotSuggested('clog');
-      assertNotSuggested('blog');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-      assertSuggestImportedClass('Uri');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_identifier_partial() {
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      class D3 { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      Z D2() {int x;}
-      class X {a() {var f; {var x;} D^ var r;} void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-
-      assertSuggestLocalClass('X');
-      assertSuggestLocalClass('Z');
-      assertSuggestLocalMethod('a', 'X', null);
-      assertSuggestLocalMethod('b', 'X', 'void');
-      assertSuggestLocalVariable('f', null);
-      // Don't suggest locals out of scope
-      assertNotSuggested('r');
-      assertNotSuggested('x');
-
-      // imported elements are portially filtered
-      //assertSuggestImportedClass('A');
-      assertNotSuggested('_B');
-      //assertSuggestImportedClass('C');
-      // hidden element suggested as low relevance
-      assertSuggestImportedClass('D',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testCD.dart');
-      assertSuggestImportedFunction('D1', null,
-          deprecated: true, relevance: DART_RELEVANCE_LOW);
-      assertSuggestLocalFunction('D2', 'Z');
-      // unimported elements suggested with low relevance
-      assertSuggestImportedClass('D3',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testH.dart');
-      //assertSuggestImportedClass('EE');
-      // hidden element suggested as low relevance
-      //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestLibraryPrefix('g');
-      assertNotSuggested('G');
-      //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
-      //assertSuggestImportedClass('Object');
-      //assertSuggestImportedFunction('min', 'num', false);
-      //assertSuggestImportedFunction(
-      //    'max',
-      //    'num',
-      //    false,
-      //    COMPLETION_RELEVANCE_LOW);
-      //assertSuggestTopLevelVarGetterSetter('T1', 'String');
-      assertNotSuggested('_T2');
-      //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
-      assertNotSuggested('_T4');
-      //assertSuggestLocalTopLevelVar('T5', 'int');
-      //assertSuggestLocalTopLevelVar('_T6', null);
-      assertNotSuggested('==');
-      // TODO (danrubel) suggest HtmlElement as low relevance
-      assertNotSuggested('HtmlElement');
-    });
-  }
-
-  test_Block_inherited_imported() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A extends E implements I with M {a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // TODO (danrubel) prefer fields over getters
-      // If add `get e1;` to interface I
-      // then suggestions include getter e1 rather than field e1
-      assertSuggestImportedField('e1', null);
-      assertSuggestImportedField('f1', null);
-      assertSuggestImportedField('i1', 'int');
-      assertSuggestImportedField('m1', null);
-      assertSuggestImportedGetter('f3', null);
-      assertSuggestImportedSetter('f4');
-      assertSuggestImportedMethod('e2', 'E', null);
-      assertSuggestImportedMethod('f2', 'F', null);
-      assertSuggestImportedMethod('i2', 'I', null);
-      //assertSuggestImportedMethod('m2', null, null);
-      assertNotSuggested('==');
-    });
-  }
-
-  test_Block_inherited_local() {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('''
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }
-      class A extends E implements I with M {a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('e1', null);
-      assertSuggestLocalField('f1', null);
-      assertSuggestLocalField('i1', 'int');
-      assertSuggestLocalField('m1', null);
-      assertSuggestLocalGetter('f3', null);
-      assertSuggestLocalSetter('f4');
-      assertSuggestLocalMethod('e2', 'E', null);
-      assertSuggestLocalMethod('f2', 'F', null);
-      assertSuggestLocalMethod('i2', 'I', null);
-      assertSuggestLocalMethod('m2', 'M', 'int');
-    });
-  }
-
-  test_Block_local_function() {
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B {boo() { partBoo() {}} }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      String get T7 => 'hello';
-      set T8(int value) { partT8() {} }
-      Z D2() {int x;}
-      class X {
-        int get clog => 8;
-        set blog(value) { }
-        a() {
-          var f;
-          localF(int arg1) { }
-          {var x;}
-          p^ var r;
-        }
-        void b() { }}
-      class Z { }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-
-      assertNotSuggested('partT8');
-      assertNotSuggested('partBoo');
-      assertNotSuggested('parseIPv6Address');
-      assertNotSuggested('parseHex');
-    });
-  }
-
-  test_Block_unimported() {
-    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
-    addSource(
-        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
-    testFile = '/proj/completionTest.dart';
-    addTestSource('class C {foo(){F^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('Foo',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testAB.dart');
-      // TODO(danrubel) implement
-      assertSuggestImportedClass('Foo2',
-          relevance: DART_RELEVANCE_LOW, importUri: 'package:myBar/bar.dart');
-      assertSuggestImportedClass('Future',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:async');
-    });
-  }
-
-  test_CascadeExpression_selector1() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      // looks like a cascade to the parser
-      // but the user is trying to get completions for a non-cascade
-      main() {A a; a.^.z}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_selector2() {
-    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a..^z}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 1);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_selector2_withTrailingReturn() {
-    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "/testB.dart";
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a..^ return}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('B');
-      assertNotSuggested('X');
-      assertNotSuggested('z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CascadeExpression_target() {
-    // SimpleIdentifier  CascadeExpression  ExpressionStatement
-    addTestSource('''
-      class A {var b; X _c;}
-      class X{}
-      main() {A a; a^..b}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertSuggestLocalVariable('a', 'A');
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('X');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_CatchClause_onType() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^ {}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('a');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_onType_noBrackets() {
-    // TypeName  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on ^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A', elemOffset: 6);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_typed() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('e', 'E');
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_CatchClause_untyped() {
-    // Block  CatchClause  TryStatement
-    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('e', null);
-      assertSuggestParameter('s', 'StackTrace');
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      @deprecated class A {^}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion suggestionA = assertSuggestLocalClass('A',
-          relevance: DART_RELEVANCE_LOW, isDeprecated: true);
-      if (suggestionA != null) {
-        expect(suggestionA.element.isDeprecated, isTrue);
-        expect(suggestionA.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion suggestionB = assertSuggestLocalClass('_B');
-      if (suggestionB != null) {
-        expect(suggestionB.element.isDeprecated, isFalse);
-        expect(suggestionB.element.isPrivate, isTrue);
-      }
-      CompletionSuggestion suggestionO = assertSuggestImportedClass('Object');
-      if (suggestionO != null) {
-        expect(suggestionO.element.isDeprecated, isFalse);
-        expect(suggestionO.element.isPrivate, isFalse);
-      }
-      assertNotSuggested('T');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_field() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ A(){}}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('T');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_field2() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as Soo;
-      class A {final S^ A();}
-      class _B {}
-      A Sew;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('Sew');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('Soo');
-    });
-  }
-
-  test_ClassDeclaration_body_final_final() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ final foo;}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('x');
-    });
-  }
-
-  test_ClassDeclaration_body_final_var() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testB.dart',
-        '''
-      class B { }''');
-    addTestSource('''
-      import "testB.dart" as x;
-      class A {final ^ var foo;}
-      class _B {}
-      A T;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
-      assertSuggestLocalClass('_B');
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T');
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('x');
-    });
-  }
-
-  test_Combinator_hide() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" hide ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_Combinator_show() {
-    // SimpleIdentifier  HideCombinator  ImportDirective
-    addSource(
-        '/testAB.dart',
-        '''
-      library libAB;
-      part '/partAB.dart';
-      class A { }
-      class B { }''');
-    addSource(
-        '/partAB.dart',
-        '''
-      part of libAB;
-      var T1;
-      PB F1() => new PB();
-      typedef PB2 F2(int blat);
-      class Clz = Object with Object;
-      class PB { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      class C { }
-      class D { }''');
-    addTestSource('''
-      import "/testAB.dart" show ^;
-      import "/testCD.dart";
-      class X {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ConditionalExpression_elseExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_elseExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_partial_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_partial_thenExpression_empty() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConditionalExpression_thenExpression() {
-    // SimpleIdentifier  ConditionalExpression  ReturnStatement
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} return a ? T^ : c}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_ConstructorName_importedClass() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      var m;
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by NamedConstructorContributor
-      assertNotSuggested('c');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_importedFactory() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {factory X.c(); factory X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      var m;
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by NamedConstructorContributor
-      assertNotSuggested('c');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_importedFactory2() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      main() {new String.fr^omCharCodes([]);}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 2);
-      expect(request.replacementLength, 13);
-      // Suggested by NamedConstructorContributor
-      assertNotSuggested('fromCharCodes');
-      assertNotSuggested('isEmpty');
-      assertNotSuggested('isNotEmpty');
-      assertNotSuggested('length');
-      assertNotSuggested('Object');
-      assertNotSuggested('String');
-    });
-  }
-
-  test_ConstructorName_localClass() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by NamedConstructorContributor
-      assertNotSuggested('c');
-      assertNotSuggested('_d');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_ConstructorName_localFactory() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
-    // InstanceCreationExpression
-    addTestSource('''
-      int T1;
-      F1() { }
-      class X {factory X.c(); factory X._d(); z() {}}
-      main() {new X.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by NamedConstructorContributor
-      assertNotSuggested('c');
-      assertNotSuggested('_d');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_DefaultFormalParameter_named_expression() {
-    // DefaultFormalParameter FormalParameterList MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {a(blat: ^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('foo', null);
-      assertSuggestLocalMethod('a', 'A', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('String');
-      assertSuggestImportedFunction('identical', 'bool');
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_ExpressionStatement_identifier() {
-    // SimpleIdentifier  ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      _B F1() { }
-      class A {int x;}
-      class _B { }''');
-    addTestSource('''
-      import "/testA.dart";
-      typedef int F2(int blat);
-      class Clz = Object with Object;
-      class C {foo(){^} void bar() {}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', '_B');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalMethod('bar', 'C', 'void');
-      assertSuggestLocalFunctionTypeAlias('F2', 'int');
-      assertSuggestLocalClassTypeAlias('Clz');
-      assertSuggestLocalClass('C');
-      assertNotSuggested('x');
-      assertNotSuggested('_B');
-    });
-  }
-
-  test_ExpressionStatement_name() {
-    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      B T1;
-      class B{}''');
-    addTestSource('''
-      import "/testA.dart";
-      class C {a() {C ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldDeclaration_name_typed() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addSource('/testA.dart', 'class A { }');
-    addTestSource('''
-      import "/testA.dart";
-      class C {A ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldDeclaration_name_var() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // FieldDeclaration
-    addSource('/testA.dart', 'class A { }');
-    addTestSource('''
-      import "/testA.dart";
-      class C {var ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_FieldFormalParameter_in_non_constructor() {
-    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
-    addTestSource('class A {B(this.^foo) {}}');
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 3);
-      assertNoSuggestions();
-    });
-  }
-
-  test_ForEachStatement_body_typed() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (int foo in bar) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestLocalVariable('foo', 'int');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_body_untyped() {
-    // Block  ForEachStatement
-    addTestSource('main(args) {for (foo in bar) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestLocalVariable('foo', null);
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_iterable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (int foo in ^) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestParameter('args', null);
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForEachStatement_loopVariable() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('args');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_ForEachStatement_loopVariable_type() {
-    // SimpleIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (^ foo in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('args');
-      assertNotSuggested('foo');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_ForEachStatement_loopVariable_type2() {
-    // DeclaredIdentifier  ForEachStatement  Block
-    addTestSource('main(args) {for (S^ foo in args) {}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertNotSuggested('args');
-      assertNotSuggested('foo');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_FormalParameterList() {
-    // FormalParameterList MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {a(^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('foo');
-      assertNotSuggested('a');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('String');
-      assertNotSuggested('identical');
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_ForStatement_body() {
-    // Block  ForStatement
-    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('i', 'int');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_ForStatement_condition() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; i^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-    });
-  }
-
-  test_ForStatement_initializer() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', 'List');
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedClass('int');
-    });
-  }
-
-  test_ForStatement_updaters() {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {for (int index = 0; index < 10; i^)}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-    });
-  }
-
-  test_ForStatement_updaters_prefix_expression() {
-    // SimpleIdentifier  PrefixExpression  ForStatement
-    addTestSource('''
-      void bar() { }
-      main() {for (int index = 0; index < 10; ++i^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestLocalVariable('index', 'int');
-      assertSuggestLocalFunction('main', null);
-      assertNotSuggested('bar');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      /* */ ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment2() {
-    // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      /** */ ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionDeclaration_returnType_afterComment3() {
-    // FunctionDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      /// some dartdoc
-      class C2 { }
-      ^ zoo(z) { } String name;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_FunctionExpression_body_function() {
-    // Block  BlockFunctionBody  FunctionExpression
-    addTestSource('''
-      void bar() { }
-      String foo(List args) {x.then((R b) {^});}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      var f = assertSuggestLocalFunction('foo', 'String', deprecated: false);
-      if (f != null) {
-        expect(f.element.isPrivate, isFalse);
-      }
-      assertSuggestLocalFunction('bar', 'void');
-      assertSuggestParameter('args', 'List');
-      assertSuggestParameter('b', 'R');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IfStatement() {
-    // SimpleIdentifier  IfStatement
-    addTestSource('''
-      class A {var b; X _c; foo() {A a; if (true) ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('b', null);
-      assertSuggestLocalField('_c', 'X');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_IfStatement_condition() {
-    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', null);
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IfStatement_empty() {
-    // SimpleIdentifier  IfStatement
-    addTestSource('''
-      class A {var b; X _c; foo() {A a; if (^) something}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalField('b', null);
-      assertSuggestLocalField('_c', 'X');
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_IfStatement_invocation() {
-    // SimpleIdentifier  PrefixIdentifier  IfStatement
-    addTestSource('''
-      main() {var a; if (a.^) something}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationMethod('toString', 'Object', 'String');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ImportDirective_dart() {
-    // SimpleStringLiteral  ImportDirective
-    addTestSource('''
-      import "dart^";
-      main() {}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_IndexExpression() {
-    // ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} f[^]}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('x');
-      assertSuggestLocalVariable('f', null);
-      assertSuggestLocalMethod('foo', 'C', null);
-      assertSuggestLocalClass('C');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestImportedClass('A');
-      assertSuggestImportedFunction('F1', null);
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_IndexExpression2() {
-    // SimpleIdentifier IndexExpression ExpressionStatement  Block
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      class B {int x;}
-      class C {foo(){var f; {var x;} f[T^]}}''');
-    computeFast();
-    return computeFull((bool result) {
-      // top level results are partially filtered based on first char
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      // TODO (danrubel) getter is being suggested instead of top level var
-      //assertSuggestImportedTopLevelVar('T1', 'int');
-    });
-  }
-
-  test_InstanceCreationExpression_imported() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      class A {A(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      import "dart:async";
-      int T2;
-      F2() { }
-      class B {B(this.x, [String boo]) { } int x;}
-      class C {foo(){var f; {var x;} new ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('Future');
-      assertSuggestImportedConstructor('A');
-      assertSuggestLocalConstructor('B');
-      assertSuggestLocalConstructor('C');
-      assertNotSuggested('f');
-      assertNotSuggested('x');
-      assertNotSuggested('foo');
-      assertNotSuggested('F1');
-      assertNotSuggested('F2');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-    });
-  }
-
-  test_InstanceCreationExpression_unimported() {
-    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('class C {foo(){new F^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedConstructor('Future',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:async');
-      assertSuggestImportedConstructor('Foo',
-          relevance: DART_RELEVANCE_LOW, importUri: 'testAB.dart');
-    });
-  }
-
-  test_InterpolationExpression() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      main() {String name; print("hello \$^");}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('Object');
-      // TODO(danrubel) should return top level var rather than getter
-      if (contributor is ImportedReferenceContributor) {
-        //assertSuggestImportedTopLevelVar('T1', 'int');
-        assertSuggestGetter('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertNotSuggested('D1');
-      assertNotSuggested('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertNotSuggested('D2');
-      assertNotSuggested('C2');
-      assertSuggestLocalVariable('name', 'String');
-    });
-  }
-
-  test_InterpolationExpression_block() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      main() {String name; print("hello \${^}");}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      // TODO(danrubel) should return top level var rather than getter
-      if (contributor is ImportedReferenceContributor) {
-        //assertSuggestImportedTopLevelVar('T1', 'int');
-        assertSuggestGetter('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertSuggestLocalVariable('name', 'String');
-    });
-  }
-
-  test_InterpolationExpression_block2() {
-    // SimpleIdentifier  InterpolationExpression  StringInterpolation
-    addTestSource('main() {String name; print("hello \${n^}");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('name', 'String');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_InterpolationExpression_prefix_selector() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${name.^}");}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('length', 'int');
-      assertNotSuggested('name');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_InterpolationExpression_prefix_selector2() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \$name.^");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_InterpolationExpression_prefix_target() {
-    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
-    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('name', 'String');
-      // top level results are partially filtered
-      //assertSuggestImportedClass('Object');
-      assertNotSuggested('length');
-    });
-  }
-
-  test_IsExpression() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      main() {var x; if (x is ^) { }}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertSuggestLocalClass('Y');
-      assertNotSuggested('x');
-      assertNotSuggested('main');
-      assertNotSuggested('foo');
-    });
-  }
-
-  test_IsExpression_target() {
-    // IfStatement  Block  BlockFunctionBody
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {int x; int y() => 0;}
-      main(){var a; if (^ is A)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalVariable('a', null);
-      assertSuggestLocalFunction('main', null);
-      assertSuggestLocalFunction('foo', null);
-      assertNotSuggested('bar');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IsExpression_type() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (a is ^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('a');
-      assertNotSuggested('main');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_IsExpression_type_partial() {
-    // SimpleIdentifier  TypeName  IsExpression  IfStatement
-    addTestSource('''
-      class A {int x; int y() => 0;}
-      main(){var a; if (a is Obj^)}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertNotSuggested('a');
-      assertNotSuggested('main');
-      assertSuggestLocalClass('A');
-      assertSuggestImportedClass('Object');
-    });
-  }
-
-  test_keyword() {
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int newT1;
-      int T1;
-      nowIsIt() { }
-      class X {factory X.c(); factory X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      String newer() {}
-      var m;
-      main() {new^ X.c();}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 3);
-      expect(request.replacementLength, 3);
-      assertNotSuggested('c');
-      assertNotSuggested('_d');
-      // Imported suggestion are filtered by 1st character
-      assertSuggestImportedFunction('nowIsIt', null);
-      assertNotSuggested('T1');
-      // TODO (danrubel) this really should be TopLevelVar not getter/setter
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('newT1', 'int');
-      }
-      assertNotSuggested('z');
-      assertSuggestLocalTopLevelVar('m', 'dynamic');
-      assertSuggestLocalFunction('newer', 'String');
-    });
-  }
-
-  test_Literal_list() {
-    // ']'  ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([^]);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('Some', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Literal_list2() {
-    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
-    addTestSource('main() {var Some; print([S^]);}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalVariable('Some', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_Literal_string() {
-    // SimpleStringLiteral  ExpressionStatement  Block
-    addTestSource('class A {a() {"hel^lo"}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_MapLiteralEntry() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {^''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestImportedFunction('F1', null);
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalTopLevelVar('T2', 'int');
-      assertSuggestLocalFunction('F2', null);
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-    });
-  }
-
-  test_MapLiteralEntry1() {
-    // MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {T^''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestLocalTopLevelVar('T2', 'int');
-    });
-  }
-
-  test_MapLiteralEntry2() {
-    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 { }
-      foo = {7:T^};''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      // TODO(danrubel) Should be top level variable
-      if (contributor is ImportedReferenceContributor) {
-        assertSuggestGetter('T1', 'int');
-        // assertSuggestImportedTopLevelVar('T1', 'int');
-      }
-      assertSuggestLocalTopLevelVar('T2', 'int');
-    });
-  }
-
-  test_MethodDeclaration_body_getters() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('a', 'A', 'Z');
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isFalse);
-        expect(methodA.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion getterF = assertSuggestLocalGetter('f', 'X',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (getterF != null) {
-        expect(getterF.element.isDeprecated, isTrue);
-        expect(getterF.element.isPrivate, isFalse);
-      }
-      CompletionSuggestion getterG = assertSuggestLocalGetter('_g', null,
-          relevance: DART_RELEVANCE_DEFAULT);
-      if (getterG != null) {
-        expect(getterG.element.isDeprecated, isFalse);
-        expect(getterG.element.isPrivate, isTrue);
-      }
-    });
-  }
-
-  test_MethodDeclaration_body_static() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testC.dart',
-        '''
-      class C {
-        c1() {}
-        var c2;
-        static c3() {}
-        static var c4;}''');
-    addTestSource('''
-      import "/testC.dart";
-      class B extends C {
-        b1() {}
-        var b2;
-        static b3() {}
-        static var b4;}
-      class A extends B {
-        a1() {}
-        var a2;
-        static a3() {}
-        static var a4;
-        static a() {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNotSuggested('a1');
-      assertNotSuggested('a2');
-      assertSuggestLocalMethod('a3', 'A', null);
-      assertSuggestLocalField('a4', null);
-      assertNotSuggested('b1');
-      assertNotSuggested('b2');
-      assertNotSuggested('b3');
-      assertNotSuggested('b4');
-      assertNotSuggested('c1');
-      assertNotSuggested('c2');
-      assertNotSuggested('c3');
-      assertNotSuggested('c4');
-    });
-  }
-
-  test_MethodDeclaration_members() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('_a', 'A', 'Z',
-          relevance: DART_RELEVANCE_DEFAULT);
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isFalse);
-        expect(methodA.element.isPrivate, isTrue);
-      }
-      CompletionSuggestion getterF = assertSuggestLocalField('f', 'X',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (getterF != null) {
-        expect(getterF.element.isDeprecated, isTrue);
-        expect(getterF.element.isPrivate, isFalse);
-        expect(getterF.element.parameters, isNull);
-      }
-      CompletionSuggestion getterG = assertSuggestLocalField('_g', null);
-      if (getterG != null) {
-        expect(getterG.element.isDeprecated, isFalse);
-        expect(getterG.element.isPrivate, isTrue);
-        expect(getterF.element.parameters, isNull);
-      }
-      assertSuggestImportedClass('bool');
-    });
-  }
-
-  test_MethodDeclaration_parameters_named() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      CompletionSuggestion methodA = assertSuggestLocalMethod('a', 'A', 'Z',
-          relevance: DART_RELEVANCE_LOW, deprecated: true);
-      if (methodA != null) {
-        expect(methodA.element.isDeprecated, isTrue);
-        expect(methodA.element.isPrivate, isFalse);
-      }
-      assertSuggestParameter('x', 'X');
-      assertSuggestParameter('y', null);
-      assertSuggestParameter('b', null);
-      assertSuggestImportedClass('int');
-      assertNotSuggested('_');
-    });
-  }
-
-  test_MethodDeclaration_parameters_positional() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('''
-      foo() { }
-      void bar() { }
-      class A {Z a(X x, [int y=1]) {^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalFunction('foo', null);
-      assertSuggestLocalFunction('bar', 'void');
-      assertSuggestLocalMethod('a', 'A', 'Z');
-      assertSuggestParameter('x', 'X');
-      assertSuggestParameter('y', 'int');
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_MethodDeclaration_returnType() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment() {
-    // ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {/* */ ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment2() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {/** */ ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodDeclaration_returnType_afterComment3() {
-    // MethodDeclaration  ClassDeclaration  CompilationUnit
-    addSource(
-        '/testA.dart',
-        '''
-      int T1;
-      F1() { }
-      typedef D1();
-      class C1 {C1(this.x) { } int x;}''');
-    addTestSource('''
-      import "/testA.dart";
-      int T2;
-      F2() { }
-      typedef D2();
-      class C2 {
-        /// some dartdoc
-        ^ zoo(z) { } String name; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertNotSuggested('T1');
-      assertNotSuggested('F1');
-      assertSuggestImportedFunctionTypeAlias('D1', null);
-      assertSuggestImportedClass('C1');
-      assertNotSuggested('T2');
-      assertNotSuggested('F2');
-      assertSuggestLocalFunctionTypeAlias('D2', null);
-      assertSuggestLocalClass('C2');
-      assertNotSuggested('name');
-    });
-  }
-
-  test_MethodInvocation_no_semicolon() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {x.^ m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_new_instance() {
-    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationMethod('nextBool', 'Random', 'bool');
-      assertSuggestInvocationMethod('nextDouble', 'Random', 'double');
-      assertSuggestInvocationMethod('nextInt', 'Random', 'int');
-      assertNotSuggested('Random');
-      assertNotSuggested('Object');
-      assertNotSuggested('A');
-    });
-  }
-
-  test_parameterName_excludeTypes() {
-    addTestSource('m(int ^) {}');
-    return computeFull((bool result) {
-      assertNotSuggested('int');
-      assertNotSuggested('bool');
-    });
-  }
-
-  test_partFile_TypeName() {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addSource(
-        '/testA.dart',
-        '''
-      library libA;
-      import "/testB.dart";
-      part "$testFile";
-      class A { }
-      var m;''');
-    addTestSource('''
-      part of libA;
-      class B { factory B.bar(int x) => null; }
-      main() {new ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalConstructor('B.bar');
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('X.c');
-      assertNotSuggested('X._d');
-      assertSuggestImportedConstructor('A');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_partFile_TypeName2() {
-    // SimpleIdentifier  TypeName  ConstructorName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      int T1;
-      F1() { }
-      class X {X.c(); X._d(); z() {}}''');
-    addSource(
-        '/testA.dart',
-        '''
-      part of libA;
-      class B { }''');
-    addTestSource('''
-      library libA;
-      import "/testB.dart";
-      part "/testA.dart";
-      class A { A({String boo: 'hoo'}) { } }
-      main() {new ^}
-      var m;''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestLocalConstructor('A');
-      assertSuggestImportedConstructor('Object');
-      assertSuggestImportedConstructor('X.c');
-      assertNotSuggested('X._d');
-      assertSuggestImportedConstructor('B');
-      assertNotSuggested('F1');
-      assertNotSuggested('T1');
-      assertNotSuggested('_d');
-      assertNotSuggested('z');
-      assertNotSuggested('m');
-    });
-  }
-
-  test_PrefixedIdentifier_class_const() {
-    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class I {
-        static const scI = 'boo';
-        X get f => new A();
-        get _g => new A();}
-      class B implements I {
-        static const int scB = 12;
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    addTestSource('''
-      import "/testB.dart";
-      class A extends B {
-        static const String scA = 'foo';
-        w() { }}
-      main() {A.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by StaticMemberContributor
-      assertNotSuggested('scA');
-      assertNotSuggested('scB');
-      assertNotSuggested('scI');
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('w');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_class_imported() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        static const int sc = 12;
-        @deprecated var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    addTestSource('''
-      import "/testB.dart";
-      main() {A a; a.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('sc');
-      assertSuggestInvocationField('b', null, isDeprecated: true);
-      assertNotSuggested('_c');
-      assertSuggestInvocationGetter('d', 'X');
-      assertNotSuggested('_e');
-      assertSuggestInvocationGetter('f', 'X');
-      assertNotSuggested('_g');
-      assertSuggestInvocationSetter('s1');
-      assertNotSuggested('_s2');
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertNotSuggested('_n');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_class_local() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('''
-      main() {A a; a.^}
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        static const int sc = 12;
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        set s1(I x) {} set _s2(I x) {}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('sc');
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertNotSuggested('a');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_getter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String get g => "one"; f() {g.^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_library() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      main() {b.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by LibraryMemberContributor
-      assertNotSuggested('X');
-      assertNotSuggested('Y');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_library_typesOnly() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      foo(b.^ f) {}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by LibraryMemberContributor
-      assertNotSuggested('X');
-      assertNotSuggested('Y');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_library_typesOnly2() {
-    // SimpleIdentifier  PrefixedIdentifier  TypeName
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      var T1;
-      class X { }
-      class Y { }''');
-    addTestSource('''
-      import "/testB.dart" as b;
-      var T2;
-      class A { }
-      foo(b.^) {}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Suggested by LibraryMemberContributor
-      assertNotSuggested('X');
-      assertNotSuggested('Y');
-      assertNotSuggested('T1');
-      assertNotSuggested('T2');
-      assertNotSuggested('Object');
-      assertNotSuggested('b');
-      assertNotSuggested('A');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_parameter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      class _W {M y; var _z;}
-      class X extends _W {}
-      class M{}''');
-    addTestSource('''
-      import "/testB.dart";
-      foo(X x) {x.^}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('y', 'M');
-      assertNotSuggested('_z');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PrefixedIdentifier_prefix() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addSource(
-        '/testA.dart',
-        '''
-      class A {static int bar = 10;}
-      _B() {}''');
-    addTestSource('''
-      import "/testA.dart";
-      class X {foo(){A^.bar}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('A');
-      assertSuggestLocalClass('X');
-      assertSuggestLocalMethod('foo', 'X', null);
-      assertNotSuggested('bar');
-      assertNotSuggested('_B');
-    });
-  }
-
-  test_PrefixedIdentifier_propertyAccess() {
-    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
-    addTestSource('class A {String x; int get foo {x.^}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEmpty', 'bool');
-      assertSuggestInvocationMethod('compareTo', 'Comparable', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_propertyAccess_newStmt() {
-    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
-    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEmpty', 'bool');
-      assertSuggestInvocationMethod('compareTo', 'Comparable', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_const() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_field() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_function() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_getter() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_local_typed() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f() {String g; g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_local_untyped() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_method() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_param() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_localVariableDeclarationName() {
-    addTestSource('main() {String m^}');
-    return computeFull((bool result) {
-      assertNotSuggested('main');
-      assertNotSuggested('min');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_param2() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('f(String g) {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PrefixedIdentifier_trailingStmt_topLevelVar() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('String g; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  test_PropertyAccess_expression() {
-    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
-    addTestSource('class A {a() {"hello".to^String().length}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 2);
-      expect(request.replacementLength, 8);
-      assertSuggestInvocationGetter('length', 'int');
-      assertNotSuggested('A');
-      assertNotSuggested('a');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_PropertyAccess_noTarget() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('class C {foo(){.^}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_PropertyAccess_noTarget2() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addSource('/testAB.dart', 'class Foo { }');
-    addTestSource('main() {.^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_PropertyAccess_selector() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
-    addTestSource('class A {a() {"hello".length.^}}');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationGetter('isEven', 'bool');
-      assertNotSuggested('A');
-      assertNotSuggested('a');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_SwitchStatement_c() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_SwitchStatement_case() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestLocalClass('A');
-      assertSuggestLocalMethod('g', 'A', 'String');
-      assertSuggestLocalVariable('t', null);
-      assertSuggestImportedClass('String');
-    });
-  }
-
-  test_SwitchStatement_empty() {
-    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
-    addTestSource('class A {String g(int x) {switch(x) {^}}}');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_ThisExpression_block() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A() {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {this.^ m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor() {
-    // MethodInvocation  ExpressionStatement  Block
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A() {this.^}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestInvocationField('b', null);
-      assertSuggestInvocationField('_c', 'X');
-      assertSuggestInvocationGetter('d', 'X');
-      assertSuggestInvocationGetter('_e', null);
-      assertSuggestInvocationGetter('f', 'X');
-      assertSuggestInvocationGetter('_g', null);
-      assertSuggestInvocationMethod('m', 'A', null);
-      assertSuggestInvocationMethod('_n', 'A', 'I');
-      assertSuggestInvocationSetter('s1');
-      assertSuggestInvocationSetter('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.^) {}
-        A.z() {}
-        var b; X _c; static sb;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      // Contributed by FieldFormalConstructorContributor
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('sb');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param2() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.b^) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      // Contributed by FieldFormalConstructorContributor
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param3() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.^b) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 1);
-      // Contributed by FieldFormalConstructorContributor
-      assertNotSuggested('b');
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_ThisExpression_constructor_param4() {
-    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
-    addTestSource('''
-      main() { }
-      class I {X get f => new A();get _g => new A();}
-      class A implements I {
-        A(this.b, this.^) {}
-        A.z() {}
-        var b; X _c;
-        X get d => new A();get _e => new A();
-        // no semicolon between completion point and next statement
-        set s1(I x) {} set _s2(I x) {m(null);}
-        m(X x) {} I _n(X x) {}}
-      class X{}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertNotSuggested('b');
-      // Contributed by FieldFormalConstructorContributor
-      assertNotSuggested('_c');
-      assertNotSuggested('d');
-      assertNotSuggested('_e');
-      assertNotSuggested('f');
-      assertNotSuggested('_g');
-      assertNotSuggested('m');
-      assertNotSuggested('_n');
-      assertNotSuggested('s1');
-      assertNotSuggested('_s2');
-      assertNotSuggested('z');
-      assertNotSuggested('I');
-      assertNotSuggested('A');
-      assertNotSuggested('X');
-      assertNotSuggested('Object');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_TopLevelVariableDeclaration_typed_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} B ^');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_TopLevelVariableDeclaration_untyped_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // TopLevelVariableDeclaration
-    addTestSource('class A {} var ^');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_TypeArgumentList() {
-    // SimpleIdentifier  BinaryExpression  ExpressionStatement
-    addSource(
-        '/testA.dart',
-        '''
-      class C1 {int x;}
-      F1() => 0;
-      typedef String T1(int blat);''');
-    addTestSource('''
-      import "/testA.dart";'
-      class C2 {int x;}
-      F2() => 0;
-      typedef int T2(int blat);
-      class C<E> {}
-      main() { C<^> c; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedClass('C1');
-      assertSuggestImportedFunctionTypeAlias('T1', 'String');
-      assertSuggestLocalClass('C2');
-      assertSuggestLocalFunctionTypeAlias('T2', 'int');
-      assertNotSuggested('F1');
-      assertNotSuggested('F2');
-    });
-  }
-
-  test_TypeArgumentList2() {
-    // TypeName  TypeArgumentList  TypeName
-    addSource(
-        '/testA.dart',
-        '''
-      class C1 {int x;}
-      F1() => 0;
-      typedef String T1(int blat);''');
-    addTestSource('''
-      import "/testA.dart";'
-      class C2 {int x;}
-      F2() => 0;
-      typedef int T2(int blat);
-      class C<E> {}
-      main() { C<C^> c; }''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset - 1);
-      expect(request.replacementLength, 1);
-      assertSuggestImportedClass('C1');
-      assertSuggestLocalClass('C2');
-    });
-  }
-
-  test_VariableDeclaration_name() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement  Block
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      main() {var ^}''');
-    computeFast();
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_VariableDeclarationList_final() {
-    // VariableDeclarationList  VariableDeclarationStatement  Block
-    addTestSource('main() {final ^} class C { }');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('Object');
-      assertSuggestLocalClass('C');
-      assertNotSuggested('==');
-    });
-  }
-
-  test_VariableDeclarationStatement_RHS() {
-    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      class Y {Y.c(); Y._d(); z() {}}
-      class C {bar(){var f; {var x;} var e = ^}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertNotSuggested('_B');
-      assertSuggestLocalClass('Y');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalVariable('f', null);
-      assertNotSuggested('x');
-      assertNotSuggested('e');
-    });
-  }
-
-  test_VariableDeclarationStatement_RHS_missing_semicolon() {
-    // VariableDeclaration  VariableDeclarationList
-    // VariableDeclarationStatement
-    addSource(
-        '/testB.dart',
-        '''
-      lib B;
-      foo1() { }
-      void bar1() { }
-      class _B { }
-      class X {X.c(); X._d(); z() {}}''');
-    addTestSource('''
-      import "/testB.dart";
-      foo2() { }
-      void bar2() { }
-      class Y {Y.c(); Y._d(); z() {}}
-      class C {bar(){var f; {var x;} var e = ^ var g}}''');
-    computeFast();
-    return computeFull((bool result) {
-      expect(request.replacementOffset, completionOffset);
-      expect(request.replacementLength, 0);
-      assertSuggestImportedClass('X');
-      assertSuggestImportedFunction('foo1', null);
-      assertNotSuggested('bar1');
-      assertSuggestLocalFunction('foo2', null);
-      assertNotSuggested('bar2');
-      assertNotSuggested('_B');
-      assertSuggestLocalClass('Y');
-      assertSuggestLocalClass('C');
-      assertSuggestLocalVariable('f', null);
-      assertNotSuggested('x');
-      assertNotSuggested('e');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index be250e7..921525b 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -94,7 +94,8 @@
       library libAB;
       part '/partAB.dart';
       class A { }
-      class B { }''');
+      class B { }
+      class _AB''');
     addSource(
         '/partAB.dart',
         '''
@@ -124,6 +125,7 @@
     assertSuggestClass('B',
         relevance: DART_RELEVANCE_DEFAULT,
         kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('_AB');
     assertSuggestClass('PB',
         relevance: DART_RELEVANCE_DEFAULT,
         kind: CompletionSuggestionKind.IDENTIFIER);
@@ -134,8 +136,8 @@
     assertSuggestClass('Clz',
         relevance: DART_RELEVANCE_DEFAULT,
         kind: CompletionSuggestionKind.IDENTIFIER);
-    assertSuggestFunctionTypeAlias('F2', null, false, DART_RELEVANCE_DEFAULT,
-        CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunctionTypeAlias('F2', null,
+        kind: CompletionSuggestionKind.IDENTIFIER);
     assertNotSuggested('C');
     assertNotSuggested('D');
     assertNotSuggested('X');
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index 66b236d..498b3d1 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -7,22 +7,13 @@
 import 'dart:async';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/analysis_server.dart'
-    show ContextSourcePair;
-import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_memory_index.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
-import '../../../analysis_abstract.dart';
-import '../../../mocks.dart';
+import '../../../domain_completion_util.dart';
 import '../../../utils.dart';
 
 main() {
@@ -31,127 +22,29 @@
 }
 
 @reflectiveTest
-class CommonUsageSorterTest extends AbstractAnalysisTest {
-  String completionId;
-  int completionOffset;
-  int replacementOffset;
-  int replacementLength;
-  List<CompletionSuggestion> suggestions = [];
-  bool suggestionsDone = false;
-
-  String addTestFile(String content) {
-    completionOffset = content.indexOf('^');
-    expect(completionOffset, isNot(equals(-1)), reason: 'missing ^');
-    int nextOffset = content.indexOf('^', completionOffset + 1);
-    expect(nextOffset, equals(-1), reason: 'too many ^');
-    return super.addTestFile(content.substring(0, completionOffset) +
-        content.substring(completionOffset + 1));
-  }
-
-  void assertHasResult(CompletionSuggestionKind kind, String completion,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      bool isDeprecated = false,
-      bool isPotential = false]) {
-    var cs;
-    suggestions.forEach((s) {
-      if (s.completion == completion) {
-        if (cs == null) {
-          cs = s;
-        } else {
-          fail('expected exactly one $completion but found > 1');
-        }
-      }
-    });
-    if (cs == null) {
-      var completions = suggestions.map((s) => s.completion).toList();
-      fail('expected "$completion" but found\n $completions');
+class CommonUsageSorterTest extends AbstractCompletionDomainTest {
+  Future getSuggestionsWith(Map<String, List<String>> selectorRelevance) async {
+    var originalSorter = DartCompletionManager.contributionSorter;
+    DartCompletionManager.contributionSorter =
+        new CommonUsageSorter(selectorRelevance);
+    try {
+      return await getSuggestions();
+    } finally {
+      DartCompletionManager.contributionSorter = originalSorter;
     }
-    expect(cs.kind, equals(kind));
-    expect(cs.relevance, equals(relevance));
-    expect(cs.selectionOffset, equals(completion.length));
-    expect(cs.selectionLength, equals(0));
-    expect(cs.isDeprecated, equals(isDeprecated));
-    expect(cs.isPotential, equals(isPotential));
-  }
-
-  void assertNoResult(String completion) {
-    if (suggestions.any((cs) => cs.completion == completion)) {
-      fail('did not expect completion: $completion');
-    }
-  }
-
-  void assertValidId(String id) {
-    expect(id, isNotNull);
-    expect(id.isNotEmpty, isTrue);
-  }
-
-  @override
-  Index createIndex() {
-    return createLocalMemoryIndex();
-  }
-
-  Future getSuggestions(Map<String, List<String>> selectorRelevance) async {
-    await waitForTasksFinished();
-    CompletionGetSuggestionsParams params =
-        new CompletionGetSuggestionsParams(testFile, completionOffset);
-    Request request = params.toRequest('0');
-    CompletionDomainHandler domainHandler = new CompletionDomainHandler(server);
-    handler = domainHandler;
-
-    ContextSourcePair contextSource = server.getContextSourcePair(params.file);
-    AnalysisContext context = contextSource.context;
-    Source source = contextSource.source;
-    DartCompletionManager completionManager = new DartCompletionManager(
-        context,
-        server.searchEngine,
-        source,
-        new DartCompletionCache(context, source),
-        null,
-        server.serverPlugin.completionContributors,
-        new CommonUsageSorter(selectorRelevance));
-
-    Response response =
-        domainHandler.processRequest(request, completionManager);
-    expect(response, isResponseSuccess('0'));
-    completionId = response.id;
-    assertValidId(completionId);
-    await pumpEventQueue();
-    expect(suggestionsDone, isTrue);
-  }
-
-  void processNotification(Notification notification) {
-    if (notification.event == COMPLETION_RESULTS) {
-      var params = new CompletionResultsParams.fromNotification(notification);
-      String id = params.id;
-      assertValidId(id);
-      if (id == completionId) {
-        expect(suggestionsDone, isFalse);
-        replacementOffset = params.replacementOffset;
-        replacementLength = params.replacementLength;
-        suggestionsDone = params.isLast;
-        expect(suggestionsDone, isNotNull);
-        suggestions = params.results;
-      }
-    }
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    createProject();
   }
 
   test_ConstructorName() async {
     // SimpleIdentifier  ConstructorName  InstanceCreationExpression
     addTestFile('import "dart:async"; class A {x() {new Future.^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       'dart.async.Future': ['value', 'wait']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'delayed');
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'value',
-        DART_RELEVANCE_COMMON_USAGE);
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -160,14 +53,14 @@
   test_PrefixedIdentifier_field() async {
     // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
     addTestFile('class A {static int s1; static int s2; x() {A.^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       '.A': ['s2']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -178,13 +71,13 @@
     addFile('/project/bin/myLib.dart',
         'library L; part "$testFile"; class A {static int s2;}');
     addTestFile('part of L; foo() {A.^}');
-    await getSuggestions({
+    await getSuggestionsWith({
       'L.A': ['s2']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -193,14 +86,14 @@
   test_PrefixedIdentifier_getter() async {
     // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
     addTestFile('class A {int get g1 => 1; int get g2 => 2; x() {new A().^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       '.A': ['g2']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'g1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 'g2', DART_RELEVANCE_COMMON_USAGE);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 'g2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -209,14 +102,14 @@
   test_PrefixedIdentifier_setter() async {
     // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
     addTestFile('class A {set s1(v) {}; set s2(v) {}; x() {new A().^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       '.A': ['s2']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 's1');
-    assertHasResult(
-        CompletionSuggestionKind.INVOCATION, 's2', DART_RELEVANCE_COMMON_USAGE);
+    assertHasResult(CompletionSuggestionKind.INVOCATION, 's2',
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -225,13 +118,13 @@
   test_PrefixedIdentifier_static_method() async {
     // SimpleIdentifier  PrefixedIdentifeir  ExpressionStatement
     addTestFile('import "dart:async"; class A {x() {Future.^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       'dart.async.Future': ['value', 'wait']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'wait',
-        DART_RELEVANCE_COMMON_USAGE - 1);
+        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
     assertNoResult('Future');
     assertNoResult('Object');
     assertNoResult('A');
@@ -240,16 +133,16 @@
   test_PropertyAccess() async {
     // SimpleIdentifier  PropertyAccess  ExpressionStatement
     addTestFile('import "dart:math"; class A {x() {new Random().^}}');
-    await getSuggestions({
+    await getSuggestionsWith({
       'dart.math.Random': ['nextInt', 'nextDouble']
     });
     expect(replacementOffset, equals(completionOffset));
     expect(replacementLength, equals(0));
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextBool');
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextDouble',
-        DART_RELEVANCE_COMMON_USAGE - 1);
+        relevance: DART_RELEVANCE_COMMON_USAGE - 1);
     assertHasResult(CompletionSuggestionKind.INVOCATION, 'nextInt',
-        DART_RELEVANCE_COMMON_USAGE);
+        relevance: DART_RELEVANCE_COMMON_USAGE);
     assertNoResult('Random');
     assertNoResult('Object');
     assertNoResult('A');
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 59e5e69..d76f15c1 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -14,13 +14,12 @@
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
-    show DartCompletionRequestImpl;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'
-    show DART_RELEVANCE_DEFAULT, DART_RELEVANCE_LOW, ReplacementRange;
+    show DartCompletionRequestImpl, ReplacementRange;
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../../../abstract_context.dart';
@@ -43,6 +42,15 @@
   DartCompletionRequest request;
   List<CompletionSuggestion> suggestions;
 
+  /**
+   * If `true` and `null` is specified as the suggestion's expected returnType
+   * then the actual suggestion is expected to have a `dynamic` returnType.
+   * Newer tests return `false` so that they can distinguish between
+   * `dynamic` and `null`.
+   * Eventually all tests should be converted and this getter removed.
+   */
+  bool get isNullExpectedReturnTypeConsideredDynamic => true;
+
   void addTestSource(String content) {
     expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
     completionOffset = content.indexOf('^');
@@ -112,7 +120,7 @@
     if (isDeprecated) {
       expect(cs.relevance, equals(DART_RELEVANCE_LOW));
     } else {
-      expect(cs.relevance, equals(relevance));
+      expect(cs.relevance, equals(relevance), reason: completion);
     }
     expect(cs.importUri, importUri);
     expect(cs.selectionOffset, equals(completion.length));
@@ -142,6 +150,7 @@
       CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
       bool isDeprecated: false,
       String elemFile,
+      String elemName,
       int elemOffset}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind,
@@ -153,6 +162,21 @@
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.CLASS));
+    expect(element.name, equals(elemName ?? name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestClassTypeAlias(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.CLASS_TYPE_ALIAS));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
     expect(element.returnType, isNull);
@@ -218,41 +242,59 @@
 
   CompletionSuggestion assertSuggestFunction(String name, String returnType,
       {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
+      bool isDeprecated: false,
       int relevance: DART_RELEVANCE_DEFAULT,
       String importUri}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
         importUri: importUri,
-        isDeprecated: deprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+        isDeprecated: isDeprecated);
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.FUNCTION));
     expect(element.name, equals(name));
-    expect(element.isDeprecated, equals(deprecated));
+    expect(element.isDeprecated, equals(isDeprecated));
     String param = element.parameters;
     expect(param, isNotNull);
     expect(param[0], equals('('));
     expect(param[param.length - 1], equals(')'));
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
+    if (returnType != null) {
+      expect(element.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(element.returnType, 'dynamic');
+    } else {
+      expect(element.returnType, isNull);
+    }
     assertHasParameterInfo(cs);
     return cs;
   }
 
   CompletionSuggestion assertSuggestFunctionTypeAlias(
-      String name, String returnType, bool isDeprecated,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
+      String name, String returnType,
+      {bool isDeprecated: false,
+      int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
+      String importUri}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
         importUri: importUri,
         isDeprecated: isDeprecated);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.FUNCTION_TYPE_ALIAS));
@@ -320,9 +362,9 @@
   }
 
   CompletionSuggestion assertSuggestSetter(String name,
-      [int relevance = DART_RELEVANCE_DEFAULT,
+      {int relevance: DART_RELEVANCE_DEFAULT,
       String importUri,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
@@ -348,13 +390,25 @@
       String importUri}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind, relevance: relevance, importUri: importUri);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    if (returnType != null) {
+      expect(cs.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(cs.returnType, 'dynamic');
+    } else {
+      expect(cs.returnType, isNull);
+    }
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.TOP_LEVEL_VARIABLE));
     expect(element.name, equals(name));
     expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    if (returnType != null) {
+      expect(element.returnType, returnType);
+    } else if (isNullExpectedReturnTypeConsideredDynamic) {
+      expect(element.returnType, 'dynamic');
+    } else {
+      expect(element.returnType, isNull);
+    }
     assertHasNoParameterInfo(cs);
     return cs;
   }
@@ -471,6 +525,12 @@
         Duration.ZERO, () => performAnalysis(times - 1, completer));
   }
 
+  void resolveSource(String path, String content) {
+    Source libSource = addSource(path, content);
+    var target = new LibrarySpecificUnit(libSource, libSource);
+    context.computeResult(target, RESOLVED_UNIT);
+  }
+
   @override
   void setUp() {
     super.setUp();
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
new file mode 100644
index 0000000..00d80df
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -0,0 +1,4375 @@
+// 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 test.services.completion.contributor.dart.imported_ref;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../abstract_context.dart';
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(ImportedReferenceContributorTest);
+}
+
+@reflectiveTest
+class ImportedReferenceContributorTest extends DartCompletionContributorTest {
+  @override
+  bool get isNullExpectedReturnTypeConsideredDynamic => false;
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new ImportedReferenceContributor();
+  }
+
+  fail_enum_deprecated() async {
+    addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
+    addTestSource('import "/libA.dart"; main() {^}');
+    await computeSuggestions();
+    // TODO(danrube) investigate why suggestion/element is not deprecated
+    // when AST node has correct @deprecated annotation
+    assertSuggestEnum('E', isDeprecated: true);
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_doc_class() async {
+    addSource(
+        '/libA.dart',
+        r'''
+library A;
+/// My class.
+/// Short description.
+///
+/// Longer description.
+class A {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestClass('A');
+    expect(suggestion.docSummary, 'My class.\nShort description.');
+    expect(suggestion.docComplete,
+        'My class.\nShort description.\n\nLonger description.');
+  }
+
+  test_doc_function() async {
+    resolveSource(
+        '/libA.dart',
+        r'''
+library A;
+/// My function.
+/// Short description.
+///
+/// Longer description.
+int myFunc() {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+    expect(suggestion.docSummary, 'My function.\nShort description.');
+    expect(suggestion.docComplete,
+        'My function.\nShort description.\n\nLonger description.');
+  }
+
+  test_doc_function_c_style() async {
+    resolveSource(
+        '/libA.dart',
+        r'''
+library A;
+/**
+ * My function.
+ * Short description.
+ *
+ * Longer description.
+ */
+int myFunc() {}
+''');
+    addTestSource('import "/libA.dart"; main() {^}');
+
+    await computeSuggestions();
+
+    CompletionSuggestion suggestion = assertSuggestFunction('myFunc', 'int');
+    expect(suggestion.docSummary, 'My function.\nShort description.');
+    expect(suggestion.docComplete,
+        'My function.\nShort description.\n\nLonger description.');
+  }
+  
+  test_enum() async {
+    addSource('/libA.dart', 'library A; enum E { one, two }');
+    addTestSource('import "/libA.dart"; main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+int m(x, {int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'int');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, [int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m({x, int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m() {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m([x, int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, int y) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_InstanceCreationExpression() async {
+    resolveSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion;
+
+    suggestion = assertSuggestConstructor('Object');
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('A');
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('B');
+    expect(suggestion.element.parameters, '(int x, [String boo])');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.parameterNames[1], 'boo');
+    expect(suggestion.parameterTypes[1], 'String');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('C.bar');
+    expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'boo');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'z');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('math');
+  }
+
+  test_internal_sdk_libs() async {
+    addTestSource('main() {p^}');
+
+    await computeSuggestions();
+    assertSuggest('print');
+    // Not imported, so not suggested
+    assertNotSuggested('pow');
+    // Do not suggest completions from internal SDK library
+    assertNotSuggested('printToConsole');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, {int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, [int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m({x, int y}) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m() {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m([x, int y]) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+void m(x, int y) {}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_mixin_ordering() async {
+    addSource(
+        '/libA.dart',
+        '''
+class B {}
+class M1 {
+  void m() {}
+}
+class M2 {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class C extends B with M1, M2 {
+  void f() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  /**
+   * Ensure that completions in one context don't appear in another
+   */
+  test_multiple_contexts() async {
+    // Create a 2nd context with source
+    var context2 = AnalysisEngine.instance.createAnalysisContext();
+    context2.sourceFactory =
+        new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
+    String content2 = 'class ClassFromAnotherContext { }';
+    Source source2 =
+        provider.newFile('/context2/foo.dart', content2).createSource();
+    ChangeSet changeSet = new ChangeSet();
+    changeSet.addedSource(source2);
+    context2.applyChanges(changeSet);
+    context2.setContents(source2, content2);
+
+    // Resolve the source in the 2nd context and update the index
+    var result = context2.performAnalysisTask();
+    while (result.hasMoreWork) {
+      result.changeNotices.forEach((ChangeNotice notice) {
+        CompilationUnit unit = notice.resolvedDartUnit;
+        if (unit != null) {
+          index.index(context2, unit);
+        }
+      });
+      result = context2.performAnalysisTask();
+    }
+
+    // Check that source in 2nd context does not appear in completion in 1st
+    addSource(
+        '/context1/libA.dart',
+        '''
+      library libA;
+      class ClassInLocalContext {int x;}''');
+    testFile = '/context1/completionTest.dart';
+    addTestSource('''
+      import "/context1/libA.dart";
+      import "/foo.dart";
+      main() {C^}
+      ''');
+
+    await computeSuggestions();
+    assertSuggestClass('ClassInLocalContext');
+    // Assert contributor does not include results from 2nd context.
+    assertNotSuggested('ClassFromAnotherContext');
+  }
+
+  test_no_parameters_field() async {
+    addSource(
+        '/libA.dart',
+        '''
+int x;
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestTopLevelVar('x', null);
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+int get x => null;
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    addSource(
+        '/libA.dart',
+        '''
+set x(int value) {};
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        expect(arg) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        typedef Funct();
+        class A { A(Funct f) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        expect(arg) { }
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    resolveSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B {
+          expect(arg) { }
+          void foo() {expect(^)}}
+        String bar() => true;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('B');
+    assertSuggestClass('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar(f()) => true;
+        void main() {bar(^);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { String bar(f()) => true; }
+        void main() {new B().bar(^);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('hasLength', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestFunction('identical', 'bool',
+        kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('B');
+    assertSuggestClass('A', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertSuggestClass('Object', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }''');
+    addTestSource('''
+        import '/libA.dart'
+        String bar() => true;
+        void main() {expect(foo: ^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    // An unresolved imported library will produce suggestions
+    // with a null returnType
+    assertSuggestFunction('hasLength', null);
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^ b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^
+          b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestFunction('identical', 'bool');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          int^ b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          i^
+          b = 1;}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertSuggestClass('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestFunction('identical', 'bool');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main() async {A a; await ^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AwaitExpression_function() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+Future y() async {return 0;}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  int x;
+  foo() async {await ^}
+}
+''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('y', 'dynamic');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_AwaitExpression_inherited() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A {
+  Future y() async { return 0; }
+}''');
+    addTestSource('''
+import "/testB.dart";
+class B extends A {
+  foo() async {await ^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('y');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            ^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A', elemFile: '/testAB.dart');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    assertNotSuggested('G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertSuggestFunction('min', 'num');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            final ^
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+
+    await computeSuggestions();
+    assertSuggestClass('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+
+    await computeSuggestions();
+    assertSuggestClass('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g hide G;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            final var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    // Hidden elements not suggested
+    assertNotSuggested('g.G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertSuggestClass('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertSuggestClass('D', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestFunction(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertSuggestClass('EE');
+    // hidden element suggested as low relevance
+    //assertSuggestClass('F', COMPLETION_RELEVANCE_LOW);
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    assertSuggestClass('Object');
+    assertNotSuggested('min');
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertSuggestClass('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    resolveSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class DF { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        class D3 { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} D^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertSuggestClass('A');
+    assertNotSuggested('_B');
+    // hidden element not suggested
+    assertNotSuggested('D');
+    assertSuggestFunction('D1', 'dynamic',
+        isDeprecated: true, relevance: DART_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    // Not imported, so not suggested
+    assertNotSuggested('D3');
+    //assertSuggestClass('EE');
+    // hidden element not suggested
+    assertNotSuggested('DF');
+    //assertSuggestLibraryPrefix('g');
+    assertSuggestClass('g.G', elemName: 'G');
+    //assertSuggestClass('H', COMPLETION_RELEVANCE_LOW);
+    //assertSuggestClass('Object');
+    //assertSuggestFunction('min', 'num', false);
+    //assertSuggestFunction(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends E implements I with M {a() {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2', null, null);
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }
+        class A extends E implements I with M {a() {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            p^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_partial_results() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} ^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    assertSuggestClass('C');
+    assertNotSuggested('H');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Not imported, so not suggested
+    assertNotSuggested('Foo');
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^z}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^ return}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a^..b}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        @deprecated class A {^}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    CompletionSuggestion suggestionO = assertSuggestClass('Object');
+    if (suggestionO != null) {
+      expect(suggestionO.element.isDeprecated, isFalse);
+      expect(suggestionO.element.isPrivate, isFalse);
+    }
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ A(){}}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as Soo;
+        class A {final S^ A();}
+        class _B {}
+        A Sew;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ final foo;}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ var foo;}
+        class _B {}
+        A T;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertSuggestClass('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" hide ^;
+        import "/testCD.dart";
+        class X {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        typedef PB2 F2(int blat);
+        class Clz = Object with Object;
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" show ^;
+        import "/testCD.dart";
+        class X {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? ^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(blat: ^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertSuggestClass('String');
+    assertSuggestFunction('identical', 'bool');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    resolveSource(
+        '/testA.dart',
+        '''
+        _B F1() { }
+        class A {int x;}
+        class _B { }''');
+    addTestSource('''
+        import "/testA.dart";
+        typedef int F2(int blat);
+        class Clz = Object with Object;
+        class C {foo(){^} void bar() {}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', '_B');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertSuggestClass('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertSuggestClass('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertSuggestClass('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertSuggestClass('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertSuggestClass('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertSuggestClass('Object');
+    assertSuggestClass('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+        void bar() { }
+        main() {for (int index = 0; index < 10; ++i^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /* */ ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /** */ ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        /// some dartdoc
+        class C2 { }
+        ^ zoo(z) { } String name;''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertSuggestClass('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestClass('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+        main() {var a; if (a.^) something}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+        import "dart^";
+        main() {}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[^]}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertSuggestClass('A');
+    assertSuggestFunction('F1', 'dynamic');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[T^]}}''');
+
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {A(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        import "dart:async";
+        int T2;
+        F2() { }
+        class B {B(this.x, [String boo]) { } int x;}
+        class C {foo(){var f; {var x;} new ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('Future');
+    assertSuggestConstructor('A');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Not imported, so not suggested
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \$^");}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \${^}");}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    // Simulate unresolved imported library
+    // in which case suggestions will have null (unresolved) returnType
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertSuggestFunctionTypeAlias('D1', 'null');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertSuggestClass('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var x; if (x is ^) { }}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {int x; int y() => 0;}
+        main(){var a; if (^ is A)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is ^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is Obj^)}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertSuggestClass('Object');
+  }
+
+  test_keyword() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int newT1;
+        int T1;
+        nowIsIt() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        String newer() {}
+        var m;
+        main() {new^ X.c();}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertSuggestFunction('nowIsIt', 'dynamic');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertSuggestTopLevelVar('newT1', 'int');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertSuggestClass('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertSuggestClass('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {^''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', null);
+    assertSuggestFunction('F1', null);
+    assertSuggestFunctionTypeAlias('D1', 'null');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {T^''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Simulate unresolved imported library,
+    // in which case suggestions will have null return types (unresolved)
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {7:T^};''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+        class C {
+          c1() {}
+          var c2;
+          static c3() {}
+          static var c4;}''');
+    addTestSource('''
+        import "/testC.dart";
+        class B extends C {
+          b1() {}
+          var b2;
+          static b3() {}
+          static var b4;}
+        class A extends B {
+          a1() {}
+          var a2;
+          static a3() {}
+          static var a4;
+          static a() {^}}''');
+
+    await computeSuggestions();
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertSuggestClass('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertSuggestClass('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {Z a(X x, [int y=1]) {^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertSuggestClass('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/* */ ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/** */ ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    resolveSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {
+          /// some dartdoc
+          ^ zoo(z) { } String name; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('F1');
+    assertSuggestFunctionTypeAlias('D1', 'dynamic');
+    assertSuggestClass('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {x.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+
+    await computeSuggestions();
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by ConstructorContributor
+    assertNotSuggested('B.bar');
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('X.c');
+    assertNotSuggested('X._d');
+    // Suggested by LocalLibraryContributor
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib libB;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    assertSuggestConstructor('Object');
+    assertSuggestConstructor('X.c');
+    assertNotSuggested('X._d');
+    // Suggested by LocalLibraryContributor
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          @deprecated var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        main() {A a; a.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+        main() {A a; a.^}
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+
+    await computeSuggestions();
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+
+    await computeSuggestions();
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertSuggestClass('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {this.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {this.^}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^) {}
+          A.z() {}
+          var b; X _c; static sb;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^b) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b, this.^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    resolveSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<^> c; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('Object');
+    assertSuggestClass('C1');
+    assertSuggestFunctionTypeAlias('T1', 'String');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<C^> c; }''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var ^}''');
+
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+
+    await computeSuggestions();
+    assertSuggestClass('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^}}''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    resolveSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo1() { }
+        void bar1() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo2() { }
+        void bar2() { }
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestFunction('foo1', 'dynamic');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
new file mode 100644
index 0000000..a864b34
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -0,0 +1,619 @@
+// 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 test.services.completion.contributor.dart.inherited_ref;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analysis_server/src/protocol_server.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(InheritedContributorTest);
+}
+
+@reflectiveTest
+class InheritedContributorTest extends DartCompletionContributorTest {
+  @override
+  bool get isNullExpectedReturnTypeConsideredDynamic => false;
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new InheritedReferenceContributor();
+  }
+
+  test_AwaitExpression_inherited() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A {
+  Future y() async {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class B extends A {
+  Future a() async {return 0;}
+  foo() async {await ^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('foo');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertSuggestMethod('y', 'A', 'dynamic');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    resolveSource(
+        '/testB.dart',
+        '''
+      lib B;
+      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }''');
+    addTestSource('''
+      import "/testB.dart";
+      class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+  }
+
+  test_inherited() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertSuggestField('x', 'int');
+    assertSuggestMethod('y', 'A2', 'int');
+    assertSuggestField('x1', 'int');
+    assertSuggestMethod('y1', 'A1', 'int');
+    assertSuggestField('x2', 'int');
+    assertSuggestMethod('y2', 'A2', 'int');
+  }
+
+  test_method_in_class() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, {int y}) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_named_local() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, [int y]) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_mixed_required_and_positional_local() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m({x, int y}) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_named_local() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_none_local() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m([x, int y]) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional_local() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  void m(x, int y) {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_mixin_ordering() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class B {}
+class M1 {
+  void m() {}
+}
+class M2 {
+  void m() {}
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class C extends B with M1, M2 {
+  void f() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'M1', 'void');
+  }
+
+  test_no_parameters_field() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  int x;
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestField('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  int get x => null;
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    resolveSource(
+        '/libA.dart',
+        '''
+class A {
+  set x(int value) {};
+}
+''');
+    addTestSource('''
+import '/libA.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_ouside_class() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+}
+foo() {^}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
+  test_static_field() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo = ^
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
+  test_static_method() async {
+    resolveSource(
+        '/testB.dart',
+        '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "/testB.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('foo');
+    assertNotSuggested('A');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 1d3549d..167e3ab 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -1114,27 +1114,6 @@
         relevance: DART_RELEVANCE_HIGH);
   }
 
-  test_inComment_block() async {
-    addTestSource('''
-main() {
-  /* text ^ */
-  print(42);
-}
-''');
-    await computeSuggestions();
-    expect(suggestions, isEmpty);
-  }
-
-  test_inComment_endOfLine() async {
-    addTestSource('''
-main() {
-  // text ^
-}
-''');
-    await computeSuggestions();
-    expect(suggestions, isEmpty);
-  }
-
   test_is_expression() async {
     addTestSource('main() {if (x is^)}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
new file mode 100644
index 0000000..850389c
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
@@ -0,0 +1,326 @@
+// 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 test.services.completion.contributor.dart.label;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LabelContributorTest);
+}
+
+@reflectiveTest
+class LabelContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLabel(String name,
+      {int relevance: DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.IDENTIFIER}) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    expect(cs.returnType, isNull);
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.flags, 0);
+    expect(element.kind, equals(protocol.ElementKind.LABEL));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, isNull);
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LabelContributor();
+  }
+
+  test_break_ignores_outer_functions_using_closure() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    var f = () {
+      bar: while (true) { break ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_break_ignores_outer_functions_using_local_function() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    void f() {
+      bar: while (true) { break ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_break_ignores_toplevel_variables() async {
+    addTestSource('''
+int x;
+void main() {
+  while (true) {
+    break ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+  }
+
+  test_break_ignores_unrelated_statements() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {}
+  while (true) { break ^ }
+  bar: while (true) {}
+}
+''');
+    await computeSuggestions();
+    // The scope of the label defined by a labeled statement is just the
+    // statement itself, so neither "foo" nor "bar" are in scope at the caret
+    // position.
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+  }
+
+  test_break_to_enclosing_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    bar: while (true) {
+      break ^
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+  }
+
+  test_continue_from_loop_to_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    bar: case 2:
+      while (true) {
+        continue ^;
+      }
+      break;
+    baz: case 3:
+      break;
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+    assertSuggestLabel('baz');
+  }
+
+  test_continue_from_switch_to_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    switch (x) {
+      case 1:
+        continue ^;
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_closure_with_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    var f = () {
+      bar: while (true) { continue ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_closure_with_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      var f = () {
+        bar: while (true) { continue ^ }
+      };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_local_function_with_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    void f() {
+      bar: while (true) { continue ^ }
+    };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_outer_functions_using_local_function_with_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      void f() {
+        bar: while (true) { continue ^ }
+      };
+  }
+}
+''');
+    await computeSuggestions();
+    // Labels in outer functions are never accessible.
+    assertSuggestLabel('bar');
+    assertNotSuggested('foo');
+  }
+
+  test_continue_ignores_unrelated_statements() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {}
+  while (true) { continue ^ }
+  bar: while (true) {}
+}
+''');
+    await computeSuggestions();
+    // The scope of the label defined by a labeled statement is just the
+    // statement itself, so neither "foo" nor "bar" are in scope at the caret
+    // position.
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+  }
+
+  test_continue_to_earlier_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    case 2:
+      continue ^;
+    case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_to_enclosing_loop() async {
+    addTestSource('''
+void main() {
+  foo: while (true) {
+    bar: while (true) {
+      continue ^
+    }
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+  }
+
+  test_continue_to_enclosing_switch() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    foo: case 1:
+      break;
+    bar: case 2:
+      switch (y) {
+        case 1:
+          continue ^;
+      }
+      break;
+    baz: case 3:
+      break;
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+    assertSuggestLabel('bar');
+    assertSuggestLabel('baz');
+  }
+
+  test_continue_to_later_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    case 1:
+      break;
+    case 2:
+      continue ^;
+    foo: case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+
+  test_continue_to_same_case() async {
+    addTestSource('''
+void main() {
+  switch (x) {
+    case 1:
+      break;
+    foo: case 2:
+      continue ^;
+    case 3:
+      break;
+''');
+    await computeSuggestions();
+    assertSuggestLabel('foo');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index ac38fa6..fd218a0 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -102,15 +102,24 @@
     await computeSuggestions();
     assertSuggestClass('Future');
     assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+    assertNotSuggested('foo');
   }
 
   test_libraryPrefix_with_exports() async {
     addSource('/libA.dart', 'library libA; class A { }');
-    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+    addSource(
+        '/libB.dart',
+        '''
+        library libB;
+        export "/libA.dart";
+        class B { }
+        @deprecated class B1 { }''');
     addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
     await computeSuggestions();
     assertSuggestClass('B');
+    assertSuggestClass('B1', relevance: DART_RELEVANCE_LOW, isDeprecated: true);
     assertSuggestClass('A');
+    assertNotSuggested('C');
   }
 
   test_PrefixedIdentifier_library() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
new file mode 100644
index 0000000..64773f4
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -0,0 +1,4074 @@
+// 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 test.services.completion.contributor.dart.constructor;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalConstructorContributorTest);
+}
+
+@reflectiveTest
+class LocalConstructorContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLocalVariable(
+      String name, String returnType,
+      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
+    // Local variables should only be suggested by LocalReferenceContributor
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestParameter(String name, String returnType,
+      {int relevance: DART_RELEVANCE_PARAMETER}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalConstructorContributor();
+  }
+
+  test_constructor_parameters_mixed_required_and_named() async {
+    addTestSource('class A {A(x, {int y}) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_mixed_required_and_positional() async {
+    addTestSource('class A {A(x, [int y]) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_named() async {
+    addTestSource('class A {A({x, int y}) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_positional() async {
+    addTestSource('class A {A([x, int y]) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_constructor_parameters_required() async {
+    addTestSource('class A {A(x, int y) {^}}');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+  }
+
+  test_enum() async {
+    addTestSource('enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_enum_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    addTestSource('''
+void m(x, {int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+void m(x, [int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_named() async {
+    addTestSource('''
+void m({x, int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_none() async {
+    addTestSource('''
+void m() {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_positional() async {
+    addTestSource('''
+void m([x, int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_function_parameters_required() async {
+    addTestSource('''
+void m(x, int y) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_ignore_symbol_being_completed() async {
+    addTestSource('class MyClass { } main(MC^) { }');
+    await computeSuggestions();
+    assertNotSuggested('MyClass');
+    assertNotSuggested('MC');
+  }
+
+  test_inDartDoc_reference1() async {
+    addTestSource('''
+/// The [^
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference2() async {
+    addTestSource('''
+/// The [m^
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference3() async {
+    addTestSource('''
+/// The [^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_inDartDoc_reference4() async {
+    addTestSource('''
+/// The [m^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertNotSuggested('main');
+  }
+
+  test_InstanceCreationExpression() async {
+    addTestSource('''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion;
+
+    suggestion = assertSuggestConstructor('A', elemOffset: -1);
+    expect(suggestion.element.parameters, '()');
+    expect(suggestion.element.returnType, 'A');
+    expect(suggestion.declaringType, 'A');
+    expect(suggestion.parameterNames, hasLength(0));
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('B');
+    expect(suggestion.element.parameters, '(int x, [String boo])');
+    expect(suggestion.element.returnType, 'B');
+    expect(suggestion.declaringType, 'B');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.parameterNames[1], 'boo');
+    expect(suggestion.parameterTypes[1], 'String');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+
+    suggestion = assertSuggestConstructor('C.bar');
+    expect(suggestion.element.parameters, '({dynamic boo: \'hoo\', int z: 0})');
+    expect(suggestion.element.returnType, 'C');
+    expect(suggestion.declaringType, 'C');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'boo');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'z');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_missing_params_constructor() async {
+    addTestSource('class C1{C1{} main(){C^}}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_function() async {
+    addTestSource('int f1{} main(){f^}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_method() async {
+    addTestSource('class C1{int f1{} main(){f^}}');
+    await computeSuggestions();
+  }
+
+  test_overrides() async {
+    addTestSource('''
+class A {m() {}}
+class B extends A {m() {^}}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_prioritization() async {
+    addTestSource('main() {var ab; var _ab; ^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_prioritization_private() async {
+    addTestSource('main() {var ab; var _ab; _^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_prioritization_public() async {
+    addTestSource('main() {var ab; var _ab; a^}');
+    await computeSuggestions();
+    assertNotSuggested('ab');
+    assertNotSuggested('_ab');
+  }
+
+  test_shadowed_name() async {
+    addTestSource('var a; class A { var a; m() { ^ } }');
+    await computeSuggestions();
+    assertNotSuggested('a');
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+expect(arg) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+typedef Funct();
+class A { A(Funct f) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+expect(arg) { }
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B {
+  expect(arg) { }
+  void foo() {expect(^)}}
+String bar() => true;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar(f()) => true;
+void main() {bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { String bar(f()) => true; }
+void main() {new B().bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }''');
+    addTestSource('''
+import '/libA.dart'
+String bar() => true;
+void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  int^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  i^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main() async {A a; await ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    final ^
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+class D3 { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+Z D2() {int x;}
+class X {a() {var f; {var x;} D^ var r;} void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertNotSuggested('D2');
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertSuggestLibraryPrefix('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertSuggestTopLevelVar('_T6', null);
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }''');
+    addTestSource('''
+import "/testB.dart";
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    p^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+// looks like a cascade to the parser
+// but the user is trying to get completions for a non-cascade
+main() {A a; a.^.z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^ return}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+class A {var b; X _c;}
+class X{}
+main() {A a; a^..b}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" hide ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+typedef PB2 F2(int blat);
+class Clz = Object with Object;
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" show ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+_B F1() { }
+class A {int x;}
+class _B { }''');
+    addTestSource('''
+import "/testA.dart";
+typedef int F2(int blat);
+class Clz = Object with Object;
+class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+void bar() { }
+main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+/// some dartdoc
+class C2 { }
+^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+import "dart^";
+main() {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {A(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:async";
+int T2;
+F2() { }
+class B {B(this.x, [String boo]) { } int x;}
+class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    assertSuggestConstructor('B');
+    assertSuggestConstructor('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {int x; int y() => 0;}
+main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword() async {
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int newT1;
+int T1;
+nowIsIt() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+String newer() {}
+var m;
+main() {new^ X.c();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('newT1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {T^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {7:T^};''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+class C {
+  c1() {}
+  var c2;
+  static c3() {}
+  static var c4;}''');
+    addTestSource('''
+import "/testC.dart";
+class B extends C {
+  b1() {}
+  var b2;
+  static b3() {}
+  static var b4;}
+class A extends B {
+  a1() {}
+  var a2;
+  static a3() {}
+  static var a4;
+  static a() {^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {
+  /// some dartdoc
+  ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {x.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+library libA;
+import "/testB.dart";
+part "$testFile";
+class A { }
+var m;''');
+    addTestSource('''
+part of libA;
+class B { factory B.bar(int x) => null; }
+main() {new ^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+part of libA;
+class B { }''');
+    addTestSource('''
+library libA;
+import "/testB.dart";
+part "/testA.dart";
+class A { A({String boo: 'hoo'}) { } }
+main() {new ^}
+var m;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {
+  static const scI = 'boo';
+  X get f => new A();
+  get _g => new A();}
+class B implements I {
+  static const int scB = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+class A extends B {
+  static const String scA = 'foo';
+  w() { }}
+main() {A.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  @deprecated var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+main() {A a; a.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+main() {A a; a.^}
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+main() {b.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^ f) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class _W {M y; var _z;}
+class X extends _W {}
+class M{}''');
+    addTestSource('''
+import "/testB.dart";
+foo(X x) {x.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class A {static int bar = 10;}
+_B() {}''');
+    addTestSource('''
+import "/testA.dart";
+class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {this.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {this.^}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^) {}
+  A.z() {}
+  var b; X _c; static sb;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^b) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b, this.^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<C^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+
+    assertNotSuggested('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo1() { }
+void bar1() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+foo2() { }
+void bar2() { }
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
similarity index 95%
rename from pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart
rename to pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
index e1ab7da..f70f720f 100644
--- a/pkg/analysis_server/test/services/completion/local_declaration_visitor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
@@ -4,7 +4,7 @@
 
 library test.services.completion.local_declaration_visitor_test;
 
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
+import 'package:analysis_server/src/services/completion/dart/local_declaration_visitor.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart';
@@ -12,7 +12,7 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
-import '../../utils.dart';
+import '../../../utils.dart';
 
 main() {
   initializeTestEnvironment();
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
new file mode 100644
index 0000000..fc707f9
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -0,0 +1,201 @@
+// 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 test.services.completion.contributor.dart.local_lib;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalLibraryContributorTest);
+}
+
+@reflectiveTest
+class LocalLibraryContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalLibraryContributor();
+  }
+
+  test_partFile_Constructor() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('A');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertSuggestTopLevelVar('m', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_partFile_TypeName() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { var a1; a2(){}}
+        var m;
+        typedef t1(int blue);
+        int af() {return 0;}''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {^}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestFunction('af', 'int',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('m', null,
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunctionTypeAlias('t1', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+  }
+
+  test_partFile_Constructor2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestConstructor('B');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { var b1; b2(){}}
+        int bf() => 0;
+        typedef t1(int blue);
+        var n;''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {^}
+        var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('B');
+    assertSuggestFunction('bf', 'int',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('n', null,
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunctionTypeAlias('t1', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    // Suggested by ConstructorContributor
+    assertNotSuggested('A');
+    // Suggested by ImportedReferenceContributor
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
new file mode 100644
index 0000000..e5d854d
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -0,0 +1,4279 @@
+// 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 test.services.completion.contributor.dart.local_ref;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
+    show Element, ElementKind;
+import 'package:analysis_server/plugin/protocol/protocol.dart'
+    hide Element, ElementKind;
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LocalReferenceContributorTest);
+}
+
+@reflectiveTest
+class LocalReferenceContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestLocalVariable(
+      String name, String returnType,
+      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
+    // Local variables should only be suggested by LocalReferenceContributor
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType, returnType != null ? returnType : 'dynamic');
+    assertHasNoParameterInfo(cs);
+    return cs;
+  }
+
+  CompletionSuggestion assertSuggestParameter(String name, String returnType,
+      {int relevance: DART_RELEVANCE_PARAMETER}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
+    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
+    protocol.Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
+    expect(element.name, equals(name));
+    expect(element.parameters, isNull);
+    expect(element.returnType,
+        equals(returnType != null ? returnType : 'dynamic'));
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LocalReferenceContributor();
+  }
+
+  test_constructor_parameters_mixed_required_and_named() async {
+    addTestSource('class A {A(x, {int y}) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_mixed_required_and_positional() async {
+    addTestSource('class A {A(x, [int y]) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_named() async {
+    addTestSource('class A {A({x, int y}) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_positional() async {
+    addTestSource('class A {A([x, int y]) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_constructor_parameters_required() async {
+    addTestSource('class A {A(x, int y) {^}}');
+    await computeSuggestions();
+    assertSuggestParameter('x', null);
+    assertSuggestParameter('y', 'int');
+  }
+
+  test_enum() async {
+    addTestSource('enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_enum_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {^}');
+    await computeSuggestions();
+    assertSuggestEnum('E', isDeprecated: true);
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+  }
+
+  test_function_parameters_mixed_required_and_named() async {
+    addTestSource('''
+void m(x, {int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+void m(x, [int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_named() async {
+    addTestSource('''
+void m({x, int y}) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_function_parameters_none() async {
+    addTestSource('''
+void m() {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_positional() async {
+    addTestSource('''
+void m([x, int y]) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_function_parameters_required() async {
+    addTestSource('''
+void m(x, int y) {}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestFunction('m', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_ignore_symbol_being_completed() async {
+    addTestSource('class MyClass { } main(MC^) { }');
+    await computeSuggestions();
+    assertSuggestClass('MyClass');
+    assertNotSuggested('MC');
+  }
+
+  test_inDartDoc_reference3() async {
+    addTestSource('''
+/// The [^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertSuggestFunction('main', null,
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_inDartDoc_reference4() async {
+    addTestSource('''
+/// The [m^]
+main(aaa, bbb) {}''');
+    await computeSuggestions();
+    assertSuggestFunction('main', null,
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_InstanceCreationExpression() async {
+    addTestSource('''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    // Suggested by LocalConstructorContributor
+    assertNoSuggestions();
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class A {
+  void m(x, {int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class A {
+  void m(x, [int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class A {
+  void m({x, int y}) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class A {
+  void m() {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class A {
+  void m([x, int y]) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+}
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertNotSuggested('m');
+  }
+
+  test_missing_params_constructor() async {
+    addTestSource('class C1{C1{} main(){C^}}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_function() async {
+    addTestSource('int f1{} main(){f^}');
+    await computeSuggestions();
+  }
+
+  test_missing_params_method() async {
+    addTestSource('class C1{int f1{} main(){f^}}');
+    await computeSuggestions();
+  }
+
+  test_overrides() async {
+    addTestSource('''
+class A {m() {}}
+class B extends A {m() {^}}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+  }
+
+  test_prioritization() async {
+    addTestSource('main() {var ab; var _ab; ^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+  }
+
+  test_prioritization_private() async {
+    addTestSource('main() {var ab; var _ab; _^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null);
+  }
+
+  test_prioritization_public() async {
+    addTestSource('main() {var ab; var _ab; a^}');
+    await computeSuggestions();
+    assertSuggestLocalVariable('ab', null);
+    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
+  }
+
+  test_shadowed_name() async {
+    addTestSource('var a; class A { var a; m() { ^ } }');
+    await computeSuggestions();
+    assertSuggestField('a', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+expect(arg) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+typedef Funct();
+class A { A(Funct f) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar() => true;
+void main() {new A(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+expect(arg) { }
+class B { }
+String bar() => true;
+void main() {expect(^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import '/libA.dart'
+class B {
+  expect(arg) { }
+  void foo() {expect(^)}}
+String bar() => true;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { }
+String bar(f()) => true;
+void main() {bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertSuggestFunction('bar', 'String',
+        kind: CompletionSuggestionKind.IDENTIFIER,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+class A { A(f()) { } }
+bool hasLength(int expected) { }
+void baz() { }''');
+    addTestSource('''
+import 'dart:async';
+import '/libA.dart';
+class B { String bar(f()) => true; }
+void main() {new B().bar(^);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertSuggestClass('B', kind: CompletionSuggestionKind.IDENTIFIER);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+library A;
+bool hasLength(int expected) { }''');
+    addTestSource('''
+import '/libA.dart'
+String bar() => true;
+void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('bar', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  ^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  int^ b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+class A {} main() {
+  int a;
+  i^
+  b = 1;
+}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertSuggestLocalVariable('a', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main() async {A a; await ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'A');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AwaitExpression2() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {
+          int x;
+          Future y() async {return 0;}
+          foo() async {await ^ await y();}
+        }
+        ''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestMethod('y', 'A', 'Future',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'int');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X', elemFile: testFile);
+    assertSuggestClass('Z');
+    assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('b', 'X', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestFunction('localF', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestLocalVariable('f', null);
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertSuggestTopLevelVar('T5', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestTopLevelVar('_T6', null, relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('==');
+    assertSuggestGetter('T7', 'String',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestSetter('T8', relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestGetter('clog', 'int',
+        relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    assertSuggestSetter('blog', relevance: DART_RELEVANCE_LOCAL_ACCESSOR);
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    final ^
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+class D3 { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+Z D2() {int x;}
+class X {a() {var f; {var x;} D^ var r;} void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertSuggestClass('X');
+    assertSuggestClass('Z');
+    assertSuggestMethod('a', 'X', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('b', 'X', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestLocalVariable('f', null);
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertSuggestFunction('D2', 'Z', relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertSuggestLibraryPrefix('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertNotSuggested('T3');
+    assertNotSuggested('_T4');
+    //assertSuggestTopLevelVar('T5', 'int', relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    //assertSuggestTopLevelVar('_T6', null);
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    resolveSource(
+        '/testB.dart',
+        '''
+lib B;
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }''');
+    addTestSource('''
+import "/testB.dart";
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    p^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+// looks like a cascade to the parser
+// but the user is trying to get completions for a non-cascade
+main() {A a; a.^.z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^z}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "/testB.dart";
+class A {var b; X _c;}
+class X{}
+main() {A a; a..^ return}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+class A {var b; X _c;}
+class X{}
+main() {A a; a^..b}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertSuggestLocalVariable('a', 'A');
+    assertSuggestClass('A');
+    assertSuggestClass('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A', elemOffset: 6);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('e', 'E');
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('e', null);
+    assertSuggestParameter('s', 'StackTrace');
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion suggestionA = assertSuggestClass('A',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (suggestionA != null) {
+      expect(suggestionA.element.isDeprecated, isTrue);
+      expect(suggestionA.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion suggestionB = assertSuggestClass('_B');
+    if (suggestionB != null) {
+      expect(suggestionB.element.isDeprecated, isFalse);
+      expect(suggestionB.element.isPrivate, isTrue);
+    }
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('A');
+    assertSuggestClass('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    // Suggested by LibraryPrefixContributor
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" hide ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+library libAB;
+part '/partAB.dart';
+class A { }
+class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+part of libAB;
+var T1;
+PB F1() => new PB();
+typedef PB2 F2(int blat);
+class Clz = Object with Object;
+class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+class C { }
+class D { }''');
+    addTestSource('''
+import "/testAB.dart" show ^;
+import "/testCD.dart";
+class X {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+var m;
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+int T1;
+F1() { }
+class X {factory X.c(); factory X._d(); z() {}}
+main() {new X.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestMethod('a', 'A', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+_B F1() { }
+class A {int x;}
+class _B { }''');
+    addTestSource('''
+import "/testA.dart";
+typedef int F2(int blat);
+class Clz = Object with Object;
+class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertSuggestClass('C');
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestMethod('bar', 'C', 'void',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestFunctionTypeAlias('F2', 'int');
+    assertSuggestClassTypeAlias('Clz');
+    assertSuggestClass('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertSuggestLocalVariable('foo', 'int');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertSuggestLocalVariable('foo', null);
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestParameter('args', null);
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {a(^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertSuggestClass('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForEachStatement() async {
+    // SimpleIdentifier  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in ^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForEachStatement2() async {
+    // SimpleIdentifier  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForEachStatement3() async {
+    // SimpleIdentifier ParenthesizedExpression  ForEachStatement
+    addTestSource('main() {List<int> values; for (int index in (i^))}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('values', 'List');
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('i', 'int');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', 'List');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+void bar() { }
+main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLocalVariable('index', 'int');
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+/** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+/// some dartdoc
+class C2 { }
+^ zoo(z) { } String name;''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^});}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    var f = assertSuggestFunction('foo', 'String',
+        isDeprecated: false, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    if (f != null) {
+      expect(f.element.isPrivate, isFalse);
+    }
+    assertSuggestFunction('bar', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestParameter('args', 'List');
+    assertSuggestParameter('b', 'R');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', null);
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_DEFAULT);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_empty_private() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (_^) something}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertSuggestField('_c', 'X', relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('Object');
+    assertSuggestClass('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('toString');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+import "dart^";
+main() {}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('x');
+    assertSuggestLocalVariable('f', null);
+    assertSuggestMethod('foo', 'C', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestClass('C');
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+class B {int x;}
+class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+
+    // top level results are partially filtered based on first char
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertNotSuggested('T1');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+class A {A(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+import "dart:async";
+int T2;
+F2() { }
+class B {B(this.x, [String boo]) { } int x;}
+class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertSuggestLocalVariable('name', 'String');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertSuggestLocalVariable('name', 'String');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('name', 'String');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('length');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('name', 'String');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {int x; int y() => 0;}
+main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLocalVariable('a', null);
+    assertSuggestFunction('main', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+class A {int x; int y() => 0;}
+main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertSuggestClass('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword() async {
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int newT1;
+int T1;
+nowIsIt() { }
+class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+String newer() {}
+var m;
+main() {new^ X.c();}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('newT1');
+    assertNotSuggested('z');
+    assertSuggestTopLevelVar('m', 'dynamic',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('newer', 'String',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('Some', null);
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+
+    assertSuggestLocalVariable('Some', null);
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {T^''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 { }
+foo = {7:T^};''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T1');
+    assertSuggestTopLevelVar('T2', 'int',
+        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion getterF = assertSuggestGetter('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+    }
+    CompletionSuggestion getterG =
+        assertSuggestGetter('_g', null, relevance: DART_RELEVANCE_DEFAULT);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+    }
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+class C {
+  c1() {}
+  var c2;
+  static c3() {}
+  static var c4;}''');
+    addTestSource('''
+import "/testC.dart";
+class B extends C {
+  b1() {}
+  var b2;
+  static b3() {}
+  static var b4;}
+class A extends B {
+  a1() {}
+  var a2;
+  static a3() {}
+  static var a4;
+  static a() {^}}''');
+    await computeSuggestions();
+
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertSuggestMethod('a3', 'A', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestField('a4', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA =
+        assertSuggestMethod('_a', 'A', 'Z', relevance: DART_RELEVANCE_DEFAULT);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isTrue);
+    }
+    CompletionSuggestion getterF = assertSuggestField('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+      expect(getterF.element.parameters, isNull);
+    }
+    // If user did not type '_' then relevance of private members is not raised
+    CompletionSuggestion getterG =
+        assertSuggestField('_g', null, relevance: DART_RELEVANCE_DEFAULT);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+      expect(getterF.element.parameters, isNull);
+    }
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_members_private() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {_^} var _g;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    CompletionSuggestion methodA = assertSuggestMethod('_a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isFalse);
+      expect(methodA.element.isPrivate, isTrue);
+    }
+    CompletionSuggestion getterF = assertSuggestField('f', 'X',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (getterF != null) {
+      expect(getterF.element.isDeprecated, isTrue);
+      expect(getterF.element.isPrivate, isFalse);
+      expect(getterF.element.parameters, isNull);
+    }
+    // If user prefixed completion with '_' then suggestion of private members
+    // should be the same as public members
+    CompletionSuggestion getterG =
+        assertSuggestField('_g', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
+    if (getterG != null) {
+      expect(getterG.element.isDeprecated, isFalse);
+      expect(getterG.element.isPrivate, isTrue);
+      expect(getterF.element.parameters, isNull);
+    }
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    CompletionSuggestion methodA = assertSuggestMethod('a', 'A', 'Z',
+        relevance: DART_RELEVANCE_LOW, isDeprecated: true);
+    if (methodA != null) {
+      expect(methodA.element.isDeprecated, isTrue);
+      expect(methodA.element.isPrivate, isFalse);
+    }
+    assertSuggestParameter('x', 'X');
+    assertSuggestParameter('y', null);
+    assertSuggestParameter('b', null);
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+foo() { }
+void bar() { }
+class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestFunction('foo', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestFunction('bar', 'void',
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertSuggestMethod('a', 'A', 'Z', relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestParameter('x', 'X');
+    assertSuggestParameter('y', 'int');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+int T1;
+F1() { }
+typedef D1();
+class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+import "/testA.dart";
+int T2;
+F2() { }
+typedef D2();
+class C2 {
+  /// some dartdoc
+  ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestClass('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {x.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+
+    assertNotSuggested('nextBool');
+    assertNotSuggested('nextDouble');
+    assertNotSuggested('nextInt');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+library libA;
+import "/testB.dart";
+part "$testFile";
+class A { }
+var m;''');
+    addTestSource('''
+part of libA;
+class B { factory B.bar(int x) => null; }
+main() {new ^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+int T1;
+F1() { }
+class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+part of libA;
+class B { }''');
+    addTestSource('''
+library libA;
+import "/testB.dart";
+part "/testA.dart";
+class A { A({String boo: 'hoo'}) { } }
+main() {new ^}
+var m;''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LocalConstructorContributor
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {
+  static const scI = 'boo';
+  X get f => new A();
+  get _g => new A();}
+class B implements I {
+  static const int scB = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+class A extends B {
+  static const String scA = 'foo';
+  w() { }}
+main() {A.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  @deprecated var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    addTestSource('''
+import "/testB.dart";
+main() {A a; a.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+main() {A a; a.^}
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  static const int sc = 12;
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  set s1(I x) {} set _s2(I x) {}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+main() {b.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^ f) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+var T1;
+class X { }
+class Y { }''');
+    addTestSource('''
+import "/testB.dart" as b;
+var T2;
+class A { }
+foo(b.^) {}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+class _W {M y; var _z;}
+class X extends _W {}
+class M{}''');
+    addTestSource('''
+import "/testB.dart";
+foo(X x) {x.^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('y');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class A {static int bar = 10;}
+_B() {}''');
+    addTestSource('''
+import "/testA.dart";
+class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertSuggestClass('X');
+    assertSuggestMethod('foo', 'X', null,
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('compareTo');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+
+    assertNotSuggested('length');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertNotSuggested('length');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('isEven');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+
+    assertSuggestClass('A');
+    assertSuggestMethod('g', 'A', 'String',
+        relevance: DART_RELEVANCE_LOCAL_METHOD);
+    assertSuggestLocalVariable('t', null);
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {this.^ m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A() {this.^}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^) {}
+  A.z() {}
+  var b; X _c; static sb;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.^b) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+main() { }
+class I {X get f => new A();get _g => new A();}
+class A implements I {
+  A(this.b, this.^) {}
+  A.z() {}
+  var b; X _c;
+  X get d => new A();get _e => new A();
+  // no semicolon between completion point and next statement
+  set s1(I x) {} set _s2(I x) {m(null);}
+  m(X x) {} I _n(X x) {}}
+class X{}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertSuggestClass('C2');
+    assertSuggestFunctionTypeAlias('T2', 'int');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+class C1 {int x;}
+F1() => 0;
+typedef String T1(int blat);''');
+    addTestSource('''
+import "/testA.dart";'
+class C2 {int x;}
+F2() => 0;
+typedef int T2(int blat);
+class C<E> {}
+main() { C<C^> c; }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertSuggestClass('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+main() {var ^}''');
+    await computeSuggestions();
+
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+
+    assertNotSuggested('Object');
+    assertSuggestClass('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertSuggestClass('Y');
+    assertSuggestClass('C');
+    assertSuggestLocalVariable('f', null);
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+lib B;
+foo1() { }
+void bar1() { }
+class _B { }
+class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+import "/testB.dart";
+foo2() { }
+void bar2() { }
+class Y {Y.c(); Y._d(); z() {}}
+class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertSuggestFunction('foo2', null,
+        relevance: DART_RELEVANCE_LOCAL_FUNCTION);
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertSuggestClass('Y');
+    assertSuggestClass('C');
+    assertSuggestLocalVariable('f', null);
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
similarity index 89%
rename from pkg/analysis_server/test/services/completion/dart/inherited_contributor_test.dart
rename to pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index 4ef42d3..e219259 100644
--- a/pkg/analysis_server/test/services/completion/dart/inherited_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -2,14 +2,12 @@
 // 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 test.services.completion.dart.inherited_computer_test;
+library test.services.completion.dart.override;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/inherited_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart'
-    hide DartCompletionContributor;
+import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -23,10 +21,10 @@
 }
 
 @reflectiveTest
-class InheritedContributorTest extends DartCompletionContributorTest {
+class OverrideContributorTest extends DartCompletionContributorTest {
   @override
   DartCompletionContributor createContributor() {
-    return new InheritedContributor();
+    return new OverrideContributor();
   }
 
   test_fromMultipleSuperclasses() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index a9dc275..482780f 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -11,11 +11,18 @@
 import 'combinator_contributor_test.dart' as combinator_test;
 import 'common_usage_sorter_test.dart' as common_usage_test;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
-import 'inherited_contributor_test.dart' as inherited_contributor_test;
+import 'imported_reference_contributor_test.dart' as imported_ref_test;
+import 'inherited_reference_contributor_test.dart' as inherited_ref_test;
 import 'keyword_contributor_test.dart' as keyword_test;
+import 'label_contributor_test.dart' as label_contributor_test;
 import 'library_member_contributor_test.dart' as library_member_test;
 import 'library_prefix_contributor_test.dart' as library_prefix_test;
+import 'local_constructor_contributor_test.dart' as local_constructor_test;
+import 'local_declaration_visitor_test.dart' as local_decl_visitor_test;
+import 'local_library_contributor_test.dart' as local_lib_test;
+import 'local_reference_contributor_test.dart' as local_ref_test;
 import 'named_constructor_contributor_test.dart' as named_contributor_test;
+import 'override_contributor_test.dart' as override_contributor_test;
 import 'static_member_contributor_test.dart' as static_contributor_test;
 import 'type_member_contributor_test.dart' as type_member_contributor_test;
 import 'uri_contributor_test.dart' as uri_contributor_test;
@@ -28,11 +35,18 @@
     combinator_test.main();
     common_usage_test.main();
     field_formal_contributor_test.main();
-    inherited_contributor_test.main();
+    imported_ref_test.main();
+    inherited_ref_test.main();
     keyword_test.main();
+    label_contributor_test.main();
     library_member_test.main();
     library_prefix_test.main();
+    local_constructor_test.main();
+    local_decl_visitor_test.main();
+    local_lib_test.main();
+    local_ref_test.main();
     named_contributor_test.main();
+    override_contributor_test.main();
     static_contributor_test.main();
     type_member_contributor_test.main();
     uri_contributor_test.main();
diff --git a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
deleted file mode 100644
index fb91d76..0000000
--- a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
+++ /dev/null
@@ -1,860 +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.
-
-library test.services.completion.toplevel;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../abstract_context.dart';
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(ImportedReferenceContributorTest);
-}
-
-@reflectiveTest
-class ImportedReferenceContributorTest extends AbstractSelectorSuggestionTest {
-  void assertCached(String completion) {
-    DartCompletionCache cache = request.cache;
-    if (!isCached(cache.importedTypeSuggestions, completion) &&
-        !isCached(cache.importedVoidReturnSuggestions, completion) &&
-        !isCached(cache.otherImportedSuggestions, completion)) {
-      fail('expected $completion to be cached');
-    }
-  }
-
-  /**
-   * Assert that the ImportedReferenceContributor uses cached results
-   * to produce identical suggestions to the original set of suggestions.
-   */
-  @override
-  assertCachedCompute(_) {
-    if (!(contributor as ImportedReferenceContributor)
-        .shouldWaitForLowPrioritySuggestions) {
-      return null;
-    }
-    List<CompletionSuggestion> oldSuggestions = request.suggestions;
-    /*
-     * Simulate a source change to flush the cached compilation unit
-     */
-    ChangeSet changes = new ChangeSet();
-    changes.addedSource(testSource);
-    context.applyChanges(changes);
-    /*
-     * Calculate a new completion at the same location
-     */
-    setUpContributor();
-    int replacementOffset = request.replacementOffset;
-    int replacementLength = request.replacementLength;
-    /*
-     * Pass null for searchEngine to ensure that it is not used
-     * when the cache has been populated.
-     */
-    request = new DartCompletionRequest(
-        context, provider, searchEngine, testSource, completionOffset, cache);
-    request.replacementOffset = replacementOffset;
-    request.replacementLength = replacementLength;
-
-    void assertResultsFromCache(List<CompletionSuggestion> oldSuggestions) {
-      List<CompletionSuggestion> newSuggestions = request.suggestions;
-      if (newSuggestions.length == oldSuggestions.length) {
-        if (!oldSuggestions
-            .any((CompletionSuggestion s) => !newSuggestions.contains(s))) {
-          return;
-        }
-      }
-      StringBuffer sb = new StringBuffer(
-          'suggestions based upon cached results do not match expectations');
-      sb.write('\n  Expected:');
-      oldSuggestions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-      sb.write('\n  Actual:');
-      newSuggestions.toList()
-        ..sort(suggestionComparator)
-        ..forEach((CompletionSuggestion suggestion) {
-          sb.write('\n    ${suggestion.completion} -> $suggestion');
-        });
-      fail(sb.toString());
-    }
-
-    computeFastResult = null;
-    if (computeFast()) {
-      expect(request.unit.element, isNull);
-      assertResultsFromCache(oldSuggestions);
-    } else {
-      // Results from cache might need to be adjusted
-      // if target is a function argument in an argument list
-      resolve(false);
-      return contributor.computeFull(request).then((bool result) {
-        expect(result, isTrue);
-        expect(request.unit.element, isNotNull);
-        assertResultsFromCache(oldSuggestions);
-      });
-    }
-  }
-
-  void assertNotCached(String completion) {
-    DartCompletionCache cache = request.cache;
-    if (isCached(cache.importedTypeSuggestions, completion) ||
-        isCached(cache.importedVoidReturnSuggestions, completion) ||
-        isCached(cache.otherImportedSuggestions, completion)) {
-      fail('expected $completion NOT to be cached');
-    }
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri,
-      String elemFile}) {
-    return assertSuggestClass(name,
-        relevance: relevance,
-        kind: kind,
-        importUri: importUri,
-        elemFile: elemFile);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
-    return assertSuggestConstructor(name,
-        relevance: relevance, importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedField(String name, String type,
-      {int relevance: DART_RELEVANCE_INHERITED_FIELD, String importUri}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      String importUri}) {
-    return assertSuggestFunction(name, returnType,
-        kind: kind,
-        deprecated: deprecated,
-        relevance: relevance,
-        importUri: importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedFunctionTypeAlias(
-      String name, String returnType,
-      [bool isDeprecated = false,
-      int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertSuggestFunctionTypeAlias(
-        name, returnType, isDeprecated, relevance, kind, importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedGetter(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) {
-    return assertSuggestGetter(name, returnType,
-        relevance: relevance, importUri: importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_INHERITED_METHOD, String importUri}) {
-    return assertSuggestMethod(name, declaringType, returnType,
-        relevance: relevance, importUri: importUri);
-  }
-
-  CompletionSuggestion assertSuggestImportedSetter(String name,
-      {int relevance: DART_RELEVANCE_INHERITED_ACCESSOR, String importUri}) {
-    return assertSuggestSetter(name, relevance, importUri);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestImportedTopLevelVar(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION,
-      String importUri]) {
-    return assertSuggestTopLevelVar(
-        name, returnType, relevance, kind, importUri);
-  }
-
-  fail_enum_deprecated() {
-    addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
-    addTestSource('import "/libA.dart"; main() {^}');
-    return computeFull((bool result) {
-      // TODO(danrube) investigate why suggestion/element is not deprecated
-      // when AST node has correct @deprecated annotation
-      assertSuggestEnum('E', isDeprecated: true);
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-    });
-  }
-
-  bool isCached(List<CompletionSuggestion> suggestions, String completion) =>
-      suggestions.any((CompletionSuggestion s) => s.completion == completion);
-
-  @override
-  void setUpContributor() {
-    contributor = new ImportedReferenceContributor(
-        shouldWaitForLowPrioritySuggestions: true);
-  }
-
-  @override
-  test_ArgumentList() {
-    return super.test_ArgumentList().then((_) {
-      expect(request.cache.importKey, "import '/libA.dart';");
-      ClassElement objClassElem1 = request.cache.importedClassMap['Object'];
-      expect(objClassElem1, isNotNull);
-      ClassElement objClassElem2 = request.cache.objectClassElement;
-      expect(objClassElem1, same(objClassElem2));
-    });
-  }
-
-  @override
-  test_ArgumentList_imported_function() {
-    return super.test_ArgumentList_imported_function().then((_) {
-      expect(request.cache.importKey, "import '/libA.dart';");
-    });
-  }
-
-  test_Assert() {
-    addTestSource('main() {assert(^)}');
-    return computeFull((bool result) {
-      assertSuggestClass('String');
-    });
-  }
-
-  @override
-  test_AssignmentExpression_RHS() {
-    return super.test_AssignmentExpression_RHS().then((_) {
-      expect(request.cache.importKey, '');
-    });
-  }
-
-  @override
-  test_Block() {
-    return super.test_Block().then((_) {
-      expect(request.cache.importKey,
-          'import "/testAB.dart";import "/testCD.dart" hide D;import "/testEEF.dart" show EE;import "/testG.dart" as g;');
-      assertCached('A');
-      assertCached('T3');
-    });
-  }
-
-  @override
-  test_Block_inherited_imported() {
-    return super.test_Block_inherited_imported().then((_) {
-      assertCached('E');
-      assertCached('F');
-      assertNotCached('e1');
-      assertNotCached('i2');
-      assertNotCached('m1');
-      assertNotCached('_pf');
-    });
-  }
-
-  test_Block_partial_results() {
-    // Block  BlockFunctionBody  MethodDeclaration
-    addSource(
-        '/testAB.dart',
-        '''
-      export "dart:math" hide max;
-      class A {int x;}
-      @deprecated D1() {int x;}
-      class _B { }''');
-    addSource(
-        '/testCD.dart',
-        '''
-      String T1;
-      var _T2;
-      class C { }
-      class D { }''');
-    addSource(
-        '/testEEF.dart',
-        '''
-      class EE { }
-      class F { }''');
-    addSource('/testG.dart', 'class G { }');
-    addSource(
-        '/testH.dart',
-        '''
-      class H { }
-      int T3;
-      var _T4;'''); // not imported
-    addTestSource('''
-      import "/testAB.dart";
-      import "/testCD.dart" hide D;
-      import "/testEEF.dart" show EE;
-      import "/testG.dart" as g;
-      int T5;
-      var _T6;
-      Z D2() {int x;}
-      class X {a() {var f; {var x;} ^ var r;} void b() { }}
-      class Z { }''');
-    ImportedReferenceContributor contributor = this.contributor;
-    contributor.shouldWaitForLowPrioritySuggestions = false;
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('C');
-      // Assert contributor does not wait for or include low priority results
-      // from non-imported libraries unless instructed to do so.
-      assertNotSuggested('H');
-    });
-  }
-
-  test_enum() {
-    addSource('/libA.dart', 'library A; enum E { one, two }');
-    addTestSource('import "/libA.dart"; main() {^}');
-    return computeFull((bool result) {
-      assertSuggestEnum('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-    });
-  }
-
-  test_function_parameters_mixed_required_and_named() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, {int y}) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_function_parameters_mixed_required_and_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, [int y]) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_named() {
-    addSource(
-        '/libA.dart',
-        '''
-void m({x, int y}) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_function_parameters_none() {
-    addSource(
-        '/libA.dart',
-        '''
-void m() {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-void m([x, int y]) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_function_parameters_required() {
-    addSource(
-        '/libA.dart',
-        '''
-void m(x, int y) {}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestFunction('m', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_inComment_endOfLine() {
-    addTestSource('''
-main() {
-  // text ^
-}
-''');
-    return computeFull((bool result) {
-      assertNoSuggestions();
-    });
-  }
-
-  test_InstanceCreationExpression() {
-    addSource(
-        '/testA.dart',
-        '''
-class A {foo(){var f; {var x;}}}
-class B {B(this.x, [String boo]) { } int x;}
-class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
-    addTestSource('''
-import "/testA.dart";
-import "dart:math" as math;
-main() {new ^ String x = "hello";}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion;
-
-      suggestion = assertSuggestImportedConstructor('Object');
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('A');
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('B');
-      expect(suggestion.element.parameters, '(int x, [String boo])');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.parameterNames[1], 'boo');
-      expect(suggestion.parameterTypes[1], 'String');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestImportedConstructor('C.bar');
-      expect(suggestion.element.parameters, "({dynamic boo: 'hoo', int z: 0})");
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'boo');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'z');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-
-      // Suggested by LibraryPrefixContributor
-      assertNotSuggested('math');
-    });
-  }
-
-  test_internal_sdk_libs() {
-    addTestSource('main() {p^}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggest('print');
-      assertSuggest('pow',
-          relevance: DART_RELEVANCE_LOW, importUri: 'dart:math');
-      // Do not suggest completions from internal SDK library
-      assertNotSuggested('printToConsole');
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, {int y}) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, [int y]) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_named() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m({x, int y}) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_none() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m() {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_positional() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m([x, int y]) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_required() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  void m(x, int y) {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion =
-          assertSuggestImportedMethod('m', 'A', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_mixin_ordering() {
-    addSource(
-        '/libA.dart',
-        '''
-class B {}
-class M1 {
-  void m() {}
-}
-class M2 {
-  void m() {}
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class C extends B with M1, M2 {
-  void f() {
-    ^
-  }
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestImportedMethod('m', 'M2', 'void');
-    });
-  }
-
-  /**
-   * Ensure that completions in one context don't appear in another
-   */
-  test_multiple_contexts() {
-    // Create a 2nd context with source
-    var context2 = AnalysisEngine.instance.createAnalysisContext();
-    context2.sourceFactory =
-        new SourceFactory([AbstractContextTest.SDK_RESOLVER, resourceResolver]);
-    String content2 = 'class ClassFromAnotherContext { }';
-    Source source2 =
-        provider.newFile('/context2/foo.dart', content2).createSource();
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source2);
-    context2.applyChanges(changeSet);
-    context2.setContents(source2, content2);
-
-    // Resolve the source in the 2nd context and update the index
-    var result = context2.performAnalysisTask();
-    while (result.hasMoreWork) {
-      result.changeNotices.forEach((ChangeNotice notice) {
-        CompilationUnit unit = notice.resolvedDartUnit;
-        if (unit != null) {
-          index.index(context2, unit);
-        }
-      });
-      result = context2.performAnalysisTask();
-    }
-
-    // Check that source in 2nd context does not appear in completion in 1st
-    addSource(
-        '/context1/libA.dart',
-        '''
-      library libA;
-      class ClassInLocalContext {int x;}''');
-    testFile = '/context1/completionTest.dart';
-    addTestSource('''
-      import "/context1/libA.dart";
-      import "/foo.dart";
-      main() {C^}
-      ''');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestImportedClass('ClassInLocalContext');
-      // Assert contributor does not include results from 2nd context.
-      assertNotSuggested('ClassFromAnotherContext');
-    });
-  }
-
-  test_no_parameters_field() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  int x;
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedField('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_getter() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  int get x => null;
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedGetter('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_setter() {
-    addSource(
-        '/libA.dart',
-        '''
-class A {
-  set x(int value) {};
-}
-''');
-    addTestSource('''
-import '/libA.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestImportedSetter('x');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  @override
-  test_partFile_TypeName() {
-    return super.test_partFile_TypeName().then((_) {
-      expect(request.cache.importKey, 'part of libA;');
-    });
-  }
-
-  @override
-  test_partFile_TypeName2() {
-    return super.test_partFile_TypeName2().then((_) {
-      expect(request.cache.importKey,
-          'library libA;import "/testB.dart";part "/testA.dart";');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
deleted file mode 100644
index 700f414..0000000
--- a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
+++ /dev/null
@@ -1,848 +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.
-
-library test.services.completion.dart.local;
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
-import 'package:analysis_server/plugin/protocol/protocol.dart'
-    hide Element, ElementKind;
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(LocalReferenceContributorTest);
-}
-
-@reflectiveTest
-class LocalReferenceContributorTest extends AbstractSelectorSuggestionTest {
-  @override
-  CompletionSuggestion assertSuggestLocalClass(String name,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT,
-      bool isDeprecated: false,
-      String elemFile,
-      int elemOffset}) {
-    return assertSuggestClass(name,
-        elemFile: elemFile,
-        elemOffset: elemOffset,
-        isDeprecated: isDeprecated,
-        kind: kind,
-        relevance: relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalClassTypeAlias(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertSuggestClassTypeAlias(name, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalConstructor(String name,
-      {int elemOffset}) {
-    return assertSuggestConstructor(name, elemOffset: elemOffset);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalField(String name, String type,
-      {int relevance: DART_RELEVANCE_LOCAL_FIELD, bool deprecated: false}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalFunction(
-      String name, String returnType,
-      {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool deprecated: false,
-      int relevance: DART_RELEVANCE_LOCAL_FUNCTION}) {
-    return assertSuggestFunction(name, returnType,
-        kind: kind, deprecated: deprecated, relevance: relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalFunctionTypeAlias(
-      String name, String returnType,
-      {bool deprecated: false, int relevance: DART_RELEVANCE_DEFAULT}) {
-    return assertSuggestFunctionTypeAlias(
-        name, returnType, deprecated, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalGetter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR, bool deprecated: false}) {
-    return assertSuggestGetter(name, returnType,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalMethod(
-      String name, String declaringType, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_METHOD, bool deprecated: false}) {
-    return assertSuggestMethod(name, declaringType, returnType,
-        relevance: relevance, isDeprecated: deprecated);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalSetter(String name,
-      {int relevance: DART_RELEVANCE_LOCAL_ACCESSOR}) {
-    return assertSuggestSetter(name, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalTopLevelVar(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE}) {
-    return assertSuggestTopLevelVar(name, returnType, relevance);
-  }
-
-  @override
-  CompletionSuggestion assertSuggestLocalVariable(
-      String name, String returnType,
-      {int relevance: DART_RELEVANCE_LOCAL_VARIABLE}) {
-    // Local variables should only be suggested by LocalReferenceContributor
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.LOCAL_VARIABLE));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType, returnType != null ? returnType : 'dynamic');
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
-  CompletionSuggestion assertSuggestParameter(String name, String returnType,
-      {int relevance: DART_RELEVANCE_PARAMETER}) {
-    CompletionSuggestion cs = assertSuggest(name,
-        csKind: CompletionSuggestionKind.INVOCATION, relevance: relevance);
-    expect(cs.returnType, returnType != null ? returnType : 'dynamic');
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.PARAMETER));
-    expect(element.name, equals(name));
-    expect(element.parameters, isNull);
-    expect(element.returnType,
-        equals(returnType != null ? returnType : 'dynamic'));
-    return cs;
-  }
-
-  fail_mixin_ordering() {
-    // TODO(paulberry): Duplicates aren't being removed, so we see both M1.m()
-    // and M2.m().
-    addTestSource('''
-class B {}
-class M1 {
-  void m() {}
-}
-class M2 {
-  void m() {}
-}
-class C extends B with M1, M2 {
-  void f() {
-    ^
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestMethod('m', 'M2', 'void');
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new LocalReferenceContributor();
-  }
-
-  test_break_ignores_outer_functions_using_closure() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    var f = () {
-      bar: while (true) { break ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_break_ignores_outer_functions_using_local_function() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    void f() {
-      bar: while (true) { break ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_break_ignores_toplevel_variables() {
-    addTestSource('''
-int x;
-void main() {
-  while (true) {
-    break ^
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNotSuggested('x');
-  }
-
-  test_break_ignores_unrelated_statements() {
-    addTestSource('''
-void main() {
-  foo: while (true) {}
-  while (true) { break ^ }
-  bar: while (true) {}
-}
-''');
-    expect(computeFast(), isTrue);
-    // The scope of the label defined by a labeled statement is just the
-    // statement itself, so neither "foo" nor "bar" are in scope at the caret
-    // position.
-    assertNotSuggested('foo');
-    assertNotSuggested('bar');
-  }
-
-  test_break_to_enclosing_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    bar: while (true) {
-      break ^
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-  }
-
-  test_constructor_parameters_mixed_required_and_named() {
-    addTestSource('class A {A(x, {int y}) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_mixed_required_and_positional() {
-    addTestSource('class A {A(x, [int y]) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_named() {
-    addTestSource('class A {A({x, int y}) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_positional() {
-    addTestSource('class A {A([x, int y]) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_constructor_parameters_required() {
-    addTestSource('class A {A(x, int y) {^}}');
-    expect(computeFast(), isTrue);
-    assertSuggestParameter('x', null);
-    assertSuggestParameter('y', 'int');
-  }
-
-  test_continue_from_loop_to_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    bar: case 2:
-      while (true) {
-        continue ^;
-      }
-      break;
-    baz: case 3:
-      break;
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-    assertSuggestLabel('baz');
-  }
-
-  test_continue_from_switch_to_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    switch (x) {
-      case 1:
-        continue ^;
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_closure_with_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    var f = () {
-      bar: while (true) { continue ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_closure_with_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      var f = () {
-        bar: while (true) { continue ^ }
-      };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_local_function_with_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    void f() {
-      bar: while (true) { continue ^ }
-    };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_outer_functions_using_local_function_with_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      void f() {
-        bar: while (true) { continue ^ }
-      };
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    // Labels in outer functions are never accessible.
-    assertSuggestLabel('bar');
-    assertNotSuggested('foo');
-  }
-
-  test_continue_ignores_unrelated_statements() {
-    addTestSource('''
-void main() {
-  foo: while (true) {}
-  while (true) { continue ^ }
-  bar: while (true) {}
-}
-''');
-    expect(computeFast(), isTrue);
-    // The scope of the label defined by a labeled statement is just the
-    // statement itself, so neither "foo" nor "bar" are in scope at the caret
-    // position.
-    assertNotSuggested('foo');
-    assertNotSuggested('bar');
-  }
-
-  test_continue_to_earlier_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    case 2:
-      continue ^;
-    case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_to_enclosing_loop() {
-    addTestSource('''
-void main() {
-  foo: while (true) {
-    bar: while (true) {
-      continue ^
-    }
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-  }
-
-  test_continue_to_enclosing_switch() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    foo: case 1:
-      break;
-    bar: case 2:
-      switch (y) {
-        case 1:
-          continue ^;
-      }
-      break;
-    baz: case 3:
-      break;
-  }
-}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-    assertSuggestLabel('bar');
-    assertSuggestLabel('baz');
-  }
-
-  test_continue_to_later_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    case 1:
-      break;
-    case 2:
-      continue ^;
-    foo: case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_continue_to_same_case() {
-    addTestSource('''
-void main() {
-  switch (x) {
-    case 1:
-      break;
-    foo: case 2:
-      continue ^;
-    case 3:
-      break;
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestLabel('foo');
-  }
-
-  test_enum() {
-    addTestSource('enum E { one, two } main() {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestEnum('E');
-    assertNotSuggested('one');
-    assertNotSuggested('two');
-  }
-
-  test_enum_deprecated() {
-    addTestSource('@deprecated enum E { one, two } main() {^}');
-    expect(computeFast(), isTrue);
-    assertSuggestEnum('E', isDeprecated: true);
-    assertNotSuggested('one');
-    assertNotSuggested('two');
-  }
-
-  test_function_parameters_mixed_required_and_named() {
-    addTestSource('''
-void m(x, {int y}) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_function_parameters_mixed_required_and_positional() {
-    addTestSource('''
-void m(x, [int y]) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_named() {
-    addTestSource('''
-void m({x, int y}) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_function_parameters_none() {
-    addTestSource('''
-void m() {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_positional() {
-    addTestSource('''
-void m([x, int y]) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_function_parameters_required() {
-    addTestSource('''
-void m(x, int y) {}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion = assertSuggestLocalFunction('m', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 2);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_ignore_symbol_being_completed() {
-    addTestSource('class MyClass { } main(MC^) { }');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalClass('MyClass');
-    assertNotSuggested('MC');
-  }
-
-  test_inComment_block_beforeNode() {
-    addTestSource('''
-main(aaa, bbb) {
-  /* text ^ */
-  print(42);
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_inComment_endOfLine_beforeNode() {
-    addTestSource('''
-main(aaa, bbb) {
-  // text ^
-  print(42);
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_inComment_endOfLine_beforeToken() {
-    addTestSource('''
-main(aaa, bbb) {
-  // text ^
-}
-''');
-    expect(computeFast(), isTrue);
-    assertNoSuggestions();
-  }
-
-  test_InstanceCreationExpression() {
-    addTestSource('''
-class A {foo(){var f; {var x;}}}
-class B {B(this.x, [String boo]) { } int x;}
-class C {C.bar({boo: 'hoo', int z: 0}) { } }
-main() {new ^ String x = "hello";}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion;
-
-      suggestion = assertSuggestLocalConstructor('A', elemOffset: -1);
-      expect(suggestion.element.parameters, '()');
-      expect(suggestion.element.returnType, 'A');
-      expect(suggestion.declaringType, 'A');
-      expect(suggestion.parameterNames, hasLength(0));
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestLocalConstructor('B');
-      expect(suggestion.element.parameters, '(int x, [String boo])');
-      expect(suggestion.element.returnType, 'B');
-      expect(suggestion.declaringType, 'B');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.parameterNames[1], 'boo');
-      expect(suggestion.parameterTypes[1], 'String');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-
-      suggestion = assertSuggestLocalConstructor('C.bar');
-      expect(suggestion.element.parameters, '({dynamic boo, int z})');
-      expect(suggestion.element.returnType, 'C');
-      expect(suggestion.declaringType, 'C');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'boo');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'z');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addTestSource('''
-class A {
-  void m(x, {int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addTestSource('''
-class A {
-  void m(x, [int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_named() {
-    addTestSource('''
-class A {
-  void m({x, int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  test_method_parameters_none() {
-    addTestSource('''
-class A {
-  void m() {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_positional() {
-    addTestSource('''
-class A {
-  void m([x, int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_method_parameters_required() {
-    addTestSource('''
-class A {
-  void m(x, int y) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    expect(computeFast(), isTrue);
-    CompletionSuggestion suggestion =
-        assertSuggestLocalMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 2);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  test_missing_params_constructor() {
-    addTestSource('class C1{C1{} main(){C^}}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_missing_params_function() {
-    addTestSource('int f1{} main(){f^}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_missing_params_method() {
-    addTestSource('class C1{int f1{} main(){f^}}');
-    expect(computeFast(), isTrue);
-  }
-
-  test_overrides() {
-    addTestSource('''
-class A {m() {}}
-class B extends A {m() {^}}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
-  }
-
-  test_prioritization_private() {
-    addTestSource('main() {var ab; var _ab; _^}');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null);
-  }
-
-  test_prioritization_public() {
-    addTestSource('main() {var ab; var _ab; a^}');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalVariable('ab', null);
-    assertSuggestLocalVariable('_ab', null, relevance: DART_RELEVANCE_DEFAULT);
-  }
-
-  test_shadowed_name() {
-    addTestSource('var a; class A { var a; m() { ^ } }');
-    expect(computeFast(), isTrue);
-    assertSuggestLocalField('a', null);
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
index 179b09b..8fb29bf 100644
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -15,6 +15,7 @@
 
 import '../../abstract_context.dart';
 import '../../utils.dart';
+import 'package:analysis_server/src/protocol_server.dart';
 
 main() {
   initializeTestEnvironment();
@@ -52,7 +53,8 @@
       bool statementLabel: false,
       bool staticMethodBody: false,
       bool typeNames: false,
-      bool voidReturn: false}) {
+      bool voidReturn: false,
+      CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION}) {
     expect(visitor.includeCaseLabelSuggestions, caseLabel, reason: 'caseLabel');
     expect(visitor.includeConstructorSuggestions, constructors,
         reason: 'constructors');
@@ -66,6 +68,7 @@
     expect(visitor.inStaticMethodBody, staticMethodBody,
         reason: 'staticMethodBody');
     expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
+    expect(visitor.suggestKind, kind, reason: 'suggestion kind');
   }
 
   void processRequiredPlugins() {
@@ -191,6 +194,36 @@
     assertOpType(returnValue: true, typeNames: true);
   }
 
+  test_AwaitExpression2() {
+    addTestSource('main() async {A a; await c^ await}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression3() {
+    addTestSource('main() async {A a; await ^ await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression4() {
+    addTestSource('main() async {A a; await ^ await bar();}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment() {
+    addTestSource('main() async {A a; int x = await ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment2() {
+    addTestSource('main() async {A a; int x = await ^ await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AwaitExpression_assignment3() {
+    addTestSource('main() async {A a; int x = await v^ int y = await foo;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_BinaryExpression_LHS() {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
@@ -375,7 +408,11 @@
   test_CommentReference() {
     // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
     addTestSource('class A {/** [^] */ mth() {}');
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+    assertOpType(
+        returnValue: true,
+        typeNames: true,
+        voidReturn: true,
+        kind: CompletionSuggestionKind.IDENTIFIER);
   }
 
   test_ConditionalExpression_elseExpression() {
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index 41ddfc9..d6b119e 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -7,27 +7,16 @@
 import 'package:unittest/unittest.dart';
 
 import '../../utils.dart';
-import 'completion_computer_test.dart' as completion_computer_test;
-import 'completion_manager_test.dart' as completion_manager_test;
 import 'completion_target_test.dart' as completion_target_test;
 import 'dart/test_all.dart' as dart_contributor_tests;
-import 'imported_reference_contributor_test.dart' as imported_test;
-import 'local_declaration_visitor_test.dart' as local_declaration_visitor_test;
-import 'local_reference_contributor_test.dart'
-    as local_reference_contributor_test;
 import 'optype_test.dart' as optype_test;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
   group('completion', () {
-    completion_computer_test.main();
-    completion_manager_test.main();
     completion_target_test.main();
     dart_contributor_tests.main();
-    imported_test.main();
-    local_declaration_visitor_test.main();
-    local_reference_contributor_test.main();
     optype_test.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index deb386d..1c2a964 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -5,8 +5,9 @@
 library test.services.correction.name_suggestion;
 
 import 'package:analysis_server/src/services/correction/name_suggestion.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/correction/source_range_test.dart b/pkg/analysis_server/test/services/correction/source_range_test.dart
index ebb0091..43d080b 100644
--- a/pkg/analysis_server/test/services/correction/source_range_test.dart
+++ b/pkg/analysis_server/test/services/correction/source_range_test.dart
@@ -5,8 +5,8 @@
 library test.services.correction.source_range;
 
 import 'package:analysis_server/src/services/correction/source_range.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 6405e01..555b5824 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -8,8 +8,8 @@
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
index 476c4dd..a33bd47 100644
--- a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
@@ -10,8 +10,8 @@
 import 'package:analysis_server/src/services/index/index_store.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/indexable_file.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1665,7 +1665,7 @@
     for (RecordedRelation recordedRelation in recordedRelations) {
       if (_equalsRecordedRelation(
           recordedRelation, expectedIndexable, relationship, location)) {
-        fail('not expected: ${recordedRelation} in\n' +
+        fail('not expected: $recordedRelation in\n' +
             recordedRelations.join('\n'));
       }
     }
diff --git a/pkg/analysis_server/test/services/index/local_index_test.dart b/pkg/analysis_server/test/services/index/local_index_test.dart
index dc2e92a..5f318ad 100644
--- a/pkg/analysis_server/test/services/index/local_index_test.dart
+++ b/pkg/analysis_server/test/services/index/local_index_test.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/src/services/index/index_contributor.dart';
 import 'package:analysis_server/src/services/index/local_index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/store/codec_test.dart b/pkg/analysis_server/test/services/index/store/codec_test.dart
index 15adf15..e7914b8 100644
--- a/pkg/analysis_server/test/services/index/store/codec_test.dart
+++ b/pkg/analysis_server/test/services/index/store/codec_test.dart
@@ -8,7 +8,7 @@
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/indexable_element.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index 1ae14d5..fbe43d7 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -12,7 +12,8 @@
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:analysis_server/src/services/index/store/memory_node_manager.dart';
 import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index 0dd3c77..f7b036f 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:unittest/unittest.dart';
 
 import 'abstract_refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index ca3a1db..4a62450 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -9,7 +9,7 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../utils.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 2e3551f..5dca20d 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -9,7 +9,7 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide ElementKind;
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../utils.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index cae09e7..cac1c16 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -36,9 +36,8 @@
     _createRefactoringForString('1 + 2');
     // conflicting name
     RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.WARNING,
-        expectedMessage:
-            "A variable with name 'res' is already defined in the visible scope.");
+    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
   }
 
   test_checkFinalConditions_sameVariable_before() async {
@@ -51,9 +50,8 @@
     _createRefactoringForString('1 + 2');
     // conflicting name
     RefactoringStatus status = await refactoring.checkAllConditions();
-    assertRefactoringStatus(status, RefactoringProblemSeverity.WARNING,
-        expectedMessage:
-            "A variable with name 'res' is already defined in the visible scope.");
+    assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
   }
 
   test_checkInitialConditions_assignmentLeftHandSize() async {
@@ -150,7 +148,20 @@
 ''');
   }
 
-  test_checkLocalName() {
+  test_checkInitialConditions_voidExpression() async {
+    indexTestUnit('''
+main() {
+  print(42);
+}
+''');
+    _createRefactoringForString('print');
+    // check conditions
+    RefactoringStatus status = await refactoring.checkInitialConditions();
+    assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL,
+        expectedMessage: 'Cannot extract the void expression.');
+  }
+
+  test_checkName() {
     indexTestUnit('''
 main() {
   int a = 1 + 2;
@@ -173,6 +184,55 @@
     assertRefactoringStatusOK(refactoring.checkName());
   }
 
+  test_checkName_conflict_withInvokedFunction() async {
+    indexTestUnit('''
+main() {
+  int a = 1 + 2;
+  res();
+}
+
+void res() {}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
+  }
+
+  test_checkName_conflict_withOtherLocal() async {
+    indexTestUnit('''
+main() {
+  var res;
+  int a = 1 + 2;
+}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'res' is already used in the scope.");
+  }
+
+  test_checkName_conflict_withTypeName() async {
+    indexTestUnit('''
+main() {
+  int a = 1 + 2;
+  Res b = null;
+}
+
+class Res {}
+''');
+    _createRefactoringForString('1 + 2');
+    await refactoring.checkInitialConditions();
+    refactoring.name = 'Res';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.ERROR,
+        expectedMessage: "The name 'Res' is already used in the scope.");
+  }
+
   test_completeStatementExpression() {
     indexTestUnit('''
 main(p) {
@@ -352,6 +412,20 @@
     expect(subExpressions, ['111', '111 + 222', 'foo(111 + 222)']);
   }
 
+  test_coveringExpressions_inInvocationOfVoidFunction() async {
+    indexTestUnit('''
+main() {
+  foo(111 + 222);
+}
+void foo(int x) {}
+''');
+    _createRefactoring(testCode.indexOf('11 +'), 0);
+    // check conditions
+    await refactoring.checkInitialConditions();
+    List<String> subExpressions = _getCoveringExpressions();
+    expect(subExpressions, ['111', '111 + 222']);
+  }
+
   test_coveringExpressions_skipAssignments() async {
     indexTestUnit('''
 main() {
@@ -960,6 +1034,22 @@
 ''');
   }
 
+  test_singleExpression_string() {
+    indexTestUnit('''
+void main() {
+  print("1234");
+}
+''');
+    _createRefactoringAtString('34"');
+    // apply refactoring
+    return _assertSuccessfulRefactoring('''
+void main() {
+  var res = "1234";
+  print(res);
+}
+''');
+  }
+
   test_singleExpression_trailingNotWhitespace() {
     indexTestUnit('''
 main() {
@@ -1093,6 +1183,16 @@
   }
 
   /**
+   * Creates a new refactoring in [refactoring] at the offset of the given
+   * [search] pattern, and with the length `0`.
+   */
+  void _createRefactoringAtString(String search) {
+    int offset = findOffset(search);
+    int length = 0;
+    _createRefactoring(offset, length);
+  }
+
+  /**
    * Creates a new refactoring in [refactoring] for the selection range of the
    * given [search] pattern.
    */
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index 9b6d46e..74d2ca8 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -7,8 +7,8 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 720dc9a..4d96523 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -10,7 +10,7 @@
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 31d826b..0e38446 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -10,7 +10,9 @@
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
diff --git a/pkg/analysis_server/test/stress/replay/operation.dart b/pkg/analysis_server/test/stress/replay/operation.dart
index d7af722..835eb50 100644
--- a/pkg/analysis_server/test/stress/replay/operation.dart
+++ b/pkg/analysis_server/test/stress/replay/operation.dart
@@ -12,22 +12,22 @@
 /**
  * An operation that will send an 'analysis.updateContent' request.
  */
-class AnalysisUpdateContent extends ServerOperation {
+class Analysis_UpdateContent extends ServerOperation {
   /**
    * The path of the file whose content is being updated.
    */
-  String filePath;
+  final String filePath;
 
   /**
    * The overlay used to update the content.
    */
-  dynamic overlay;
+  final dynamic overlay;
 
   /**
    * Initialize an operation to send an 'analysis.updateContent' request with
    * the given [filePath] and [overlay] as parameters.
    */
-  AnalysisUpdateContent(this.filePath, this.overlay);
+  Analysis_UpdateContent(this.filePath, this.overlay);
 
   @override
   void perform(Server server) {
@@ -46,6 +46,32 @@
 }
 
 /**
+ * An operation that will send a 'completion.getSuggestions' request.
+ */
+class Completion_GetSuggestions extends ServerOperation {
+  /**
+   * The path of the file in which completions are being requested.
+   */
+  final String filePath;
+
+  /**
+   * The offset at which completions are being requested.
+   */
+  final int offset;
+
+  /**
+   * Initialize an operation to send a 'completion.getSuggestions' request with
+   * the given [filePath] and [offset] as parameters.
+   */
+  Completion_GetSuggestions(this.filePath, this.offset);
+
+  @override
+  void perform(Server server) {
+    server.sendCompletionGetSuggestions(filePath, offset);
+  }
+}
+
+/**
  * An operation to be performed during the simulation.
  */
 abstract class ServerOperation {
diff --git a/pkg/analysis_server/test/stress/replay/replay.dart b/pkg/analysis_server/test/stress/replay/replay.dart
index 37de911..159944f 100644
--- a/pkg/analysis_server/test/stress/replay/replay.dart
+++ b/pkg/analysis_server/test/stress/replay/replay.dart
@@ -11,7 +11,9 @@
 import 'dart:io';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analyzer/src/generated/error.dart' as error;
 import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:args/args.dart';
@@ -34,11 +36,31 @@
  */
 class Driver {
   /**
+   * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
+   * to a file should be represented by an add overlay, followed by zero or more
+   * change overlays, followed by a remove overlay.
+   */
+  static String CHANGE_OVERLAY_STYLE = 'change';
+
+  /**
    * The name of the command-line flag that will print help text.
    */
   static String HELP_FLAG_NAME = 'help';
 
   /**
+   * The value of the [OVERLAY_STYLE_OPTION_NAME] indicating that modifications
+   * to a file should be represented by an add overlay, followed by zero or more
+   * additional add overlays, followed by a remove overlay.
+   */
+  static String MULTIPLE_ADD_OVERLAY_STYLE = 'multipleAdd';
+
+  /**
+   * The name of the command-line option used to specify the style of
+   * interaction to use when making `analysis.updateContent` requests.
+   */
+  static String OVERLAY_STYLE_OPTION_NAME = 'overlay-style';
+
+  /**
    * The name of the pubspec file.
    */
   static const String PUBSPEC_FILE_NAME = 'pubspec.yaml';
@@ -49,6 +71,11 @@
   static const String TEMP_BRANCH_NAME = 'temp';
 
   /**
+   * The style of interaction to use for analysis.updateContent requests.
+   */
+  OverlayStyle overlayStyle;
+
+  /**
    * The absolute path of the repository.
    */
   String repositoryPath;
@@ -87,75 +114,24 @@
   }
 
   /**
-   * Run the test based on the given command-line arguments ([args]).
+   * Run the simulation based on the given command-line arguments ([args]).
    */
   Future run(List<String> args) async {
     //
     // Process the command-line arguments.
     //
-    ArgParser parser = _createArgParser();
-    ArgResults results;
-    try {
-      results = parser.parse(args);
-    } catch (exception) {
-      _showUsage(parser);
+    if (!_processCommandLine(args)) {
       return null;
     }
-
-    if (results[HELP_FLAG_NAME]) {
-      _showUsage(parser);
-      return null;
-    }
-
-    List<String> arguments = results.arguments;
-    if (arguments.length < 2) {
-      _showUsage(parser);
-      return null;
-    }
-    repositoryPath = path.normalize(arguments[0]);
-    repository = new GitRepository(repositoryPath);
-
-    analysisRoots = arguments
-        .sublist(1)
-        .map((String analysisRoot) => path.normalize(analysisRoot))
-        .toList();
-    for (String analysisRoot in analysisRoots) {
-      if (repositoryPath != analysisRoot &&
-          !path.isWithin(repositoryPath, analysisRoot)) {
-        _showUsage(parser,
-            'Analysis roots must be contained within the repository: $analysisRoot');
-        return null;
-      }
-    }
     //
-    // Replay the commit history.
+    // Simulate interactions with the server.
     //
-    Stopwatch stopwatch = new Stopwatch();
-    statistics.stopwatch = stopwatch;
-    stopwatch.start();
-    await server.start();
-    server.sendServerSetSubscriptions([ServerService.STATUS]);
-    server.sendAnalysisSetGeneralSubscriptions(
-        [GeneralAnalysisService.ANALYZED_FILES]);
-    // TODO(brianwilkerson) Get the list of glob patterns from the server after
-    // an API for getting them has been implemented.
-    fileGlobs = <Glob>[
-      new Glob(path.context.separator, '**.dart'),
-      new Glob(path.context.separator, '**.html'),
-      new Glob(path.context.separator, '**.htm'),
-      new Glob(path.context.separator, '**/.analysisOptions')
-    ];
-    try {
-      _replayChanges();
-    } finally {
-      server.sendServerShutdown();
-      repository.checkout('master');
-    }
-    stopwatch.stop();
+    await _runSimulation();
     //
     // Print out statistics gathered while performing the simulation.
     //
     statistics.print();
+    exit(0);
     return null;
   }
 
@@ -170,24 +146,63 @@
         help: 'Print usage information',
         defaultsTo: false,
         negatable: false);
+
+    parser.addOption(OVERLAY_STYLE_OPTION_NAME,
+        help:
+            'The style of interaction to use for analysis.updateContent requests',
+        allowed: [CHANGE_OVERLAY_STYLE, MULTIPLE_ADD_OVERLAY_STYLE],
+        allowedHelp: {
+          CHANGE_OVERLAY_STYLE: '<add> <change>* <remove>',
+          MULTIPLE_ADD_OVERLAY_STYLE: '<add>+ <remove>'
+        },
+        defaultsTo: 'change');
     return parser;
   }
 
+  /**
+   * Add source edits to the given [fileEdit] based on the given [blobDiff].
+   */
   void _createSourceEdits(FileEdit fileEdit, BlobDiff blobDiff) {
     LineInfo info = fileEdit.lineInfo;
     for (DiffHunk hunk in blobDiff.hunks) {
-      List<SourceEdit> sourceEdits = <SourceEdit>[];
       int srcStart = info.getOffsetOfLine(hunk.srcLine);
       int srcEnd = info.getOffsetOfLine(hunk.srcLine + hunk.removeLines.length);
-      // TODO(brianwilkerson) Create multiple edits instead of a single edit.
-      sourceEdits.add(new SourceEdit(
-          srcStart, srcEnd - srcStart + 1, _join(hunk.addLines)));
+      String addedText = _join(hunk.addLines);
+      //
+      // Create the source edits.
+      //
+      List<int> breakOffsets = _getBreakOffsets(addedText);
+      int breakCount = breakOffsets.length;
+      List<SourceEdit> sourceEdits = <SourceEdit>[];
+      if (breakCount == 0) {
+        sourceEdits
+            .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, addedText));
+      } else {
+        int previousOffset = breakOffsets[0];
+        String string = addedText.substring(0, previousOffset);
+        sourceEdits
+            .add(new SourceEdit(srcStart, srcEnd - srcStart + 1, string));
+        String reconstruction = string;
+        for (int i = 1; i < breakCount; i++) {
+          int offset = breakOffsets[i];
+          string = addedText.substring(previousOffset, offset);
+          reconstruction += string;
+          sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string));
+          previousOffset = offset;
+        }
+        string = addedText.substring(previousOffset);
+        reconstruction += string;
+        sourceEdits.add(new SourceEdit(srcStart + previousOffset, 0, string));
+        if (reconstruction != addedText) {
+          throw new AssertionError();
+        }
+      }
       fileEdit.addSourceEdits(sourceEdits);
     }
   }
 
   /**
-   * Return athe absolute paths of all of the pubspec files in all of the
+   * Return the absolute paths of all of the pubspec files in all of the
    * analysis roots.
    */
   Iterable<String> _findPubspecsInAnalysisRoots() {
@@ -206,6 +221,33 @@
     return pubspecFiles;
   }
 
+  /**
+   * Return a list of offsets into the given [text] that represent good places
+   * to break the text when building edits.
+   */
+  List<int> _getBreakOffsets(String text) {
+    List<int> breakOffsets = <int>[];
+    Scanner scanner = new Scanner(null, new CharSequenceReader(text),
+        error.AnalysisErrorListener.NULL_LISTENER);
+    Token token = scanner.tokenize();
+    // TODO(brianwilkerson) Randomize. Sometimes add zero (0) as a break point.
+    while (token.type != TokenType.EOF) {
+      // TODO(brianwilkerson) Break inside comments?
+//      Token comment = token.precedingComments;
+      int offset = token.offset;
+      int length = token.length;
+      breakOffsets.add(offset);
+      if (token.type == TokenType.IDENTIFIER && length > 3) {
+        breakOffsets.add(offset + (length ~/ 2));
+      }
+      token = token.next;
+    }
+    return breakOffsets;
+  }
+
+  /**
+   * Join the given [lines] into a single string.
+   */
   String _join(List<String> lines) {
     StringBuffer buffer = new StringBuffer();
     for (int i = 0; i < lines.length; i++) {
@@ -215,9 +257,58 @@
   }
 
   /**
+   * Process the command-line [arguments]. Return `true` if the simulation
+   * should be run.
+   */
+  bool _processCommandLine(List<String> args) {
+    ArgParser parser = _createArgParser();
+    ArgResults results;
+    try {
+      results = parser.parse(args);
+    } catch (exception) {
+      _showUsage(parser);
+      return false;
+    }
+
+    if (results[HELP_FLAG_NAME]) {
+      _showUsage(parser);
+      return false;
+    }
+
+    String overlayStyleValue = results[OVERLAY_STYLE_OPTION_NAME];
+    if (overlayStyleValue == CHANGE_OVERLAY_STYLE) {
+      overlayStyle = OverlayStyle.change;
+    } else if (overlayStyleValue == MULTIPLE_ADD_OVERLAY_STYLE) {
+      overlayStyle = OverlayStyle.multipleAdd;
+    }
+
+    List<String> arguments = results.arguments;
+    if (arguments.length < 2) {
+      _showUsage(parser);
+      return false;
+    }
+    repositoryPath = path.normalize(arguments[0]);
+    repository = new GitRepository(repositoryPath);
+
+    analysisRoots = arguments
+        .sublist(1)
+        .map((String analysisRoot) => path.normalize(analysisRoot))
+        .toList();
+    for (String analysisRoot in analysisRoots) {
+      if (repositoryPath != analysisRoot &&
+          !path.isWithin(repositoryPath, analysisRoot)) {
+        _showUsage(parser,
+            'Analysis roots must be contained within the repository: $analysisRoot');
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
    * Replay the changes in each commit.
    */
-  void _replayChanges() {
+  Future _replayChanges() async {
     //
     // Get the revision history of the repo.
     //
@@ -228,17 +319,26 @@
     // Iterate over the history, applying changes.
     //
     bool firstCheckout = true;
-//    Map<String, List<AnalysisError>> expectedErrors = null;
+    ErrorMap expectedErrors = null;
     Iterable<String> changedPubspecs;
     while (iterator.moveNext()) {
       //
       // Checkout the commit on which the changes are based.
       //
-      repository.checkout(iterator.srcCommit);
-//      if (expectedErrors != null) {
-//        await server.analysisFinished;
-//        server.expectErrorState(expectedErrors);
-//      }
+      String commit = iterator.srcCommit;
+      repository.checkout(commit);
+      if (expectedErrors != null) {
+        ErrorMap actualErrors =
+            await server.computeErrorMap(server.analyzedDartFiles);
+        String difference = expectedErrors.expectErrorMap(actualErrors);
+        if (difference != null) {
+          stdout.write('Mismatched errors after commit ');
+          stdout.writeln(commit);
+          stdout.writeln();
+          stdout.writeln(difference);
+          return;
+        }
+      }
       if (firstCheckout) {
         changedPubspecs = _findPubspecsInAnalysisRoots();
         server.sendAnalysisSetAnalysisRoots(analysisRoots, []);
@@ -246,8 +346,7 @@
       } else {
         server.removeAllOverlays();
       }
-//      await server.analysisFinished;
-//      expectedErrors = server.errorMap;
+      expectedErrors = await server.computeErrorMap(server.analyzedDartFiles);
       for (String filePath in changedPubspecs) {
         _runPub(filePath);
       }
@@ -261,20 +360,28 @@
         _replayDiff(commitDelta);
       }
       changedPubspecs = commitDelta.filesMatching(PUBSPEC_FILE_NAME);
+      stdout.write('.');
     }
     server.removeAllOverlays();
+    stdout.writeln();
   }
 
+  /**
+   * Replay the changes between two commits, as represented by the given
+   * [commitDelta].
+   */
   void _replayDiff(CommitDelta commitDelta) {
     List<FileEdit> editList = <FileEdit>[];
     for (DiffRecord record in commitDelta.diffRecords) {
-      FileEdit edit = new FileEdit(record);
+      FileEdit edit = new FileEdit(overlayStyle, record);
       _createSourceEdits(edit, record.getBlobDiff());
       editList.add(edit);
     }
+    //
     // TODO(brianwilkerson) Randomize.
     // Randomly select operations from different files to simulate a user
     // editing multiple files simultaneously.
+    //
     for (FileEdit edit in editList) {
       List<String> currentFile = <String>[edit.filePath];
       server.sendAnalysisSetPriorityFiles(currentFile);
@@ -306,6 +413,34 @@
   }
 
   /**
+   * Run the simulation by starting up a server and sending it requests.
+   */
+  Future _runSimulation() async {
+    Stopwatch stopwatch = new Stopwatch();
+    statistics.stopwatch = stopwatch;
+    stopwatch.start();
+    await server.start();
+    server.sendServerSetSubscriptions([ServerService.STATUS]);
+    server.sendAnalysisSetGeneralSubscriptions(
+        [GeneralAnalysisService.ANALYZED_FILES]);
+    // TODO(brianwilkerson) Get the list of glob patterns from the server after
+    // an API for getting them has been implemented.
+    fileGlobs = <Glob>[
+      new Glob(path.context.separator, '**.dart'),
+      new Glob(path.context.separator, '**.html'),
+      new Glob(path.context.separator, '**.htm'),
+      new Glob(path.context.separator, '**/.analysisOptions')
+    ];
+    try {
+      await _replayChanges();
+    } finally {
+      server.sendServerShutdown();
+      repository.checkout('master');
+    }
+    stopwatch.stop();
+  }
+
+  /**
    * Display usage information, preceeded by the [errorMessage] if one is given.
    */
   void _showUsage(ArgParser parser, [String errorMessage = null]) {
@@ -338,6 +473,11 @@
  */
 class FileEdit {
   /**
+   * The style of interaction to use for analysis.updateContent requests.
+   */
+  OverlayStyle overlayStyle;
+
+  /**
    * The absolute path of the file to be edited.
    */
   String filePath;
@@ -358,10 +498,16 @@
   List<List<SourceEdit>> editLists = <List<SourceEdit>>[];
 
   /**
+   * The current content of the file. This field is only used if the overlay
+   * style is [OverlayStyle.multipleAdd].
+   */
+  String currentContent;
+
+  /**
    * Initialize a collection of edits to be associated with the file at the
    * given [filePath].
    */
-  FileEdit(DiffRecord record) {
+  FileEdit(this.overlayStyle, DiffRecord record) {
     filePath = record.srcPath;
     if (record.isAddition) {
       content = '';
@@ -372,6 +518,7 @@
       content = new File(filePath).readAsStringSync();
       lineInfo = new LineInfo(StringUtilities.computeLineStarts(content));
     }
+    currentContent = content;
   }
 
   /**
@@ -386,25 +533,43 @@
    * Return a list of operations to be sent to the server.
    */
   List<ServerOperation> getOperations() {
+    List<ServerOperation> operations = <ServerOperation>[];
+    void addUpdateContent(var overlay) {
+      operations.add(new Analysis_UpdateContent(filePath, overlay));
+    }
+
     // TODO(brianwilkerson) Randomize.
     // Make the order of edits random. Doing so will require updating the
     // offsets of edits after the selected edit point.
-    List<ServerOperation> operations = <ServerOperation>[];
-    operations.add(
-        new AnalysisUpdateContent(filePath, new AddContentOverlay(content)));
+    addUpdateContent(new AddContentOverlay(content));
     for (List<SourceEdit> editList in editLists.reversed) {
       for (SourceEdit edit in editList.reversed) {
-        operations.add(new AnalysisUpdateContent(
-            filePath, new ChangeContentOverlay([edit])));
+        var overlay = null;
+        if (overlayStyle == OverlayStyle.change) {
+          overlay = new ChangeContentOverlay([edit]);
+        } else if (overlayStyle == OverlayStyle.multipleAdd) {
+          currentContent = edit.apply(currentContent);
+          overlay = new AddContentOverlay(currentContent);
+        } else {
+          throw new StateError(
+              'Failed to handle overlay style = $overlayStyle');
+        }
+        if (overlay != null) {
+          addUpdateContent(overlay);
+        }
       }
     }
-    operations
-        .add(new AnalysisUpdateContent(filePath, new RemoveContentOverlay()));
+    addUpdateContent(new RemoveContentOverlay());
     return operations;
   }
 }
 
 /**
+ * The possible styles of interaction to use for analysis.updateContent requests.
+ */
+enum OverlayStyle { change, multipleAdd }
+
+/**
  * A set of statistics related to the execution of the simulation.
  */
 class Statistics {
@@ -434,6 +599,9 @@
    */
   Statistics(this.driver);
 
+  /**
+   * Print the statistics to [stdout].
+   */
   void print() {
     stdout.write('Replay commits in ');
     stdout.writeln(driver.repositoryPath);
@@ -447,6 +615,10 @@
     stdout.writeln(commitsWithChangeInRootCount);
   }
 
+  /**
+   * Return a textual representation of the given duration, represented in
+   * [milliseconds].
+   */
   String _printTime(int milliseconds) {
     int seconds = milliseconds ~/ 1000;
     milliseconds -= seconds * 1000;
diff --git a/pkg/analysis_server/test/stress/utilities/server.dart b/pkg/analysis_server/test/stress/utilities/server.dart
index 149dcdf..ee52fdd 100644
--- a/pkg/analysis_server/test/stress/utilities/server.dart
+++ b/pkg/analysis_server/test/stress/utilities/server.dart
@@ -17,6 +17,48 @@
 import '../../integration/integration_tests.dart' as base;
 
 /**
+ * ???
+ */
+class ErrorMap {
+  /**
+   * A table mapping file paths to the errors associated with that file.
+   */
+  final Map<String, List<AnalysisError>> pathMap =
+      new HashMap<String, List<AnalysisError>>();
+
+  /**
+   * Initialize a newly created error map.
+   */
+  ErrorMap();
+
+  /**
+   * Initialize a newly created error map to contain the same mapping as the
+   * given [errorMap].
+   */
+  ErrorMap.from(ErrorMap errorMap) {
+    pathMap.addAll(errorMap.pathMap);
+  }
+
+  void operator []=(String filePath, List<AnalysisError> errors) {
+    pathMap[filePath] = errors;
+  }
+
+  /**
+   * Compare the this error map with the state captured in the given [errorMap].
+   * Throw an exception if the two maps do not agree.
+   */
+  String expectErrorMap(ErrorMap errorMap) {
+    StringBuffer buffer = new StringBuffer();
+    _ErrorComparator comparator = new _ErrorComparator(buffer);
+    comparator.compare(pathMap, errorMap.pathMap);
+    if (buffer.length > 0) {
+      return buffer.toString();
+    }
+    return null;
+  }
+}
+
+/**
  * An interface for starting and communicating with an analysis server running
  * in a separate process.
  */
@@ -27,11 +69,10 @@
   List<String> filesWithOverlays = <String>[];
 
   /**
-   * A table mapping the absolute paths of files to the most recent set of
-   * errors received for that file.
+   * A mapping from the absolute paths of files to the most recent set of errors
+   * received for that file.
    */
-  Map<String, List<AnalysisError>> _errorMap =
-      new HashMap<String, List<AnalysisError>>();
+  ErrorMap _errorMap = new ErrorMap();
 
   /**
    * Initialize a new analysis server. The analysis server is not running and
@@ -43,17 +84,41 @@
   }
 
   /**
+   * Return a list of the paths of files that are currently being analyzed.
+   */
+  List<String> get analyzedDartFiles {
+    // TODO(brianwilkerson) Implement this.
+    return <String>[];
+  }
+
+  /**
    * Return a table mapping the absolute paths of files to the most recent set
    * of errors received for that file. The content of the map will not change
    * when new sets of errors are received.
    */
-  Map<String, List<AnalysisError>> get errorMap =>
-      new HashMap<String, List<AnalysisError>>.from(_errorMap);
+  ErrorMap get errorMap => new ErrorMap.from(_errorMap);
 
   @override
   base.Server get server => this;
 
   /**
+   * Compute a mapping from each of the file paths in the given list of
+   * [filePaths] to the list of errors in the file at that path.
+   */
+  Future<ErrorMap> computeErrorMap(List<String> filePaths) async {
+    ErrorMap errorMap = new ErrorMap();
+    List<Future> futures = <Future>[];
+    for (String filePath in filePaths) {
+      futures.add(sendAnalysisGetErrors(filePath)
+          .then((AnalysisGetErrorsResult result) {
+        errorMap[filePath] = result.errors;
+      }));
+    }
+    await Future.wait(futures);
+    return errorMap;
+  }
+
+  /**
    * Remove any existing overlays.
    */
   Future<AnalysisUpdateContentResult> removeAllOverlays() {
@@ -84,3 +149,141 @@
     _errorMap[params.file] = params.errors;
   }
 }
+
+/**
+ * A utility class used to compare two sets of errors.
+ */
+class _ErrorComparator {
+  /**
+   * An empty list of analysis errors.
+   */
+  static final List<AnalysisError> NO_ERRORS = <AnalysisError>[];
+
+  /**
+   * The buffer to which an error description will be written if any of the
+   * files have different errors than are expected.
+   */
+  final StringBuffer buffer;
+
+  /**
+   * Initialize a newly created comparator to write to the given [buffer].
+   */
+  _ErrorComparator(this.buffer);
+
+  /**
+   * Compare the [actualErrorMap] and the [expectedErrorMap], writing a
+   * description to the [buffer] if they are not the same. The error maps are
+   * expected to be maps from absolute file paths to the list of actual or
+   * expected errors.
+   */
+  void compare(Map<String, List<AnalysisError>> actualErrorMap,
+      Map<String, List<AnalysisError>> expectedErrorMap) {
+    Set<String> allFiles = new HashSet();
+    allFiles.addAll(actualErrorMap.keys);
+    allFiles.addAll(expectedErrorMap.keys);
+    List<String> sortedFiles = allFiles.toList()..sort();
+    for (String filePath in sortedFiles) {
+      List<AnalysisError> actualErrors = actualErrorMap[filePath];
+      List<AnalysisError> expectedErrors = expectedErrorMap[filePath];
+      _compareLists(
+          filePath, actualErrors ?? NO_ERRORS, expectedErrors ?? NO_ERRORS);
+    }
+  }
+
+  /**
+   * Compare the [actualErrors] and [expectedErrors], writing a description to
+   * the [buffer] if they are not the same.
+   */
+  void _compareLists(String filePath, List<AnalysisError> actualErrors,
+      List<AnalysisError> expectedErrors) {
+    List<AnalysisError> remainingExpected =
+        new List<AnalysisError>.from(expectedErrors);
+    for (AnalysisError actualError in actualErrors) {
+      AnalysisError expectedError = _findError(remainingExpected, actualError);
+      if (expectedError == null) {
+        _writeReport(filePath, actualErrors, expectedErrors);
+        return;
+      }
+      remainingExpected.remove(expectedError);
+    }
+    if (remainingExpected.isNotEmpty) {
+      _writeReport(filePath, actualErrors, expectedErrors);
+    }
+  }
+
+  /**
+   * Return `true` if the [firstError] and the [secondError] are equivalent.
+   */
+  bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
+      firstError.severity == secondError.severity &&
+      firstError.type == secondError.type &&
+      _equalLocations(firstError.location, secondError.location) &&
+      firstError.message == secondError.message;
+
+  /**
+   * Return `true` if the [firstLocation] and the [secondLocation] are
+   * equivalent.
+   */
+  bool _equalLocations(Location firstLocation, Location secondLocation) =>
+      firstLocation.file == secondLocation.file &&
+      firstLocation.offset == secondLocation.offset &&
+      firstLocation.length == secondLocation.length;
+
+  /**
+   * Search through the given list of [errors] for an error that is equal to the
+   * [targetError]. If one is found, return it, otherwise return `null`.
+   */
+  AnalysisError _findError(
+      List<AnalysisError> errors, AnalysisError targetError) {
+    for (AnalysisError error in errors) {
+      if (_equalErrors(error, targetError)) {
+        return error;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Write the given list of [errors], preceded by a header beginning with the
+   * given [prefix].
+   */
+  void _writeErrors(String prefix, List<AnalysisError> errors) {
+    buffer.write(prefix);
+    buffer.write(errors.length);
+    buffer.write(' errors:');
+    for (AnalysisError error in errors) {
+      buffer.writeln();
+      Location location = error.location;
+      int offset = location.offset;
+      buffer.write('    ');
+      buffer.write(location.file);
+      buffer.write(' (');
+      buffer.write(offset);
+      buffer.write('..');
+      buffer.write(offset + location.length);
+      buffer.write(') ');
+      buffer.write(error.severity);
+      buffer.write(', ');
+      buffer.write(error.type);
+      buffer.write(' : ');
+      buffer.write(error.message);
+    }
+  }
+
+  /**
+   * Write a report of the differences between the [actualErrors] and the
+   * [expectedErrors]. The errors are reported as being from the file at the
+   * given [filePath].
+   */
+  void _writeReport(String filePath, List<AnalysisError> actualErrors,
+      List<AnalysisError> expectedErrors) {
+    if (buffer.length > 0) {
+      buffer.writeln();
+      buffer.writeln();
+    }
+    buffer.writeln(filePath);
+    _writeErrors('  Expected ', expectedErrors);
+    buffer.writeln();
+    _writeErrors('  Found ', expectedErrors);
+  }
+}
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 0389ea4..b752b2e 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -73,7 +73,7 @@
         if (_typeRenames.containsKey(typeNameInSpec)) {
           typeNameInJava = _typeRenames[typeNameInSpec];
         }
-        map['${typeNameInJava}.java'] = (String pkgPath) {
+        map['$typeNameInJava.java'] = (String pkgPath) {
           String superclassName = null;
           if (isRefactoringFeedback) {
             superclassName = 'RefactoringFeedback';
@@ -156,11 +156,11 @@
   String _getEqualsLogicForField(TypeObjectField field, String other) {
     String name = javaName(field.name);
     if (isPrimitive(field.type) && !field.optional) {
-      return '${other}.${name} == ${name}';
+      return '$other.$name == $name';
     } else if (isArray(field.type)) {
-      return 'Arrays.equals(other.${name}, ${name})';
+      return 'Arrays.equals(other.$name, $name)';
     } else {
-      return 'ObjectUtilities.equals(${other}.${name}, ${name})';
+      return 'ObjectUtilities.equals($other.$name, $name)';
     }
   }
 
@@ -171,7 +171,7 @@
   String _getToStringForField(TypeObjectField field) {
     String name = javaName(field.name);
     if (isArray(field.type) || isList(field.type)) {
-      return 'StringUtils.join(${name}, ", ")';
+      return 'StringUtils.join($name, ", ")';
     } else {
       return name;
     }
@@ -199,7 +199,7 @@
     //
     _extraFieldsOnElement.forEach((String name, String value) {
       publicField(javaName(name), () {
-        writeln('private static final int ${name} = ${value};');
+        writeln('private static final int $name = $value;');
       });
     });
 
@@ -211,8 +211,8 @@
     //
     _extraMethodsOnElement.forEach((String methodName, String fieldName) {
       publicMethod(methodName, () {
-        writeln('public boolean ${methodName}() {');
-        writeln('  return (flags & ${fieldName}) != 0;');
+        writeln('public boolean $methodName() {');
+        writeln('  return (flags & $fieldName) != 0;');
         writeln('}');
       });
     });
@@ -225,23 +225,23 @@
   void _writeOutJsonObjectAddStatement(TypeObjectField field) {
     String name = javaName(field.name);
     if (isDeclaredInSpec(field.type)) {
-      writeln('jsonObject.add("${name}", ${name}.toJson());');
+      writeln('jsonObject.add("$name", $name.toJson());');
     } else if (field.type is TypeList) {
       TypeDecl listItemType = (field.type as TypeList).itemType;
       String jsonArrayName = 'jsonArray${capitalize(name)}';
-      writeln('JsonArray ${jsonArrayName} = new JsonArray();');
-      writeln('for (${javaType(listItemType)} elt : ${name}) {');
+      writeln('JsonArray $jsonArrayName = new JsonArray();');
+      writeln('for (${javaType(listItemType)} elt : $name) {');
       indent(() {
         if (isDeclaredInSpec(listItemType)) {
-          writeln('${jsonArrayName}.add(elt.toJson());');
+          writeln('$jsonArrayName.add(elt.toJson());');
         } else {
-          writeln('${jsonArrayName}.add(new JsonPrimitive(elt));');
+          writeln('$jsonArrayName.add(new JsonPrimitive(elt));');
         }
       });
       writeln('}');
-      writeln('jsonObject.add("${name}", ${jsonArrayName});');
+      writeln('jsonObject.add("$name", $jsonArrayName);');
     } else {
-      writeln('jsonObject.addProperty("${name}", ${name});');
+      writeln('jsonObject.addProperty("$name", $name);');
     }
   }
 
@@ -251,7 +251,7 @@
       toHtmlVisitor.br();
       toHtmlVisitor.write('@coverage dart.server.generated.types');
     }));
-    makeClass('public class ${className}', () {
+    makeClass('public class $className', () {
       TypeEnum typeEnum = type as TypeEnum;
       List<TypeEnumValue> values = typeEnum.values;
       //
@@ -291,7 +291,7 @@
       toHtmlVisitor.write('@coverage dart.server.generated.types');
     }));
     writeln('@SuppressWarnings("unused")');
-    String header = 'public class ${className}';
+    String header = 'public class $className';
     if (superclassName != null) {
       header += ' extends $superclassName';
     }
@@ -304,7 +304,7 @@
       //
       publicField(javaName("EMPTY_ARRAY"), () {
         writeln(
-            'public static final ${className}[] EMPTY_ARRAY = new ${className}[0];');
+            'public static final $className[] EMPTY_ARRAY = new $className[0];');
       });
 
       //
@@ -312,7 +312,7 @@
       //
       publicField(javaName("EMPTY_LIST"), () {
         writeln(
-            'public static final List<${className}> EMPTY_LIST = Lists.newArrayList();');
+            'public static final List<$className> EMPTY_LIST = Lists.newArrayList();');
       });
 
       //
@@ -361,9 +361,9 @@
       //
       constructor(className, () {
         javadocComment(toHtmlVisitor.collectHtml(() {
-          toHtmlVisitor.write('Constructor for {@link ${className}}.');
+          toHtmlVisitor.write('Constructor for {@link $className}.');
         }));
-        write('public ${className}(');
+        write('public $className(');
         // write out parameters to constructor
         List<String> parameters = new List();
         if (className == 'Outline') {
@@ -481,7 +481,7 @@
       if (className != 'Outline') {
         publicMethod('fromJson', () {
           writeln(
-              'public static ${className} fromJson(JsonObject jsonObject) {');
+              'public static $className fromJson(JsonObject jsonObject) {');
           indent(() {
             for (TypeObjectField field in fields) {
               write('${javaFieldType(field)} ${javaName(field.name)} = ');
@@ -514,7 +514,7 @@
               }
               writeln(';');
             }
-            write('return new ${className}(');
+            write('return new $className(');
             List<String> parameters = new List();
             for (TypeObjectField field in fields) {
               if (!_isTypeFieldInUpdateContentUnionType(
@@ -568,13 +568,13 @@
           className != 'RefactoringOptions') {
         publicMethod('fromJsonArray', () {
           writeln(
-              'public static List<${className}> fromJsonArray(JsonArray jsonArray) {');
+              'public static List<$className> fromJsonArray(JsonArray jsonArray) {');
           indent(() {
             writeln('if (jsonArray == null) {');
             writeln('  return EMPTY_LIST;');
             writeln('}');
             writeln(
-                'ArrayList<${className}> list = new ArrayList<${className}>(jsonArray.size());');
+                'ArrayList<$className> list = new ArrayList<$className>(jsonArray.size());');
             writeln('Iterator<JsonElement> iterator = jsonArray.iterator();');
             writeln('while (iterator.hasNext()) {');
             writeln('  list.add(fromJson(iterator.next().getAsJsonObject()));');
@@ -624,9 +624,9 @@
         writeln('@Override');
         writeln('public boolean equals(Object obj) {');
         indent(() {
-          writeln('if (obj instanceof ${className}) {');
+          writeln('if (obj instanceof $className) {');
           indent(() {
-            writeln('${className} other = (${className}) obj;');
+            writeln('$className other = ($className) obj;');
             writeln('return');
             indent(() {
               List<String> equalsForField = new List<String>();
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 2ff2fe8..3840d86 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -107,7 +107,7 @@
   for (String expectedAttribute in requiredAttributes) {
     if (!attributesFound.contains(expectedAttribute)) {
       throw new Exception(
-          '$context: ${element.localName} must contain attribute ${expectedAttribute}');
+          '$context: ${element.localName} must contain attribute $expectedAttribute');
     }
   }
 }
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 805dcd8..d7e871c 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.27.1
+* Moved the public and private API's for the element model into their proper places.
+* Added back support for auto-processing of plugins.
+
 ## 0.27.0
 * Support for DEP 37 (Assert with optional message).
 * Lexical support for DEP 40 (Interface libraries). This does not include any semantic checking to ensure that the
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index 59e66e7..74ed79c 100755
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -5,8 +5,8 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
new file mode 100644
index 0000000..e0efffc
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -0,0 +1,2051 @@
+// 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.dart.element.element;
+
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart' show DartObject;
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/model.dart' show AnalysisTarget;
+
+/**
+ * An element that represents a class.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassElement
+    implements TypeDefiningElement, TypeParameterizedElement {
+  /**
+   * An empty list of class elements.
+   */
+  static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
+
+  /**
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this class.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  /**
+   * Return a list containing all the supertypes defined for this class and its
+   * supertypes. This includes superclasses, mixins and interfaces.
+   */
+  List<InterfaceType> get allSupertypes;
+
+  /**
+   * Return a list containing all of the constructors declared in this class.
+   */
+  List<ConstructorElement> get constructors;
+
+  /**
+   * Return a list containing all of the fields declared in this class.
+   */
+  List<FieldElement> get fields;
+
+  /**
+   * Return `true` if this class or its superclass declares a non-final instance
+   * field.
+   */
+  bool get hasNonFinalField;
+
+  /**
+   * Return `true` if this class has reference to super (so, for example, cannot
+   * be used as a mixin).
+   */
+  bool get hasReferenceToSuper;
+
+  /**
+   * Return `true` if this class declares a static member.
+   */
+  bool get hasStaticMember;
+
+  /**
+   * Return a list containing all of the interfaces that are implemented by this
+   * class.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  List<InterfaceType> get interfaces;
+
+  /**
+   * Return `true` if this class is abstract. A class is abstract if it has an
+   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
+   * is different from <i>has unimplemented members</i>.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this class is defined by an enum declaration.
+   */
+  bool get isEnum;
+
+  /**
+   * Return `true` if this class is a mixin application.  A class is a mixin
+   * application if it was declared using the syntax "class A = B with C;".
+   */
+  bool get isMixinApplication;
+
+  /**
+   * Return `true` if this class [isProxy], or if it inherits the proxy
+   * annotation from a supertype.
+   */
+  bool get isOrInheritsProxy;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@proxy'.
+   */
+  bool get isProxy;
+
+  /**
+   * Return `true` if this class can validly be used as a mixin when defining
+   * another class. The behavior of this method is defined by the Dart Language
+   * Specification in section 9:
+   * <blockquote>
+   * It is a compile-time error if a declared or derived mixin refers to super.
+   * It is a compile-time error if a declared or derived mixin explicitly
+   * declares a constructor. It is a compile-time error if a mixin is derived
+   * from a class whose superclass is not Object.
+   * </blockquote>
+   */
+  bool get isValidMixin;
+
+  /**
+   * Return a list containing all of the methods declared in this class.
+   */
+  List<MethodElement> get methods;
+
+  /**
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  List<InterfaceType> get mixins;
+
+  /**
+   * Return the superclass of this class, or `null` if the class represents the
+   * class 'Object'. All other classes will have a non-`null` superclass. If the
+   * superclass was not explicitly declared then the implicit superclass
+   * 'Object' will be returned.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  InterfaceType get supertype;
+
+  @override
+  InterfaceType get type;
+
+  /**
+   * Return the unnamed constructor declared in this class, or `null` if this
+   * class does not declare an unnamed constructor but does declare named
+   * constructors. The returned constructor will be synthetic if this class does
+   * not declare any constructors, in which case it will represent the default
+   * constructor for the class.
+   */
+  ConstructorElement get unnamedConstructor;
+
+  @override
+  NamedCompilationUnitMember computeNode();
+
+  /**
+   * Return the field (synthetic or explicit) defined in this class that has the
+   * given [name], or `null` if this class does not define a field with the
+   * given name.
+   */
+  FieldElement getField(String name);
+
+  /**
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
+   */
+  PropertyAccessorElement getGetter(String name);
+
+  /**
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
+   */
+  MethodElement getMethod(String name);
+
+  /**
+   * Return the named constructor declared in this class with the given [name],
+   * or `null` if this class does not declare a named constructor with the given
+   * name.
+   */
+  ConstructorElement getNamedConstructor(String name);
+
+  /**
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
+   */
+  PropertyAccessorElement getSetter(String name);
+
+  /**
+   * Determine whether the given [constructor], which exists in the superclass
+   * of this class, is accessible to constructors in this class.
+   */
+  bool isSuperConstructorAccessible(ConstructorElement constructor);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library],
+   * ignoring abstract methods, or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is: If <i>C</i> declares an instance method named <i>m</i>
+   * that is accessible to <i>L</i>, then that method is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up method <i>m</i> in <i>S</i> with
+   * respect to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetter(
+      String getterName, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract getters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpInheritedConcreteGetter(
+      String getterName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract methods, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpInheritedConcreteMethod(
+      String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract setters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpInheritedConcreteSetter(
+      String setterName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpInheritedMethod(
+      String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethod(String methodName, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetter(
+      String setterName, LibraryElement library);
+}
+
+/**
+ * An element that is contained within a [ClassElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassMemberElement implements Element {
+  @override
+  ClassElement get enclosingElement;
+
+  /**
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
+   */
+  bool get isStatic;
+}
+
+/**
+ * An element representing a compilation unit.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CompilationUnitElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of compilation unit elements.
+   */
+  static const List<CompilationUnitElement> EMPTY_LIST =
+      const <CompilationUnitElement>[];
+
+  /**
+   * Return a list containing all of the top-level accessors (getters and
+   * setters) contained in this compilation unit.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  @override
+  LibraryElement get enclosingElement;
+
+  /**
+   * Return a list containing all of the enums contained in this compilation
+   * unit.
+   */
+  List<ClassElement> get enums;
+
+  /**
+   * Return a list containing all of the top-level functions contained in this
+   * compilation unit.
+   */
+  List<FunctionElement> get functions;
+
+  /**
+   * Return a list containing all of the function type aliases contained in this
+   * compilation unit.
+   */
+  List<FunctionTypeAliasElement> get functionTypeAliases;
+
+  /**
+   * Return `true` if this compilation unit defines a top-level function named
+   * `loadLibrary`.
+   */
+  bool get hasLoadLibraryFunction;
+
+  /**
+   * Return a list containing all of the top-level variables contained in this
+   * compilation unit.
+   */
+  List<TopLevelVariableElement> get topLevelVariables;
+
+  /**
+   * Return a list containing all of the classes contained in this compilation
+   * unit.
+   */
+  List<ClassElement> get types;
+
+  @override
+  CompilationUnit computeNode();
+
+  /**
+   * Return the element at the given [offset], maybe `null` if no such element.
+   */
+  Element getElementAt(int offset);
+
+  /**
+   * Return the enum defined in this compilation unit that has the given [name],
+   * or `null` if this compilation unit does not define an enum with the given
+   * name.
+   */
+  ClassElement getEnum(String name);
+
+  /**
+   * Return the class defined in this compilation unit that has the given
+   * [name], or `null` if this compilation unit does not define a class with the
+   * given name.
+   */
+  ClassElement getType(String name);
+}
+
+/**
+ * An element representing a constructor or a factory method defined within a
+ * class.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorElement
+    implements ClassMemberElement, ExecutableElement, ConstantEvaluationTarget {
+  /**
+   * An empty list of constructor elements.
+   */
+  static const List<ConstructorElement> EMPTY_LIST =
+      const <ConstructorElement>[];
+
+  /**
+   * Return `true` if this constructor is a const constructor.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if this constructor can be used as a default constructor -
+   * unnamed and has no required parameters.
+   */
+  bool get isDefaultConstructor;
+
+  /**
+   * Return `true` if this constructor represents a factory constructor.
+   */
+  bool get isFactory;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this constructor's name, or `null` if not named.
+   */
+  int get nameEnd;
+
+  /**
+   * Return the offset of the `.` before this constructor name, or `null` if
+   * not named.
+   */
+  int get periodOffset;
+
+  /**
+   * Return the constructor to which this constructor is redirecting, or `null`
+   * if this constructor does not redirect to another constructor or if the
+   * library containing this constructor has not yet been resolved.
+   */
+  ConstructorElement get redirectedConstructor;
+
+  @override
+  ConstructorDeclaration computeNode();
+}
+
+/**
+ * The base class for all of the elements in the element model. Generally
+ * speaking, the element model is a semantic model of the program that
+ * represents things that are declared with a name and hence can be referenced
+ * elsewhere in the code.
+ *
+ * There are two exceptions to the general case. First, there are elements in
+ * the element model that are created for the convenience of various kinds of
+ * analysis but that do not have any corresponding declaration within the source
+ * code. Such elements are marked as being <i>synthetic</i>. Examples of
+ * synthetic elements include
+ * * default constructors in classes that do not define any explicit
+ *   constructors,
+ * * getters and setters that are induced by explicit field declarations,
+ * * fields that are induced by explicit declarations of getters and setters,
+ *   and
+ * * functions representing the initialization expression for a variable.
+ *
+ * Second, there are elements in the element model that do not have a name.
+ * These correspond to unnamed functions and exist in order to more accurately
+ * represent the semantic structure of the program.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Element implements AnalysisTarget {
+  /**
+   * A comparator that can be used to sort elements by their name offset.
+   * Elements with a smaller offset will be sorted to be before elements with a
+   * larger name offset.
+   */
+  static final Comparator<Element> SORT_BY_OFFSET =
+      (Element firstElement, Element secondElement) =>
+          firstElement.nameOffset - secondElement.nameOffset;
+
+  /**
+   * Return the analysis context in which this element is defined.
+   */
+  AnalysisContext get context;
+
+  /**
+   * Return the display name of this element, or `null` if this element does not
+   * have a name.
+   *
+   * In most cases the name and the display name are the same. Differences
+   * though are cases such as setters where the name of some setter `set f(x)`
+   * is `f=`, instead of `f`.
+   */
+  String get displayName;
+
+  /**
+   * Return the content of the documentation comment (including delimiters) for
+   * this element, or `null` if this element does not or cannot have
+   * documentation.
+   */
+  String get documentationComment;
+
+  /**
+   * Return the source range of the documentation comment for this element,
+   * or `null` if this element does not or cannot have a documentation.
+   *
+   * Deprecated.  Use [documentationComment] instead.
+   */
+  @deprecated
+  SourceRange get docRange;
+
+  /**
+   * Return the element that either physically or logically encloses this
+   * element. This will be `null` if this element is a library because libraries
+   * are the top-level elements in the model.
+   */
+  Element get enclosingElement;
+
+  /**
+   * The unique integer identifier of this element.
+   */
+  int get id;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@deprecated'
+   * or '@Deprecated('..')'.
+   */
+  bool get isDeprecated;
+
+  /**
+   * Return `true` if this element has an annotation of the form '@override'.
+   */
+  bool get isOverride;
+
+  /**
+   * Return `true` if this element is private. Private elements are visible only
+   * within the library in which they are declared.
+   */
+  bool get isPrivate;
+
+  /**
+   * Return `true` if this element is public. Public elements are visible within
+   * any library that imports the library in which they are declared.
+   */
+  bool get isPublic;
+
+  /**
+   * Return `true` if this element is synthetic. A synthetic element is an
+   * element that is not represented in the source code explicitly, but is
+   * implied by the source code, such as the default constructor for a class
+   * that does not explicitly define any constructors.
+   */
+  bool get isSynthetic;
+
+  /**
+   * Return the kind of element that this is.
+   */
+  ElementKind get kind;
+
+  /**
+   * Return the library that contains this element. This will be the element
+   * itself if it is a library element. This will be `null` if this element is
+   * an HTML file because HTML files are not contained in libraries.
+   */
+  LibraryElement get library;
+
+  /**
+   * Return an object representing the location of this element in the element
+   * model. The object can be used to locate this element at a later time.
+   */
+  ElementLocation get location;
+
+  /**
+   * Return a list containing all of the metadata associated with this element.
+   * The array will be empty if the element does not have any metadata or if the
+   * library containing this element has not yet been resolved.
+   */
+  List<ElementAnnotation> get metadata;
+
+  /**
+   * Return the name of this element, or `null` if this element does not have a
+   * name.
+   */
+  String get name;
+
+  /**
+   * Return the length of the name of this element in the file that contains the
+   * declaration of this element, or `0` if this element does not have a name.
+   */
+  int get nameLength;
+
+  /**
+   * Return the offset of the name of this element in the file that contains the
+   * declaration of this element, or `-1` if this element is synthetic, does not
+   * have a name, or otherwise does not have an offset.
+   */
+  int get nameOffset;
+
+  @override
+  Source get source;
+
+  /**
+   * Return the resolved [CompilationUnit] that declares this element, or `null`
+   * if this element is synthetic.
+   *
+   * This method is expensive, because resolved AST might have been already
+   * evicted from cache, so parsing and resolving will be performed.
+   */
+  CompilationUnit get unit;
+
+  /**
+   * Use the given [visitor] to visit this element. Return the value returned by
+   * the visitor as a result of visiting this element.
+   */
+  accept(ElementVisitor visitor);
+
+  /**
+   * Return the documentation comment for this element as it appears in the
+   * original source (complete with the beginning and ending delimiters), or
+   * `null` if this element does not have a documentation comment associated
+   * with it. This can be a long-running operation if the information needed to
+   * access the comment is not cached.
+   *
+   * Throws [AnalysisException] if the documentation comment could not be
+   * determined because the analysis could not be performed
+   *
+   * Deprecated.  Use [documentationComment] instead.
+   */
+  @deprecated
+  String computeDocumentationComment();
+
+  /**
+   * Return the resolved [AstNode] node that declares this element, or `null` if
+   * this element is synthetic or isn't contained in a compilation unit, such as
+   * a [LibraryElement].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
+   *
+   * <b>Note:</b> This method cannot be used in an async environment.
+   */
+  AstNode computeNode();
+
+  /**
+   * Return the most immediate ancestor of this element for which the
+   * [predicate] returns `true`, or `null` if there is no such ancestor. Note
+   * that this element will never be returned.
+   */
+  Element getAncestor(Predicate<Element> predicate);
+
+  /**
+   * Return a display name for the given element that includes the path to the
+   * compilation unit in which the type is defined. If [shortName] is `null`
+   * then [getDisplayName] will be used as the name of this element. Otherwise
+   * the provided name will be used.
+   */
+  // TODO(brianwilkerson) Make the parameter optional.
+  String getExtendedDisplayName(String shortName);
+
+  /**
+   * Return `true` if this element, assuming that it is within scope, is
+   * accessible to code in the given [library]. This is defined by the Dart
+   * Language Specification in section 3.2:
+   * <blockquote>
+   * A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
+   * declared in <i>L</i> or if <i>m</i> is public.
+   * </blockquote>
+   */
+  bool isAccessibleIn(LibraryElement library);
+
+  /**
+   * Use the given [visitor] to visit all of the children of this element. There
+   * is no guarantee of the order in which the children will be visited.
+   */
+  void visitChildren(ElementVisitor visitor);
+}
+
+/**
+ * A single annotation associated with an element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ElementAnnotation {
+  /**
+   * An empty list of annotations.
+   */
+  static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
+
+  /**
+   * Return a representation of the value of this annotation.
+   *
+   * Return `null` if the value of this annotation could not be computed because
+   * of errors.
+   */
+  DartObject get constantValue;
+
+  /**
+   * Return the element representing the field, variable, or const constructor
+   * being used as an annotation.
+   */
+  Element get element;
+
+  /**
+   * Return `true` if this annotation marks the associated element as being
+   * deprecated.
+   */
+  bool get isDeprecated;
+
+  /**
+   * Return `true` if this annotation marks the associated method as being
+   * expected to override an inherited method.
+   */
+  bool get isOverride;
+
+  /**
+   * Return `true` if this annotation marks the associated class as implementing
+   * a proxy object.
+   */
+  bool get isProxy;
+}
+
+/**
+ * The enumeration `ElementKind` defines the various kinds of elements in the
+ * element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ElementKind extends Enum<ElementKind> {
+  static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
+
+  static const ElementKind COMPILATION_UNIT =
+      const ElementKind('COMPILATION_UNIT', 1, "compilation unit");
+
+  static const ElementKind CONSTRUCTOR =
+      const ElementKind('CONSTRUCTOR', 2, "constructor");
+
+  static const ElementKind DYNAMIC =
+      const ElementKind('DYNAMIC', 3, "<dynamic>");
+
+  static const ElementKind ERROR = const ElementKind('ERROR', 4, "<error>");
+
+  static const ElementKind EXPORT =
+      const ElementKind('EXPORT', 5, "export directive");
+
+  static const ElementKind FIELD = const ElementKind('FIELD', 6, "field");
+
+  static const ElementKind FUNCTION =
+      const ElementKind('FUNCTION', 7, "function");
+
+  static const ElementKind GETTER = const ElementKind('GETTER', 8, "getter");
+
+  static const ElementKind IMPORT =
+      const ElementKind('IMPORT', 9, "import directive");
+
+  static const ElementKind LABEL = const ElementKind('LABEL', 10, "label");
+
+  static const ElementKind LIBRARY =
+      const ElementKind('LIBRARY', 11, "library");
+
+  static const ElementKind LOCAL_VARIABLE =
+      const ElementKind('LOCAL_VARIABLE', 12, "local variable");
+
+  static const ElementKind METHOD = const ElementKind('METHOD', 13, "method");
+
+  static const ElementKind NAME = const ElementKind('NAME', 14, "<name>");
+
+  static const ElementKind PARAMETER =
+      const ElementKind('PARAMETER', 15, "parameter");
+
+  static const ElementKind PREFIX =
+      const ElementKind('PREFIX', 16, "import prefix");
+
+  static const ElementKind SETTER = const ElementKind('SETTER', 17, "setter");
+
+  static const ElementKind TOP_LEVEL_VARIABLE =
+      const ElementKind('TOP_LEVEL_VARIABLE', 18, "top level variable");
+
+  static const ElementKind FUNCTION_TYPE_ALIAS =
+      const ElementKind('FUNCTION_TYPE_ALIAS', 19, "function type alias");
+
+  static const ElementKind TYPE_PARAMETER =
+      const ElementKind('TYPE_PARAMETER', 20, "type parameter");
+
+  static const ElementKind UNIVERSE =
+      const ElementKind('UNIVERSE', 21, "<universe>");
+
+  static const List<ElementKind> values = const [
+    CLASS,
+    COMPILATION_UNIT,
+    CONSTRUCTOR,
+    DYNAMIC,
+    ERROR,
+    EXPORT,
+    FIELD,
+    FUNCTION,
+    GETTER,
+    IMPORT,
+    LABEL,
+    LIBRARY,
+    LOCAL_VARIABLE,
+    METHOD,
+    NAME,
+    PARAMETER,
+    PREFIX,
+    SETTER,
+    TOP_LEVEL_VARIABLE,
+    FUNCTION_TYPE_ALIAS,
+    TYPE_PARAMETER,
+    UNIVERSE
+  ];
+
+  /**
+   * The name displayed in the UI for this kind of element.
+   */
+  final String displayName;
+
+  /**
+   * Initialize a newly created element kind to have the given [displayName].
+   */
+  const ElementKind(String name, int ordinal, this.displayName)
+      : super(name, ordinal);
+
+  /**
+   * Return the kind of the given [element], or [ERROR] if the element is
+   * `null`. This is a utility method that can reduce the need for null checks
+   * in other places.
+   */
+  static ElementKind of(Element element) {
+    if (element == null) {
+      return ERROR;
+    }
+    return element.kind;
+  }
+}
+
+/**
+ * The location of an element within the element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ElementLocation {
+  /**
+   * Return the path to the element whose location is represented by this
+   * object. Clients must not modify the returned array.
+   */
+  List<String> get components;
+
+  /**
+   * Return an encoded representation of this location that can be used to
+   * create a location that is equal to this location.
+   */
+  String get encoding;
+}
+
+/**
+ * An object that can be used to visit an element structure.
+ *
+ * Clients may implement this class.
+ */
+abstract class ElementVisitor<R> {
+  R visitClassElement(ClassElement element);
+
+  R visitCompilationUnitElement(CompilationUnitElement element);
+
+  R visitConstructorElement(ConstructorElement element);
+
+  R visitExportElement(ExportElement element);
+
+  R visitFieldElement(FieldElement element);
+
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element);
+
+  R visitFunctionElement(FunctionElement element);
+
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
+
+  R visitImportElement(ImportElement element);
+
+  R visitLabelElement(LabelElement element);
+
+  R visitLibraryElement(LibraryElement element);
+
+  R visitLocalVariableElement(LocalVariableElement element);
+
+  R visitMethodElement(MethodElement element);
+
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element);
+
+  R visitParameterElement(ParameterElement element);
+
+  R visitPrefixElement(PrefixElement element);
+
+  R visitPropertyAccessorElement(PropertyAccessorElement element);
+
+  R visitTopLevelVariableElement(TopLevelVariableElement element);
+
+  R visitTypeParameterElement(TypeParameterElement element);
+}
+
+/**
+ * An element representing an executable object, including functions, methods,
+ * constructors, getters, and setters.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExecutableElement implements FunctionTypedElement {
+  /**
+   * An empty list of executable elements.
+   */
+  static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
+
+  /**
+   * Return a list containing all of the functions defined within this
+   * executable element.
+   */
+  List<FunctionElement> get functions;
+
+  /**
+   * Return `true` if this executable element did not have an explicit return
+   * type specified for it in the original source. Note that if there was no
+   * explicit return type, and if the element model is fully populated, then
+   * the [returnType] will not be `null`.
+   */
+  bool get hasImplicitReturnType;
+
+  /**
+   * Return `true` if this executable element is abstract. Executable elements
+   * are abstract if they are not external and have no body.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this executable element has body marked as being
+   * asynchronous.
+   */
+  bool get isAsynchronous;
+
+  /**
+   * Return `true` if this executable element is external. Executable elements
+   * are external if they are explicitly marked as such using the 'external'
+   * keyword.
+   */
+  bool get isExternal;
+
+  /**
+   * Return `true` if this executable element has a body marked as being a
+   * generator.
+   */
+  bool get isGenerator;
+
+  /**
+   * Return `true` if this executable element is an operator. The test may be
+   * based on the name of the executable element, in which case the result will
+   * be correct when the name is legal.
+   */
+  bool get isOperator;
+
+  /**
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
+   */
+  bool get isStatic;
+
+  /**
+   * Return `true` if this executable element has a body marked as being
+   * synchronous.
+   */
+  bool get isSynchronous;
+
+  /**
+   * Return a list containing all of the labels defined within this executable
+   * element.
+   */
+  List<LabelElement> get labels;
+
+  /**
+   * Return a list containing all of the local variables defined within this
+   * executable element.
+   */
+  List<LocalVariableElement> get localVariables;
+}
+
+/**
+ * An export directive within a library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExportElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of export elements.
+   */
+  static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
+
+  /**
+   * Return a list containing the combinators that were specified as part of the
+   * export directive in the order in which they were specified.
+   */
+  List<NamespaceCombinator> get combinators;
+
+  /**
+   * Return the library that is exported from this library by this export
+   * directive.
+   */
+  LibraryElement get exportedLibrary;
+}
+
+/**
+ * A field defined within a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldElement
+    implements ClassMemberElement, PropertyInducingElement {
+  /**
+   * An empty list of field elements.
+   */
+  static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
+
+  /**
+   * Return {@code true} if this element is an enum constant.
+   */
+  bool get isEnumConstant;
+
+  @override
+  AstNode computeNode();
+}
+
+/**
+ * A field formal parameter defined within a constructor element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldFormalParameterElement implements ParameterElement {
+  /**
+   * Return the field element associated with this field formal parameter, or
+   * `null` if the parameter references a field that doesn't exist.
+   */
+  FieldElement get field;
+}
+
+/**
+ * A (non-method) function. This can be either a top-level function, a local
+ * function, a closure, or the initialization expression for a field or
+ * variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionElement implements ExecutableElement, LocalElement {
+  /**
+   * An empty list of function elements.
+   */
+  static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
+
+  /**
+   * The name of the method that can be implemented by a class to allow its
+   * instances to be invoked as if they were a function.
+   */
+  static final String CALL_METHOD_NAME = "call";
+
+  /**
+   * The name of the synthetic function defined for libraries that are deferred.
+   */
+  static final String LOAD_LIBRARY_NAME = "loadLibrary";
+
+  /**
+   * The name of the function used as an entry point.
+   */
+  static const String MAIN_FUNCTION_NAME = "main";
+
+  /**
+   * The name of the method that will be invoked if an attempt is made to invoke
+   * an undefined method on an object.
+   */
+  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
+
+  /**
+   * Return `true` if the function is an entry point, i.e. a top-level function
+   * and has the name `main`.
+   */
+  bool get isEntryPoint;
+
+  @override
+  FunctionDeclaration computeNode();
+}
+
+/**
+ * A function type alias (`typedef`).
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypeAliasElement implements FunctionTypedElement {
+  /**
+   * An empty array of type alias elements.
+   */
+  static List<FunctionTypeAliasElement> EMPTY_LIST =
+      new List<FunctionTypeAliasElement>(0);
+
+  /**
+   * Return the compilation unit in which this type alias is defined.
+   */
+  @override
+  CompilationUnitElement get enclosingElement;
+
+  @override
+  FunctionTypeAlias computeNode();
+}
+
+/**
+ * An element that has a [FunctionType] as its [type].
+ *
+ * This also provides convenient access to the parameters and return type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypedElement
+    implements TypeDefiningElement, TypeParameterizedElement {
+  /**
+   * Return a list containing all of the parameters defined by this executable
+   * element.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return the return type defined by this element. If the element model is
+   * fully populated, then the [returnType] will not be `null`, even if no
+   * return type was explicitly specified.
+   */
+  DartType get returnType;
+
+  @override
+  FunctionType get type;
+}
+
+/**
+ * A combinator that causes some of the names in a namespace to be hidden when
+ * being imported.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class HideElementCombinator implements NamespaceCombinator {
+  /**
+   * Return a list containing the names that are not to be made visible in the
+   * importing library even if they are defined in the imported library.
+   */
+  List<String> get hiddenNames;
+}
+
+/**
+ * A single import directive within a library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ImportElement implements Element, UriReferencedElement {
+  /**
+   * An empty list of import elements.
+   */
+  static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
+
+  /**
+   * Return a list containing the combinators that were specified as part of the
+   * import directive in the order in which they were specified.
+   */
+  List<NamespaceCombinator> get combinators;
+
+  /**
+   * Return the library that is imported into this library by this import
+   * directive.
+   */
+  LibraryElement get importedLibrary;
+
+  /**
+   * Return `true` if this import is for a deferred library.
+   */
+  bool get isDeferred;
+
+  /**
+   * Return the prefix that was specified as part of the import directive, or
+   * `null` if there was no prefix specified.
+   */
+  PrefixElement get prefix;
+
+  /**
+   * Return the offset of the prefix of this import in the file that contains
+   * this import directive, or `-1` if this import is synthetic, does not have a
+   * prefix, or otherwise does not have an offset.
+   */
+  int get prefixOffset;
+}
+
+/**
+ * A label associated with a statement.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LabelElement implements Element {
+  /**
+   * An empty list of label elements.
+   */
+  static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
+
+  @override
+  ExecutableElement get enclosingElement;
+}
+
+/**
+ * A library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LibraryElement implements Element {
+  /**
+   * An empty list of library elements.
+   */
+  static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
+
+  /**
+   * Return the compilation unit that defines this library.
+   */
+  CompilationUnitElement get definingCompilationUnit;
+
+  /**
+   * Return the entry point for this library, or `null` if this library does not
+   * have an entry point. The entry point is defined to be a zero argument
+   * top-level function whose name is `main`.
+   */
+  FunctionElement get entryPoint;
+
+  /**
+   * Return a list containing all of the libraries that are exported from this
+   * library.
+   */
+  List<LibraryElement> get exportedLibraries;
+
+  /**
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get exportNamespace;
+
+  /**
+   * Return a list containing all of the exports defined in this library.
+   */
+  List<ExportElement> get exports;
+
+  /**
+   * Return `true` if the defining compilation unit of this library contains at
+   * least one import directive whose URI uses the "dart-ext" scheme.
+   */
+  bool get hasExtUri;
+
+  /**
+   * Return `true` if this library defines a top-level function named
+   * `loadLibrary`.
+   */
+  bool get hasLoadLibraryFunction;
+
+  /**
+   * Return an identifier that uniquely identifies this element among the
+   * children of this element's parent.
+   */
+  String get identifier;
+
+  /**
+   * Return a list containing all of the libraries that are imported into this
+   * library. This includes all of the libraries that are imported using a
+   * prefix (also available through the prefixes returned by [getPrefixes]) and
+   * those that are imported without a prefix.
+   */
+  List<LibraryElement> get importedLibraries;
+
+  /**
+   * Return a list containing all of the imports defined in this library.
+   */
+  List<ImportElement> get imports;
+
+  /**
+   * Return `true` if this library is an application that can be run in the
+   * browser.
+   */
+  bool get isBrowserApplication;
+
+  /**
+   * Return `true` if this library is the dart:core library.
+   */
+  bool get isDartCore;
+
+  /**
+   * Return `true` if this library is part of the SDK.
+   */
+  bool get isInSdk;
+
+  /**
+   * Return the element representing the synthetic function `loadLibrary` that
+   * is implicitly defined for this library if the library is imported using a
+   * deferred import.
+   */
+  FunctionElement get loadLibraryFunction;
+
+  /**
+   * Return a list containing all of the compilation units that are included in
+   * this library using a `part` directive. This does not include the defining
+   * compilation unit that contains the `part` directives.
+   */
+  List<CompilationUnitElement> get parts;
+
+  /**
+   * Return a list containing elements for each of the prefixes used to `import`
+   * libraries into this library. Each prefix can be used in more than one
+   * `import` directive.
+   */
+  List<PrefixElement> get prefixes;
+
+  /**
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get publicNamespace;
+
+  /**
+   * Return a list containing all of the compilation units this library consists
+   * of. This includes the defining compilation unit and units included using
+   * the `part` directive.
+   */
+  List<CompilationUnitElement> get units;
+
+  /**
+   * Return a list containing all directly and indirectly imported libraries.
+   */
+  List<LibraryElement> get visibleLibraries;
+
+  /**
+   * Return a list containing all of the imports that share the given [prefix],
+   * or an empty array if there are no such imports.
+   */
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
+
+  /**
+   * Return the class defined in this library that has the given [name], or
+   * `null` if this library does not define a class with the given name.
+   */
+  ClassElement getType(String className);
+
+  /**
+   * Return `true` if this library is up to date with respect to the given
+   * [timeStamp]. If any transitively referenced Source is newer than the time
+   * stamp, this method returns false.
+   */
+  bool isUpToDate(int timeStamp);
+}
+
+/**
+ * An element that can be (but is not required to be) defined within a method
+ * or function (an [ExecutableElement]).
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LocalElement implements Element {
+  /**
+   * Return a source range that covers the approximate portion of the source in
+   * which the name of this element is visible, or `null` if there is no single
+   * range of characters within which the element name is visible.
+   *
+   * * For a local variable, this includes everything from the end of the
+   *   variable's initializer to the end of the block that encloses the variable
+   *   declaration.
+   * * For a parameter, this includes the body of the method or function that
+   *   declares the parameter.
+   * * For a local function, this includes everything from the beginning of the
+   *   function's body to the end of the block that encloses the function
+   *   declaration.
+   * * For top-level functions, `null` will be returned because they are
+   *   potentially visible in multiple sources.
+   */
+  SourceRange get visibleRange;
+}
+
+/**
+ * A local variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LocalVariableElement implements LocalElement, VariableElement {
+  /**
+   * An empty list of field elements.
+   */
+  static const List<LocalVariableElement> EMPTY_LIST =
+      const <LocalVariableElement>[];
+}
+
+/**
+ * An element that represents a method defined within a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MethodElement implements ClassMemberElement, ExecutableElement {
+  /**
+   * An empty list of method elements.
+   */
+  static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
+
+  @override
+  MethodDeclaration computeNode();
+}
+
+/**
+ * The enumeration `Modifier` defines constants for all of the modifiers defined
+ * by the Dart language and for a few additional flags that are useful.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class Modifier extends Enum<Modifier> {
+  /**
+   * Indicates that the modifier 'abstract' was applied to the element.
+   */
+  static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
+
+  /**
+   * Indicates that an executable element has a body marked as being
+   * asynchronous.
+   */
+  static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
+
+  /**
+   * Indicates that the modifier 'const' was applied to the element.
+   */
+  static const Modifier CONST = const Modifier('CONST', 2);
+
+  /**
+   * Indicates that the import element represents a deferred library.
+   */
+  static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
+
+  /**
+   * Indicates that a class element was defined by an enum declaration.
+   */
+  static const Modifier ENUM = const Modifier('ENUM', 4);
+
+  /**
+   * Indicates that a class element was defined by an enum declaration.
+   */
+  static const Modifier EXTERNAL = const Modifier('EXTERNAL', 5);
+
+  /**
+   * Indicates that the modifier 'factory' was applied to the element.
+   */
+  static const Modifier FACTORY = const Modifier('FACTORY', 6);
+
+  /**
+   * Indicates that the modifier 'final' was applied to the element.
+   */
+  static const Modifier FINAL = const Modifier('FINAL', 7);
+
+  /**
+   * Indicates that an executable element has a body marked as being a
+   * generator.
+   */
+  static const Modifier GENERATOR = const Modifier('GENERATOR', 8);
+
+  /**
+   * Indicates that the pseudo-modifier 'get' was applied to the element.
+   */
+  static const Modifier GETTER = const Modifier('GETTER', 9);
+
+  /**
+   * A flag used for libraries indicating that the defining compilation unit
+   * contains at least one import directive whose URI uses the "dart-ext"
+   * scheme.
+   */
+  static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 10);
+
+  /**
+   * Indicates that the associated element did not have an explicit type
+   * associated with it. If the element is an [ExecutableElement], then the
+   * type being referred to is the return type.
+   */
+  static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 11);
+
+  /**
+   * Indicates that a class can validly be used as a mixin.
+   */
+  static const Modifier MIXIN = const Modifier('MIXIN', 12);
+
+  /**
+   * Indicates that a class is a mixin application.
+   */
+  static const Modifier MIXIN_APPLICATION =
+      const Modifier('MIXIN_APPLICATION', 13);
+
+  /**
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the context.
+   */
+  static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
+      const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 14);
+
+  /**
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the scope.
+   */
+  static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
+      const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 15);
+
+  /**
+   * Indicates that a class contains an explicit reference to 'super'.
+   */
+  static const Modifier REFERENCES_SUPER =
+      const Modifier('REFERENCES_SUPER', 16);
+
+  /**
+   * Indicates that the pseudo-modifier 'set' was applied to the element.
+   */
+  static const Modifier SETTER = const Modifier('SETTER', 17);
+
+  /**
+   * Indicates that the modifier 'static' was applied to the element.
+   */
+  static const Modifier STATIC = const Modifier('STATIC', 18);
+
+  /**
+   * Indicates that the element does not appear in the source code but was
+   * implicitly created. For example, if a class does not define any
+   * constructors, an implicit zero-argument constructor will be created and it
+   * will be marked as being synthetic.
+   */
+  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 19);
+
+  static const List<Modifier> values = const [
+    ABSTRACT,
+    ASYNCHRONOUS,
+    CONST,
+    DEFERRED,
+    ENUM,
+    EXTERNAL,
+    FACTORY,
+    FINAL,
+    GENERATOR,
+    GETTER,
+    HAS_EXT_URI,
+    IMPLICIT_TYPE,
+    MIXIN,
+    MIXIN_APPLICATION,
+    POTENTIALLY_MUTATED_IN_CONTEXT,
+    POTENTIALLY_MUTATED_IN_SCOPE,
+    REFERENCES_SUPER,
+    SETTER,
+    STATIC,
+    SYNTHETIC
+  ];
+
+  const Modifier(String name, int ordinal) : super(name, ordinal);
+}
+
+/**
+ * A pseudo-element that represents multiple elements defined within a single
+ * scope that have the same name. This situation is not allowed by the language,
+ * so objects implementing this interface always represent an error. As a
+ * result, most of the normal operations on elements do not make sense and will
+ * return useless results.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MultiplyDefinedElement implements Element {
+  /**
+   * Return a list containing all of the elements that were defined within the
+   * scope to have the same name.
+   */
+  List<Element> get conflictingElements;
+
+  /**
+   * Return the type of this element as the dynamic type.
+   */
+  DartType get type;
+}
+
+/**
+ * An [ExecutableElement], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
+  /**
+   * Return a list containing all of the executable elements defined within this
+   * executable element.
+   */
+  List<ExecutableElement> get inheritedElements;
+}
+
+/**
+ * An object that controls how namespaces are combined.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NamespaceCombinator {
+  /**
+   * An empty list of namespace combinators.
+   */
+  static const List<NamespaceCombinator> EMPTY_LIST =
+      const <NamespaceCombinator>[];
+}
+
+/**
+ * A parameter defined within an executable element.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ParameterElement
+    implements LocalElement, VariableElement, ConstantEvaluationTarget {
+  /**
+   * An empty list of parameter elements.
+   */
+  static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
+
+  /**
+   * Return the Dart code of the default value, or `null` if no default value.
+   */
+  String get defaultValueCode;
+
+  /**
+   * Return `true` if this parameter is an initializing formal parameter.
+   */
+  bool get isInitializingFormal;
+
+  /**
+   * Return the kind of this parameter.
+   */
+  ParameterKind get parameterKind;
+
+  /**
+   * Return a list containing all of the parameters defined by this parameter.
+   * A parameter will only define other parameters if it is a function typed
+   * parameter.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return a list containing all of the type parameters defined by this
+   * parameter. A parameter will only define other parameters if it is a
+   * function typed parameter.
+   */
+  List<TypeParameterElement> get typeParameters;
+
+  /**
+   * Append the type, name and possibly the default value of this parameter to
+   * the given [buffer].
+   */
+  void appendToWithoutDelimiters(StringBuffer buffer);
+
+  @override
+  FormalParameter computeNode();
+}
+
+/**
+ * A prefix used to import one or more libraries into another library.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PrefixElement implements Element {
+  /**
+   * An empty list of prefix elements.
+   */
+  static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
+
+  @override
+  LibraryElement get enclosingElement;
+
+  /**
+   * Return a list containing all of the libraries that are imported using this
+   * prefix.
+   */
+  List<LibraryElement> get importedLibraries;
+}
+
+/**
+ * A getter or a setter. Note that explicitly defined property accessors
+ * implicitly define a synthetic field. Symmetrically, synthetic accessors are
+ * implicitly created for explicitly defined fields. The following rules apply:
+ *
+ * * Every explicit field is represented by a non-synthetic [FieldElement].
+ * * Every explicit field induces a getter and possibly a setter, both of which
+ *   are represented by synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a field that is represented by a synthetic [FieldElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PropertyAccessorElement implements ExecutableElement {
+  /**
+   * An empty list of property accessor elements.
+   */
+  static const List<PropertyAccessorElement> EMPTY_LIST =
+      const <PropertyAccessorElement>[];
+
+  /**
+   * Return the accessor representing the getter that corresponds to (has the
+   * same name as) this setter, or `null` if this accessor is not a setter or if
+   * there is no corresponding getter.
+   */
+  PropertyAccessorElement get correspondingGetter;
+
+  /**
+   * Return the accessor representing the setter that corresponds to (has the
+   * same name as) this getter, or `null` if this accessor is not a getter or if
+   * there is no corresponding setter.
+   */
+  PropertyAccessorElement get correspondingSetter;
+
+  /**
+   * Return `true` if this accessor represents a getter.
+   */
+  bool get isGetter;
+
+  /**
+   * Return `true` if this accessor represents a setter.
+   */
+  bool get isSetter;
+
+  /**
+   * Return the field or top-level variable associated with this accessor. If
+   * this accessor was explicitly defined (is not synthetic) then the variable
+   * associated with it will be synthetic.
+   */
+  PropertyInducingElement get variable;
+}
+
+/**
+ * A variable that has an associated getter and possibly a setter. Note that
+ * explicitly defined variables implicitly define a synthetic getter and that
+ * non-`final` explicitly defined variables implicitly define a synthetic
+ * setter. Symmetrically, synthetic fields are implicitly created for explicitly
+ * defined getters and setters. The following rules apply:
+ *
+ * * Every explicit variable is represented by a non-synthetic
+ *   [PropertyInducingElement].
+ * * Every explicit variable induces a getter and possibly a setter, both of
+ *   which are represented by synthetic [PropertyAccessorElement]s.
+ * * Every explicit getter or setter is represented by a non-synthetic
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a variable that is represented by a synthetic
+ *   [PropertyInducingElement].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PropertyInducingElement implements VariableElement {
+  /**
+   * An empty list of elements.
+   */
+  static const List<PropertyInducingElement> EMPTY_LIST =
+      const <PropertyInducingElement>[];
+
+  /**
+   * Return the getter associated with this variable. If this variable was
+   * explicitly defined (is not synthetic) then the getter associated with it
+   * will be synthetic.
+   */
+  PropertyAccessorElement get getter;
+
+  /**
+   * Return the propagated type of this variable, or `null` if type propagation
+   * has not been performed, for example because the variable is not final.
+   */
+  DartType get propagatedType;
+
+  /**
+   * Return the setter associated with this variable, or `null` if the variable
+   * is effectively `final` and therefore does not have a setter associated with
+   * it. (This can happen either because the variable is explicitly defined as
+   * being `final` or because the variable is induced by an explicit getter that
+   * does not have a corresponding setter.) If this variable was explicitly
+   * defined (is not synthetic) then the setter associated with it will be
+   * synthetic.
+   */
+  PropertyAccessorElement get setter;
+}
+
+/**
+ * A combinator that cause some of the names in a namespace to be visible (and
+ * the rest hidden) when being imported.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ShowElementCombinator implements NamespaceCombinator {
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node.
+   */
+  int get end;
+
+  /**
+   * Return the offset of the 'show' keyword of this element.
+   */
+  int get offset;
+
+  /**
+   * Return a list containing the names that are to be made visible in the
+   * importing library if they are defined in the imported library.
+   */
+  List<String> get shownNames;
+}
+
+/**
+ * A top-level variable.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TopLevelVariableElement implements PropertyInducingElement {
+  /**
+   * An empty list of top-level variable elements.
+   */
+  static const List<TopLevelVariableElement> EMPTY_LIST =
+      const <TopLevelVariableElement>[];
+
+  @override
+  VariableDeclaration computeNode();
+}
+
+/**
+ * An element that defines a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeDefiningElement implements Element {
+  /**
+   * Return the type defined by this element.
+   */
+  DartType get type;
+}
+
+/**
+ * A type parameter.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterElement implements TypeDefiningElement {
+  /**
+   * An empty list of type parameter elements.
+   */
+  static const List<TypeParameterElement> EMPTY_LIST =
+      const <TypeParameterElement>[];
+
+  /**
+   * Return the type representing the bound associated with this parameter, or
+   * `null` if this parameter does not have an explicit bound.
+   */
+  DartType get bound;
+
+  @override
+  TypeParameterType get type;
+}
+
+/**
+ * An element that has type parameters, such as a class or a typedef. This also
+ * includes functions and methods if support for generic methods is enabled.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterizedElement implements Element {
+  /**
+   * Return a list containing all of the type parameters declared by this
+   * element directly. This does not include type parameters that are declared
+   * by any enclosing elements.
+   */
+  List<TypeParameterElement> get typeParameters;
+}
+
+/**
+ * A pseudo-elements that represents names that are undefined. This situation is
+ * not allowed by the language, so objects implementing this interface always
+ * represent an error. As a result, most of the normal operations on elements do
+ * not make sense and will return useless results.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UndefinedElement implements Element {}
+
+/**
+ * An element included into a library using some URI.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UriReferencedElement implements Element {
+  /**
+   * Return the URI that is used to include this element into the enclosing
+   * library, or `null` if this is the defining compilation unit of a library.
+   */
+  String get uri;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node's URI, or `-1` for synthetic import.
+   */
+  int get uriEnd;
+
+  /**
+   * Return the offset of the URI in the file, or `-1` if this element is
+   * synthetic.
+   */
+  int get uriOffset;
+}
+
+/**
+ * A variable. There are more specific subclasses for more specific kinds of
+ * variables.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class VariableElement implements Element, ConstantEvaluationTarget {
+  /**
+   * An empty list of variable elements.
+   */
+  static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
+
+  /**
+   * Return a representation of the value of this variable.
+   *
+   * Return `null` if either this variable was not declared with the 'const'
+   * modifier or if the value of this variable could not be computed because of
+   * errors.
+   */
+  DartObject get constantValue;
+
+  /**
+   * Return `true` if this variable element did not have an explicit type
+   * specified for it.
+   */
+  bool get hasImplicitType;
+
+  /**
+   * Return a synthetic function representing this variable's initializer, or
+   * `null` if this variable does not have an initializer. The function will
+   * have no parameters. The return type of the function will be the
+   * compile-time type of the initialization expression.
+   */
+  FunctionElement get initializer;
+
+  /**
+   * Return `true` if this variable was declared with the 'const' modifier.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if this variable was declared with the 'final' modifier.
+   * Variables that are declared with the 'const' modifier will return `false`
+   * even though they are implicitly final.
+   */
+  bool get isFinal;
+
+  /**
+   * Return `true` if this variable is potentially mutated somewhere in a
+   * closure. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
+   */
+  bool get isPotentiallyMutatedInClosure;
+
+  /**
+   * Return `true` if this variable is potentially mutated somewhere in its
+   * scope. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
+   */
+  bool get isPotentiallyMutatedInScope;
+
+  /**
+   * Return `true` if this element is a static variable, as per section 8 of the
+   * Dart Language Specification:
+   *
+   * > A static variable is a variable that is not associated with a particular
+   * > instance, but rather with an entire library or class. Static variables
+   * > include library variables and class variables. Class variables are
+   * > variables whose declaration is immediately nested inside a class
+   * > declaration and includes the modifier static. A library variable is
+   * > implicitly static.
+   */
+  bool get isStatic;
+
+  /**
+   * Return the declared type of this variable, or `null` if the variable did
+   * not have a declared type (such as if it was declared using the keyword
+   * 'var').
+   */
+  DartType get type;
+}
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
new file mode 100644
index 0000000..49607dc
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -0,0 +1,627 @@
+// 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.dart.element.type;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
+
+/**
+ * The type associated with elements in the element model.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DartType {
+  /**
+   * An empty list of types.
+   */
+  static const List<DartType> EMPTY_LIST = const <DartType>[];
+
+  /**
+   * Return the name of this type as it should appear when presented to users in
+   * contexts such as error messages.
+   */
+  String get displayName;
+
+  /**
+   * Return the element representing the declaration of this type, or `null` if
+   * the type has not, or cannot, be associated with an element. The former case
+   * will occur if the element model is not yet complete; the latter case will
+   * occur if this object represents an undefined type.
+   */
+  Element get element;
+
+  /**
+   * Return `true` if this type represents the bottom type.
+   */
+  bool get isBottom;
+
+  /**
+   * Return `true` if this type represents the type 'Function' defined in the
+   * dart:core library.
+   */
+  bool get isDartCoreFunction;
+
+  /**
+   * Return `true` if this type represents the type 'dynamic'.
+   */
+  bool get isDynamic;
+
+  /**
+   * Return `true` if this type represents the type 'Object'.
+   */
+  bool get isObject;
+
+  /**
+   * Return `true` if this type represents a typename that couldn't be resolved.
+   */
+  bool get isUndefined;
+
+  /**
+   * Return `true` if this type represents the type 'void'.
+   */
+  bool get isVoid;
+
+  /**
+   * Return the name of this type, or `null` if the type does not have a name,
+   * such as when the type represents the type of an unnamed function.
+   */
+  String get name;
+
+  /**
+   * Return `true` if this type is assignable to the given [type]. A type
+   * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
+   * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
+   */
+  bool isAssignableTo(DartType type);
+
+  /**
+   * Return `true` if this type is more specific than the given [type].
+   */
+  bool isMoreSpecificThan(DartType type);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type].
+   */
+  bool isSubtypeOf(DartType type);
+
+  /**
+   * Return `true` if this type is a supertype of the given [type]. A type
+   * <i>S</i> is a supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff
+   * <i>T</i> is a subtype of <i>S</i>.
+   */
+  bool isSupertypeOf(DartType type);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * the given [parameterTypes] in this type. The specification defines this
+   * operation in section 2:
+   * <blockquote>
+   * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ...,
+   * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of
+   * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
+   * <i>x<sub>i</sub></i>.
+   * </blockquote>
+   * Note that, contrary to the specification, this method will not create a
+   * copy of this type if no substitutions were required, but will return this
+   * type directly.
+   *
+   * Note too that the current implementation of this method is only guaranteed
+   * to work when the parameter types are type variables.
+   */
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+}
+
+/**
+ * The type of a function, method, constructor, getter, or setter. Function
+ * types come in three variations:
+ *
+ * * The types of functions that only have required parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
+ * * The types of functions with optional positional parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
+ *   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
+ * * The types of functions with named parameters. These have the general form
+ *   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
+ *   T<sub>xk</sub> xk}) &rarr; T</i>.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionType implements ParameterizedType {
+  /**
+   * The type parameters of this generic function. For example `<T> T -> T`.
+   *
+   * These are distinct from the [typeParameters] list, which contains type
+   * parameters from surrounding contexts, and thus are free type variables from
+   * the perspective of this function type.
+   */
+  List<TypeParameterElement> get boundTypeParameters;
+
+  /**
+   * Return a map from the names of named parameters to the types of the named
+   * parameters of this type of function. The entries in the map will be
+   * iterated in the same order as the order in which the named parameters were
+   * defined. If there were no named parameters declared then the map will be
+   * empty.
+   */
+  Map<String, DartType> get namedParameterTypes;
+
+  /**
+   * Return a list containing the types of the normal parameters of this type of
+   * function. The parameter types are in the same order as they appear in the
+   * declaration of the function.
+   */
+  List<DartType> get normalParameterTypes;
+
+  /**
+   * 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
+   * optional parameters were defined. If there were no optional parameters
+   * declared then the map will be empty.
+   */
+  List<DartType> get optionalParameterTypes;
+
+  /**
+   * 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.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return the type of object returned by this type of function.
+   */
+  DartType get returnType;
+
+  /**
+   * Return the type resulting from instantiating (replacing) the given
+   * [argumentTypes] for this function's bound type parameters.
+   */
+  FunctionType instantiate(List<DartType> argumentTypes);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type].
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
+   * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
+   * &rarr; S</i>, if all of the following conditions are met:
+   *
+   * * Either
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr; T</i> is a subtype of
+   * the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
+   * following conditions are met:
+   *
+   * * Either
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
+   *
+   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>,
+   *   <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i> is a subtype
+   * of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of
+   * the following conditions are met:
+   * * Either
+   *   * <i>S</i> is void,
+   *   * or <i>T &hArr; S</i>.
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>,
+   *   &hellip;, x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
+   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;,
+   *   y<sub>m</sub>}</i>, <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
+   *
+   * In addition, the following subtype rules apply:
+   *
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, {}) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, []) &rarr; T.</i>
+   *
+   * All functions implement the class `Function`. However not all function
+   * types are a subtype of `Function`. If an interface type <i>I</i> includes a
+   * method named `call()`, and the type of `call()` is the function type
+   * <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
+   */
+  @override
+  bool isSubtypeOf(DartType type);
+
+  @override
+  FunctionType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * this type's parameters. This is fully equivalent to
+   * `substitute(argumentTypes, getTypeArguments())`.
+   */
+  @deprecated // use instantiate
+  FunctionType substitute3(List<DartType> argumentTypes);
+}
+
+/**
+ * The type introduced by either a class or an interface, or a reference to such
+ * a type.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InterfaceType implements ParameterizedType {
+  /**
+   * An empty list of types.
+   */
+  static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
+
+  /**
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this type.
+   */
+  List<PropertyAccessorElement> get accessors;
+
+  /**
+   * Return a list containing all of the constructors declared in this type.
+   */
+  List<ConstructorElement> get constructors;
+
+  @override
+  ClassElement get element;
+
+  /**
+   * Return a list containing all of the interfaces that are implemented by this
+   * interface. Note that this is <b>not</b>, in general, equivalent to getting
+   * the interfaces from this type's element because the types returned by this
+   * method will have had their type parameters replaced.
+   */
+  List<InterfaceType> get interfaces;
+
+  /**
+   * Return a list containing all of the methods declared in this type.
+   */
+  List<MethodElement> get methods;
+
+  /**
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class. Note that
+   * this is <b>not</b>, in general, equivalent to getting the mixins from this
+   * type's element because the types returned by this method will have had
+   * their type parameters replaced.
+   */
+  List<InterfaceType> get mixins;
+
+  /**
+   * Return the type representing the superclass of this type, or null if this
+   * type represents the class 'Object'. Note that this is <b>not</b>, in
+   * general, equivalent to getting the superclass from this type's element
+   * because the type returned by this method will have had it's type parameters
+   * replaced.
+   */
+  InterfaceType get superclass;
+
+  /**
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
+   */
+  PropertyAccessorElement getGetter(String name);
+
+  /**
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
+   */
+  MethodElement getMethod(String name);
+
+  /**
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
+   */
+  PropertyAccessorElement getSetter(String name);
+
+  /**
+   * Return `true` if this type is a direct supertype of the given [type]. The
+   * implicit interface of class <i>I</i> is a direct supertype of the implicit
+   * interface of class <i>J</i> iff:
+   *
+   * * <i>I</i> is Object, and <i>J</i> has no extends clause.
+   * * <i>I</i> is listed in the extends clause of <i>J</i>.
+   * * <i>I</i> is listed in the implements clause of <i>J</i>.
+   * * <i>I</i> is listed in the with clause of <i>J</i>.
+   * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
+   */
+  bool isDirectSupertypeOf(InterfaceType type);
+
+  /**
+   * Return `true` if this type is more specific than the given [type]. An
+   * interface type <i>T</i> is more specific than an interface type <i>S</i>,
+   * written <i>T &laquo; S</i>, if one of the following conditions is met:
+   *
+   * * Reflexivity: <i>T</i> is <i>S</i>.
+   * * <i>T</i> is bottom.
+   * * <i>S</i> is dynamic.
+   * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
+   * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
+   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
+   *   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
+   *   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
+   *   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
+   * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
+   */
+  @override
+  bool isMoreSpecificThan(DartType type);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type]. An interface
+   * type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
+   * <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
+   * more specific than <i>S</i>). If an interface type <i>I</i> includes a
+   * method named <i>call()</i>, and the type of <i>call()</i> is the function
+   * type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
+   */
+  @override
+  bool isSubtypeOf(DartType type);
+
+  /**
+   * Return the element representing the constructor that results from looking
+   * up the constructor with the given [name] in this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 12.11.1:
+   * <blockquote>
+   * If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be the
+   * constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>.
+   * Otherwise, if <i>q</i> is not defined or not accessible, a
+   * NoSuchMethodException is thrown.
+   * </blockquote>
+   */
+  ConstructorElement lookUpConstructor(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpGetterInSuperclass(
+      String name, LibraryElement library);
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, starting from this type. If the search fails,
+   * search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Look up the member with the given [name] in this type and all extended
+   * and mixed in classes, and by default including [thisType]. If the search
+   * fails, this will then search interfaces.
+   *
+   * Return the element representing the member that was found, or `null` if
+   * there is no getter with the given name.
+   *
+   * The [library] determines if a private member name is visible, and does not
+   * need to be supplied for public names.
+   */
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true});
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   *   <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   *   result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>
+   *   Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethod(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   * result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>.
+   * Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  MethodElement lookUpMethodInSuperclass(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
+   */
+  PropertyAccessorElement lookUpSetterInSuperclass(
+      String name, LibraryElement library);
+
+  @override
+  InterfaceType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+
+  /**
+   * Return the type resulting from substituting the given arguments for this
+   * type's parameters. This is fully equivalent to `substitute2(argumentTypes,
+   * getTypeArguments())`.
+   */
+  // TODO(jmesserly): introduce a new "instantiate" and deprecate this.
+  // The new "instantiate" should work similar to FunctionType.instantiate,
+  // which uses [boundTypeParameters] to model type parameters that haven't been
+  // filled in yet. Those are kept separate from already-substituted type
+  // parameters or free variables from the enclosing scopes, which allows nested
+  // generics to work, such as a generic method in a generic class.
+  InterfaceType substitute4(List<DartType> argumentTypes);
+
+  /**
+   * Returns a "smart" version of the "least upper bound" of the given types.
+   *
+   * If these types have the same element and differ only in terms of the type
+   * arguments, attempts to find a compatible set of type arguments.
+   *
+   * Otherwise, returns the same result as [DartType.getLeastUpperBound].
+   */
+  // TODO(brianwilkerson) This needs to be deprecated and moved to TypeSystem.
+  static InterfaceType getSmartLeastUpperBound(
+          InterfaceType first, InterfaceType second) =>
+      InterfaceTypeImpl.getSmartLeastUpperBound(first, second);
+}
+
+/**
+ * A type with type parameters, such as a class or function type alias.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ParameterizedType implements DartType {
+  /**
+   * Return a list containing the actual types of the type arguments. If this
+   * type's element does not have type parameters, then the array should be
+   * empty (although it is possible for type arguments to be erroneously
+   * declared). If the element has type parameters and the actual type does not
+   * explicitly include argument values, then the type "dynamic" will be
+   * automatically provided.
+   */
+  List<DartType> get typeArguments;
+
+  /**
+   * Return a list containing all of the type parameters declared for this type.
+   */
+  List<TypeParameterElement> get typeParameters;
+}
+
+/**
+ * The type introduced by a type parameter.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterType implements DartType {
+  /**
+   * An empty list of type parameter types.
+   */
+  static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
+
+  @override
+  TypeParameterElement get element;
+}
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
new file mode 100644
index 0000000..4a5f393
--- /dev/null
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -0,0 +1,356 @@
+// 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.dart.element.visitor;
+
+import 'package:analyzer/dart/element/element.dart';
+
+/**
+ * An element visitor that will recursively visit all of the elements in an
+ * element model (like instances of the class [RecursiveElementVisitor]). In
+ * addition, when an element of a specific type is visited not only will the
+ * visit method for that specific type of element be invoked, but additional
+ * methods for the supertypes of that element will also be invoked. For example,
+ * using an instance of this class to visit a [MethodElement] will cause the
+ * method [visitMethodElement] to be invoked but will also cause the methods
+ * [visitExecutableElement] and [visitElement] to be subsequently invoked. This
+ * allows visitors to be written that visit all executable elements without
+ * needing to override the visit method for each of the specific subclasses of
+ * [ExecutableElement].
+ *
+ * Note, however, that unlike many visitors, element visitors visit objects
+ * based on the interfaces implemented by those elements. Because interfaces
+ * form a graph structure rather than a tree structure the way classes do, and
+ * because it is generally undesirable for an object to be visited more than
+ * once, this class flattens the interface graph into a pseudo-tree. In
+ * particular, this class treats elements as if the element types were
+ * structured in the following way:
+ *
+ * <pre>
+ * Element
+ *   ClassElement
+ *   CompilationUnitElement
+ *   ExecutableElement
+ *       ConstructorElement
+ *       LocalElement
+ *           FunctionElement
+ *       MethodElement
+ *       PropertyAccessorElement
+ *   ExportElement
+ *   HtmlElement
+ *   ImportElement
+ *   LabelElement
+ *   LibraryElement
+ *   MultiplyDefinedElement
+ *   PrefixElement
+ *   TypeAliasElement
+ *   TypeParameterElement
+ *   UndefinedElement
+ *   VariableElement
+ *       PropertyInducingElement
+ *           FieldElement
+ *           TopLevelVariableElement
+ *       LocalElement
+ *           LocalVariableElement
+ *           ParameterElement
+ *               FieldFormalParameterElement
+ * </pre>
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general visit method. Failure to
+ * do so will cause the visit methods for superclasses of the element to not be
+ * invoked and will cause the children of the visited node to not be visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) => visitElement(element);
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) =>
+      visitElement(element);
+
+  @override
+  R visitConstructorElement(ConstructorElement element) =>
+      visitExecutableElement(element);
+
+  R visitElement(Element element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  R visitExecutableElement(ExecutableElement element) => visitElement(element);
+
+  @override
+  R visitExportElement(ExportElement element) => visitElement(element);
+
+  @override
+  R visitFieldElement(FieldElement element) =>
+      visitPropertyInducingElement(element);
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
+      visitParameterElement(element);
+
+  @override
+  R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
+      visitElement(element);
+
+  @override
+  R visitImportElement(ImportElement element) => visitElement(element);
+
+  @override
+  R visitLabelElement(LabelElement element) => visitElement(element);
+
+  @override
+  R visitLibraryElement(LibraryElement element) => visitElement(element);
+
+  R visitLocalElement(LocalElement element) {
+    if (element is LocalVariableElement) {
+      return visitVariableElement(element);
+    } else if (element is ParameterElement) {
+      return visitVariableElement(element);
+    } else if (element is FunctionElement) {
+      return visitExecutableElement(element);
+    }
+    return null;
+  }
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) =>
+      visitLocalElement(element);
+
+  @override
+  R visitMethodElement(MethodElement element) =>
+      visitExecutableElement(element);
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
+      visitElement(element);
+
+  @override
+  R visitParameterElement(ParameterElement element) =>
+      visitLocalElement(element);
+
+  @override
+  R visitPrefixElement(PrefixElement element) => visitElement(element);
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) =>
+      visitExecutableElement(element);
+
+  R visitPropertyInducingElement(PropertyInducingElement element) =>
+      visitVariableElement(element);
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) =>
+      visitPropertyInducingElement(element);
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) =>
+      visitElement(element);
+
+  R visitVariableElement(VariableElement element) => visitElement(element);
+}
+
+/**
+ * A visitor that will recursively visit all of the element in an element model.
+ * For example, using an instance of this class to visit a
+ * [CompilationUnitElement] will also cause all of the types in the compilation
+ * unit to be visited.
+ *
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or must explicitly ask the visited element to visit its
+ * children. Failure to do so will cause the children of the visited element to
+ * not be visited.
+ *
+ * Clients may extend or implement this class.
+ */
+class RecursiveElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitConstructorElement(ConstructorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitExportElement(ExportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldElement(FieldElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionElement(FunctionElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitImportElement(ImportElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLabelElement(LabelElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLibraryElement(LibraryElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMethodElement(MethodElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitParameterElement(ParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPrefixElement(PrefixElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+}
+
+/**
+ * A visitor that will do nothing when visiting an element. It is intended to be
+ * a superclass for classes that use the visitor pattern primarily as a dispatch
+ * mechanism (and hence don't need to recursively visit a whole structure) and
+ * that only need to visit a small number of element types.
+ *
+ * Clients may extend or implement this class.
+ */
+class SimpleElementVisitor<R> implements ElementVisitor<R> {
+  @override
+  R visitClassElement(ClassElement element) => null;
+
+  @override
+  R visitCompilationUnitElement(CompilationUnitElement element) => null;
+
+  @override
+  R visitConstructorElement(ConstructorElement element) => null;
+
+  @override
+  R visitExportElement(ExportElement element) => null;
+
+  @override
+  R visitFieldElement(FieldElement element) => null;
+
+  @override
+  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
+      null;
+
+  @override
+  R visitFunctionElement(FunctionElement element) => null;
+
+  @override
+  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
+
+  @override
+  R visitImportElement(ImportElement element) => null;
+
+  @override
+  R visitLabelElement(LabelElement element) => null;
+
+  @override
+  R visitLibraryElement(LibraryElement element) => null;
+
+  @override
+  R visitLocalVariableElement(LocalVariableElement element) => null;
+
+  @override
+  R visitMethodElement(MethodElement element) => null;
+
+  @override
+  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
+
+  @override
+  R visitParameterElement(ParameterElement element) => null;
+
+  @override
+  R visitPrefixElement(PrefixElement element) => null;
+
+  @override
+  R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
+
+  @override
+  R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
+
+  @override
+  R visitTypeParameterElement(TypeParameterElement element) => null;
+}
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 6c4048c..1c96ef0 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -311,7 +311,7 @@
       print('Please regenerate using:');
       String executable = Platform.executable;
       String packageRoot = '';
-      if (Platform.packageRoot.isNotEmpty) {
+      if (Platform.packageRoot != null) {
         packageRoot = ' --package-root=${Platform.packageRoot}';
       }
       String generateScript =
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 7c2971a..c9604ef 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -7,14 +7,15 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/task.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_resolver.dart';
@@ -557,22 +558,8 @@
   }
 
   @override
-  String computeDocumentationComment(Element element) {
-    if (element == null) {
-      return null;
-    }
-    Source source = element.source;
-    if (source == null) {
-      return null;
-    }
-    SourceRange docRange = element.docRange;
-    if (docRange == null) {
-      return null;
-    }
-    String code = getContents(source).data;
-    String comment = code.substring(docRange.offset, docRange.end);
-    return comment.replaceAll('\r\n', '\n');
-  }
+  String computeDocumentationComment(Element element) =>
+      element?.documentationComment;
 
   @override
   List<AnalysisError> computeErrors(Source source) {
@@ -1093,6 +1080,7 @@
       setValue(LIBRARY_ELEMENT5, library);
       setValue(LIBRARY_ELEMENT6, library);
       setValue(LIBRARY_ELEMENT7, library);
+      setValue(LIBRARY_ELEMENT8, library);
       setValue(LINE_INFO, new LineInfo(<int>[0]));
       setValue(PARSE_ERRORS, AnalysisError.NO_ERRORS);
       entry.setState(PARSED_UNIT, CacheState.FLUSHED);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
new file mode 100644
index 0000000..ff39868
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -0,0 +1,4585 @@
+// 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.element;
+
+import 'dart:collection';
+import 'dart:math' show min;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+
+/**
+ * For AST nodes that could be in both the getter and setter contexts
+ * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
+ * elements are stored in the AST node, in an [AuxiliaryElements]. Because
+ * resolved elements are either statically resolved or resolved using propagated
+ * type information, this class is a wrapper for a pair of [ExecutableElement]s,
+ * not just a single [ExecutableElement].
+ */
+class AuxiliaryElements {
+  /**
+   * The element based on propagated type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
+   */
+  final ExecutableElement propagatedElement;
+
+  /**
+   * The element based on static type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
+   */
+  final ExecutableElement staticElement;
+
+  /**
+   * Initialize a newly created pair to have both the [staticElement] and the
+   * [propagatedElement].
+   */
+  AuxiliaryElements(this.staticElement, this.propagatedElement);
+}
+
+/**
+ * A concrete implementation of a [ClassElement].
+ */
+class ClassElementImpl extends ElementImpl implements ClassElement {
+  /**
+   * A list containing all of the accessors (getters and setters) contained in
+   * this class.
+   */
+  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
+
+  /**
+   * For classes which are not mixin applications, a list containing all of the
+   * constructors contained in this class, or `null` if the list of
+   * constructors has not yet been built.
+   *
+   * For classes which are mixin applications, the list of constructors is
+   * computed on the fly by the [constructors] getter, and this field is
+   * `null`.
+   */
+  List<ConstructorElement> _constructors;
+
+  /**
+   * A list containing all of the fields contained in this class.
+   */
+  List<FieldElement> _fields = FieldElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the mixins that are applied to the class being
+   * extended in order to derive the superclass of this class.
+   */
+  List<InterfaceType> mixins = InterfaceType.EMPTY_LIST;
+
+  /**
+   * A list containing all of the interfaces that are implemented by this class.
+   */
+  List<InterfaceType> interfaces = InterfaceType.EMPTY_LIST;
+
+  /**
+   * A list containing all of the methods contained in this class.
+   */
+  List<MethodElement> _methods = MethodElement.EMPTY_LIST;
+
+  /**
+   * The superclass of the class, or `null` if the class does not have an
+   * explicit superclass.
+   */
+  InterfaceType supertype;
+
+  /**
+   * The type defined by the class.
+   */
+  InterfaceType type;
+
+  /**
+   * A list containing all of the type parameters defined for this class.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The [SourceRange] of the `with` clause, `null` if there is no one.
+   */
+  SourceRange withClauseRange;
+
+  /**
+   * A flag indicating whether the types associated with the instance members of
+   * this class have been inferred.
+   */
+  bool hasBeenInferred = false;
+
+  /**
+   * Initialize a newly created class element to have the given [name] at the
+   * given [offset] in the file that contains the declaration of this element.
+   */
+  ClassElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created class element to have the given [name].
+   */
+  ClassElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this class is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  List<PropertyAccessorElement> get accessors => _accessors;
+
+  /**
+   * Set the accessors contained in this class to the given [accessors].
+   */
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
+      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+    }
+    this._accessors = accessors;
+  }
+
+  @override
+  List<InterfaceType> get allSupertypes {
+    List<InterfaceType> list = new List<InterfaceType>();
+    _collectAllSupertypes(list);
+    return list;
+  }
+
+  @override
+  List<ConstructorElement> get constructors {
+    if (!isMixinApplication) {
+      assert(_constructors != null);
+      return _constructors == null
+          ? ConstructorElement.EMPTY_LIST
+          : _constructors;
+    }
+
+    return _computeMixinAppConstructors();
+  }
+
+  /**
+   * Set the constructors contained in this class to the given [constructors].
+   *
+   * Should only be used for class elements that are not mixin applications.
+   */
+  void set constructors(List<ConstructorElement> constructors) {
+    assert(!isMixinApplication);
+    for (ConstructorElement constructor in constructors) {
+      (constructor as ConstructorElementImpl).enclosingElement = this;
+    }
+    this._constructors = constructors;
+  }
+
+  /**
+   * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
+   * be reported for this class.
+   */
+  bool get doesMixinLackConstructors {
+    if (!isMixinApplication && mixins.isEmpty) {
+      // This class is not a mixin application and it doesn't have a "with"
+      // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
+      // inapplicable.
+      return false;
+    }
+    if (supertype == null) {
+      // Should never happen, since Object is the only class that has no
+      // supertype, and it should have been caught by the test above.
+      assert(false);
+      return false;
+    }
+    // Find the nearest class in the supertype chain that is not a mixin
+    // application.
+    ClassElement nearestNonMixinClass = supertype.element;
+    if (nearestNonMixinClass.isMixinApplication) {
+      // Use a list to keep track of the classes we've seen, so that we won't
+      // go into an infinite loop in the event of a non-trivial loop in the
+      // class hierarchy.
+      List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
+      while (nearestNonMixinClass.isMixinApplication) {
+        if (classesSeen.contains(nearestNonMixinClass)) {
+          // Loop in the class hierarchy (which is reported elsewhere).  Don't
+          // confuse the user with further errors.
+          return false;
+        }
+        classesSeen.add(nearestNonMixinClass);
+        if (nearestNonMixinClass.supertype == null) {
+          // Should never happen, since Object is the only class that has no
+          // supertype, and it is not a mixin application.
+          assert(false);
+          return false;
+        }
+        nearestNonMixinClass = nearestNonMixinClass.supertype.element;
+      }
+    }
+    return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
+  }
+
+  /**
+   * Set whether this class is defined by an enum declaration.
+   */
+  void set enum2(bool isEnum) {
+    setModifier(Modifier.ENUM, isEnum);
+  }
+
+  @override
+  List<FieldElement> get fields => _fields;
+
+  /**
+   * Set the fields contained in this class to the given [fields].
+   */
+  void set fields(List<FieldElement> fields) {
+    for (FieldElement field in fields) {
+      (field as FieldElementImpl).enclosingElement = this;
+    }
+    this._fields = fields;
+  }
+
+  @override
+  bool get hasNonFinalField {
+    List<ClassElement> classesToVisit = new List<ClassElement>();
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    classesToVisit.add(this);
+    while (!classesToVisit.isEmpty) {
+      ClassElement currentElement = classesToVisit.removeAt(0);
+      if (visitedClasses.add(currentElement)) {
+        // check fields
+        for (FieldElement field in currentElement.fields) {
+          if (!field.isFinal &&
+              !field.isConst &&
+              !field.isStatic &&
+              !field.isSynthetic) {
+            return true;
+          }
+        }
+        // check mixins
+        for (InterfaceType mixinType in currentElement.mixins) {
+          ClassElement mixinElement = mixinType.element;
+          classesToVisit.add(mixinElement);
+        }
+        // check super
+        InterfaceType supertype = currentElement.supertype;
+        if (supertype != null) {
+          ClassElement superElement = supertype.element;
+          if (superElement != null) {
+            classesToVisit.add(superElement);
+          }
+        }
+      }
+    }
+    // not found
+    return false;
+  }
+
+  @override
+  bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
+
+  /**
+   * Set whether this class references 'super'.
+   */
+  void set hasReferenceToSuper(bool isReferencedSuper) {
+    setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
+  }
+
+  @override
+  bool get hasStaticMember {
+    for (MethodElement method in _methods) {
+      if (method.isStatic) {
+        return true;
+      }
+    }
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isStatic) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+
+  @override
+  bool get isEnum => hasModifier(Modifier.ENUM);
+
+  @override
+  bool get isMixinApplication => hasModifier(Modifier.MIXIN_APPLICATION);
+
+  @override
+  bool get isOrInheritsProxy =>
+      _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
+
+  @override
+  bool get isProxy {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isProxy) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isValidMixin => hasModifier(Modifier.MIXIN);
+
+  @override
+  ElementKind get kind => ElementKind.CLASS;
+
+  @override
+  List<MethodElement> get methods => _methods;
+
+  /**
+   * Set the methods contained in this class to the given [methods].
+   */
+  void set methods(List<MethodElement> methods) {
+    for (MethodElement method in methods) {
+      (method as MethodElementImpl).enclosingElement = this;
+    }
+    this._methods = methods;
+  }
+
+  /**
+   * Set whether this class is a mixin application.
+   */
+  void set mixinApplication(bool isMixinApplication) {
+    setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined for this class to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  ConstructorElement get unnamedConstructor {
+    for (ConstructorElement element in constructors) {
+      String name = element.displayName;
+      if (name == null || name.isEmpty) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Set whether this class is a valid mixin.
+   */
+  void set validMixin(bool isValidMixin) {
+    setModifier(Modifier.MIXIN, isValidMixin);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitClassElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (isAbstract) {
+      buffer.write('abstract ');
+    }
+    if (isEnum) {
+      buffer.write('enum ');
+    } else {
+      buffer.write('class ');
+    }
+    String name = displayName;
+    if (name == null) {
+      buffer.write("{unnamed class}");
+    } else {
+      buffer.write(name);
+    }
+    int variableCount = _typeParameters.length;
+    if (variableCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < variableCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+    if (supertype != null && !supertype.isObject) {
+      buffer.write(' extends ');
+      buffer.write(supertype.displayName);
+    }
+    if (mixins.isNotEmpty) {
+      buffer.write(' with ');
+      buffer.write(mixins.map((t) => t.displayName).join(', '));
+    }
+    if (interfaces.isNotEmpty) {
+      buffer.write(' implements ');
+      buffer.write(interfaces.map((t) => t.displayName).join(', '));
+    }
+  }
+
+  @override
+  NamedCompilationUnitMember computeNode() {
+    if (isEnum) {
+      return getNodeMatching((node) => node is EnumDeclaration);
+    } else {
+      return getNodeMatching(
+          (node) => node is ClassDeclaration || node is ClassTypeAlias);
+    }
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have
+    // thrown a CCE if any of the elements in the arrays were not of the
+    // expected types.
+    //
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (ConstructorElement constructor in _constructors) {
+      if ((constructor as ConstructorElementImpl).identifier == identifier) {
+        return constructor as ConstructorElementImpl;
+      }
+    }
+    for (FieldElement field in _fields) {
+      if ((field as FieldElementImpl).identifier == identifier) {
+        return field as FieldElementImpl;
+      }
+    }
+    for (MethodElement method in _methods) {
+      if ((method as MethodElementImpl).identifier == identifier) {
+        return method as MethodElementImpl;
+      }
+    }
+    for (TypeParameterElement typeParameter in _typeParameters) {
+      if ((typeParameter as TypeParameterElementImpl).identifier ==
+          identifier) {
+        return typeParameter as TypeParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  FieldElement getField(String name) {
+    for (FieldElement fieldElement in _fields) {
+      if (name == fieldElement.name) {
+        return fieldElement;
+      }
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement getGetter(String getterName) {
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isGetter && accessor.name == getterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+
+  @override
+  MethodElement getMethod(String methodName) {
+    for (MethodElement method in _methods) {
+      if (method.name == methodName) {
+        return method;
+      }
+    }
+    return null;
+  }
+
+  @override
+  ConstructorElement getNamedConstructor(String name) {
+    for (ConstructorElement element in constructors) {
+      String elementName = element.name;
+      if (elementName != null && elementName == name) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement getSetter(String setterName) {
+    // TODO (jwren) revisit- should we append '=' here or require clients to
+    // include it?
+    // Do we need the check for isSetter below?
+    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
+      setterName += '=';
+    }
+    for (PropertyAccessorElement accessor in _accessors) {
+      if (accessor.isSetter && accessor.name == setterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
+
+  @override
+  bool isSuperConstructorAccessible(ConstructorElement constructor) {
+    // If this class has no mixins, then all superclass constructors are
+    // accessible.
+    if (mixins.isEmpty) {
+      return true;
+    }
+    // Otherwise only constructors that lack optional parameters are
+    // accessible (see dartbug.com/19576).
+    for (ParameterElement parameter in constructor.parameters) {
+      if (parameter.parameterKind != ParameterKind.REQUIRED) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  MethodElement lookUpConcreteMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpConcreteMethod(methodName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpGetter(
+          String getterName, LibraryElement library) =>
+      _internalLookUpGetter(getterName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpInheritedConcreteGetter(
+          String getterName, LibraryElement library) =>
+      _internalLookUpConcreteGetter(getterName, library, false);
+
+  @override
+  MethodElement lookUpInheritedConcreteMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpConcreteMethod(methodName, library, false);
+
+  @override
+  PropertyAccessorElement lookUpInheritedConcreteSetter(
+          String setterName, LibraryElement library) =>
+      _internalLookUpConcreteSetter(setterName, library, false);
+
+  @override
+  MethodElement lookUpInheritedMethod(
+          String methodName, LibraryElement library) =>
+      _internalLookUpMethod(methodName, library, false);
+
+  @override
+  MethodElement lookUpMethod(String methodName, LibraryElement library) =>
+      _internalLookUpMethod(methodName, library, true);
+
+  @override
+  PropertyAccessorElement lookUpSetter(
+          String setterName, LibraryElement library) =>
+      _internalLookUpSetter(setterName, library, true);
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_constructors, visitor);
+    safelyVisitChildren(_fields, visitor);
+    safelyVisitChildren(_methods, visitor);
+    safelyVisitChildren(_typeParameters, visitor);
+  }
+
+  void _collectAllSupertypes(List<InterfaceType> supertypes) {
+    List<InterfaceType> typesToVisit = new List<InterfaceType>();
+    List<ClassElement> visitedClasses = new List<ClassElement>();
+    typesToVisit.add(this.type);
+    while (!typesToVisit.isEmpty) {
+      InterfaceType currentType = typesToVisit.removeAt(0);
+      ClassElement currentElement = currentType.element;
+      if (!visitedClasses.contains(currentElement)) {
+        visitedClasses.add(currentElement);
+        if (!identical(currentType, this.type)) {
+          supertypes.add(currentType);
+        }
+        InterfaceType supertype = currentType.superclass;
+        if (supertype != null) {
+          typesToVisit.add(supertype);
+        }
+        for (InterfaceType type in currentElement.interfaces) {
+          typesToVisit.add(type);
+        }
+        for (InterfaceType type in currentElement.mixins) {
+          ClassElement element = type.element;
+          if (!visitedClasses.contains(element)) {
+            supertypes.add(type);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Compute a list of constructors for this class, which is a mixin
+   * application.  If specified, [visitedClasses] is a list of the other mixin
+   * application classes which have been visited on the way to reaching this
+   * one (this is used to detect circularities).
+   */
+  List<ConstructorElement> _computeMixinAppConstructors(
+      [List<ClassElementImpl> visitedClasses = null]) {
+    // First get the list of constructors of the superclass which need to be
+    // forwarded to this class.
+    Iterable<ConstructorElement> constructorsToForward;
+    if (supertype == null) {
+      // Shouldn't ever happen, since the only class with no supertype is
+      // Object, and it isn't a mixin application.  But for safety's sake just
+      // assume an empty list.
+      assert(false);
+      constructorsToForward = <ConstructorElement>[];
+    } else if (!supertype.element.isMixinApplication) {
+      List<ConstructorElement> superclassConstructors =
+          supertype.element.constructors;
+      // Filter out any constructors with optional parameters (see
+      // dartbug.com/15101).
+      constructorsToForward =
+          superclassConstructors.where(isSuperConstructorAccessible);
+    } else {
+      if (visitedClasses == null) {
+        visitedClasses = <ClassElementImpl>[this];
+      } else {
+        if (visitedClasses.contains(this)) {
+          // Loop in the class hierarchy.  Don't try to forward any
+          // constructors.
+          return <ConstructorElement>[];
+        }
+        visitedClasses.add(this);
+      }
+      try {
+        ClassElementImpl superclass = supertype.element;
+        constructorsToForward =
+            superclass._computeMixinAppConstructors(visitedClasses);
+      } finally {
+        visitedClasses.removeLast();
+      }
+    }
+
+    // Figure out the type parameter substitution we need to perform in order
+    // to produce constructors for this class.  We want to be robust in the
+    // face of errors, so drop any extra type arguments and fill in any missing
+    // ones with `dynamic`.
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(supertype.typeParameters);
+    List<DartType> argumentTypes = new List<DartType>.filled(
+        parameterTypes.length, DynamicTypeImpl.instance);
+    for (int i = 0; i < supertype.typeArguments.length; i++) {
+      if (i >= argumentTypes.length) {
+        break;
+      }
+      argumentTypes[i] = supertype.typeArguments[i];
+    }
+
+    // Now create an implicit constructor for every constructor found above,
+    // substituting type parameters as appropriate.
+    return constructorsToForward
+        .map((ConstructorElement superclassConstructor) {
+      ConstructorElementImpl implicitConstructor =
+          new ConstructorElementImpl(superclassConstructor.name, -1);
+      implicitConstructor.synthetic = true;
+      implicitConstructor.redirectedConstructor = superclassConstructor;
+      implicitConstructor.const2 = superclassConstructor.isConst;
+      implicitConstructor.returnType = type;
+      List<ParameterElement> superParameters = superclassConstructor.parameters;
+      int count = superParameters.length;
+      if (count > 0) {
+        List<ParameterElement> implicitParameters =
+            new List<ParameterElement>(count);
+        for (int i = 0; i < count; i++) {
+          ParameterElement superParameter = superParameters[i];
+          ParameterElementImpl implicitParameter =
+              new ParameterElementImpl(superParameter.name, -1);
+          implicitParameter.const3 = superParameter.isConst;
+          implicitParameter.final2 = superParameter.isFinal;
+          implicitParameter.parameterKind = superParameter.parameterKind;
+          implicitParameter.synthetic = true;
+          implicitParameter.type =
+              superParameter.type.substitute2(argumentTypes, parameterTypes);
+          implicitParameters[i] = implicitParameter;
+        }
+        implicitConstructor.parameters = implicitParameters;
+      }
+      implicitConstructor.enclosingElement = this;
+      implicitConstructor.type = new FunctionTypeImpl(implicitConstructor);
+      return implicitConstructor;
+    }).toList();
+  }
+
+  PropertyAccessorElement _internalLookUpConcreteGetter(
+      String getterName, LibraryElement library, bool includeThisClass) {
+    PropertyAccessorElement getter =
+        _internalLookUpGetter(getterName, library, includeThisClass);
+    while (getter != null && getter.isAbstract) {
+      Element definingClass = getter.enclosingElement;
+      if (definingClass is! ClassElementImpl) {
+        return null;
+      }
+      getter = (definingClass as ClassElementImpl)
+          ._internalLookUpGetter(getterName, library, false);
+    }
+    return getter;
+  }
+
+  MethodElement _internalLookUpConcreteMethod(
+      String methodName, LibraryElement library, bool includeThisClass) {
+    MethodElement method =
+        _internalLookUpMethod(methodName, library, includeThisClass);
+    while (method != null && method.isAbstract) {
+      ClassElement definingClass = method.enclosingElement;
+      if (definingClass == null) {
+        return null;
+      }
+      method = definingClass.lookUpInheritedMethod(methodName, library);
+    }
+    return method;
+  }
+
+  PropertyAccessorElement _internalLookUpConcreteSetter(
+      String setterName, LibraryElement library, bool includeThisClass) {
+    PropertyAccessorElement setter =
+        _internalLookUpSetter(setterName, library, includeThisClass);
+    while (setter != null && setter.isAbstract) {
+      Element definingClass = setter.enclosingElement;
+      if (definingClass is! ClassElementImpl) {
+        return null;
+      }
+      setter = (definingClass as ClassElementImpl)
+          ._internalLookUpSetter(setterName, library, false);
+    }
+    return setter;
+  }
+
+  PropertyAccessorElement _internalLookUpGetter(
+      String getterName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      PropertyAccessorElement element = currentElement.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          PropertyAccessorElement element = mixinElement.getGetter(getterName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      PropertyAccessorElement element = currentElement.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  MethodElement _internalLookUpMethod(
+      String methodName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      MethodElement element = currentElement.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          MethodElement element = mixinElement.getMethod(methodName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      MethodElement element = currentElement.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  PropertyAccessorElement _internalLookUpSetter(
+      String setterName, LibraryElement library, bool includeThisClass) {
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    ClassElement currentElement = this;
+    if (includeThisClass) {
+      PropertyAccessorElement element = currentElement.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    while (currentElement != null && visitedClasses.add(currentElement)) {
+      for (InterfaceType mixin in currentElement.mixins.reversed) {
+        ClassElement mixinElement = mixin.element;
+        if (mixinElement != null) {
+          PropertyAccessorElement element = mixinElement.getSetter(setterName);
+          if (element != null && element.isAccessibleIn(library)) {
+            return element;
+          }
+        }
+      }
+      InterfaceType supertype = currentElement.supertype;
+      if (supertype == null) {
+        return null;
+      }
+      currentElement = supertype.element;
+      PropertyAccessorElement element = currentElement.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  bool _safeIsOrInheritsProxy(
+      ClassElement classElt, HashSet<ClassElement> visitedClassElts) {
+    if (visitedClassElts.contains(classElt)) {
+      return false;
+    }
+    visitedClassElts.add(classElt);
+    if (classElt.isProxy) {
+      return true;
+    } else if (classElt.supertype != null &&
+        _safeIsOrInheritsProxy(classElt.supertype.element, visitedClassElts)) {
+      return true;
+    }
+    List<InterfaceType> supertypes = classElt.interfaces;
+    for (int i = 0; i < supertypes.length; i++) {
+      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
+        return true;
+      }
+    }
+    supertypes = classElt.mixins;
+    for (int i = 0; i < supertypes.length; i++) {
+      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * A concrete implementation of a [CompilationUnitElement].
+ */
+class CompilationUnitElementImpl extends UriReferencedElementImpl
+    implements CompilationUnitElement {
+  /**
+   * The source that corresponds to this compilation unit.
+   */
+  Source source;
+
+  /**
+   * The source of the library containing this compilation unit.
+   *
+   * This is the same as the source of the containing [LibraryElement],
+   * except that it does not require the containing [LibraryElement] to be
+   * computed.
+   */
+  Source librarySource;
+
+  /**
+   * A list containing all of the top-level accessors (getters and setters)
+   * contained in this compilation unit.
+   */
+  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the enums contained in this compilation unit.
+   */
+  List<ClassElement> _enums = ClassElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the top-level functions contained in this
+   * compilation unit.
+   */
+  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the function type aliases contained in this
+   * compilation unit.
+   */
+  List<FunctionTypeAliasElement> _typeAliases =
+      FunctionTypeAliasElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the types contained in this compilation unit.
+   */
+  List<ClassElement> _types = ClassElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the variables contained in this compilation unit.
+   */
+  List<TopLevelVariableElement> _variables = TopLevelVariableElement.EMPTY_LIST;
+
+  /**
+   * A map from offsets to elements of this unit at these offsets.
+   */
+  final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
+
+  /**
+   * Initialize a newly created compilation unit element to have the given
+   * [name].
+   */
+  CompilationUnitElementImpl(String name) : super(name, -1);
+
+  @override
+  List<PropertyAccessorElement> get accessors => _accessors;
+
+  /**
+   * Set the top-level accessors (getters and setters) contained in this
+   * compilation unit to the given [accessors].
+   */
+  void set accessors(List<PropertyAccessorElement> accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
+      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
+    }
+    this._accessors = accessors;
+  }
+
+  @override
+  LibraryElement get enclosingElement =>
+      super.enclosingElement as LibraryElement;
+
+  @override
+  List<ClassElement> get enums => _enums;
+
+  /**
+   * Set the enums contained in this compilation unit to the given [enums].
+   */
+  void set enums(List<ClassElement> enums) {
+    for (ClassElement enumDeclaration in enums) {
+      (enumDeclaration as ClassElementImpl).enclosingElement = this;
+    }
+    this._enums = enums;
+  }
+
+  @override
+  List<FunctionElement> get functions => _functions;
+
+  /**
+   * Set the top-level functions contained in this compilation unit to the given
+   * [functions].
+   */
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._functions = functions;
+  }
+
+  @override
+  List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
+
+  @override
+  int get hashCode => source.hashCode;
+
+  @override
+  bool get hasLoadLibraryFunction {
+    for (int i = 0; i < _functions.length; i++) {
+      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String get identifier => source.encoding;
+
+  @override
+  ElementKind get kind => ElementKind.COMPILATION_UNIT;
+
+  @override
+  List<TopLevelVariableElement> get topLevelVariables => _variables;
+
+  /**
+   * Set the top-level variables contained in this compilation unit to the given
+   * [variables].
+   */
+  void set topLevelVariables(List<TopLevelVariableElement> variables) {
+    for (TopLevelVariableElement field in variables) {
+      (field as TopLevelVariableElementImpl).enclosingElement = this;
+    }
+    this._variables = variables;
+  }
+
+  /**
+   * Set the function type aliases contained in this compilation unit to the
+   * given [typeAliases].
+   */
+  void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
+    for (FunctionTypeAliasElement typeAlias in typeAliases) {
+      (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
+    }
+    this._typeAliases = typeAliases;
+  }
+
+  @override
+  List<ClassElement> get types => _types;
+
+  /**
+   * Set the types contained in this compilation unit to the given [types].
+   */
+  void set types(List<ClassElement> types) {
+    for (ClassElement type in types) {
+      (type as ClassElementImpl).enclosingElement = this;
+    }
+    this._types = types;
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      object is CompilationUnitElementImpl && source == object.source;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
+
+  /**
+   * This method is invoked after this unit was incrementally resolved.
+   */
+  void afterIncrementalResolution() {
+    _offsetToElementMap.clear();
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (source == null) {
+      buffer.write("{compilation unit}");
+    } else {
+      buffer.write(source.fullName);
+    }
+  }
+
+  @override
+  CompilationUnit computeNode() => unit;
+
+  @override
+  ElementImpl getChild(String identifier) {
+    //
+    // The casts in this method are safe because the set methods would have
+    // thrown a CCE if any of the elements in the arrays were not of the
+    // expected types.
+    //
+    for (PropertyAccessorElement accessor in _accessors) {
+      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
+        return accessor as PropertyAccessorElementImpl;
+      }
+    }
+    for (VariableElement variable in _variables) {
+      if ((variable as VariableElementImpl).identifier == identifier) {
+        return variable as VariableElementImpl;
+      }
+    }
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (FunctionTypeAliasElement typeAlias in _typeAliases) {
+      if ((typeAlias as FunctionTypeAliasElementImpl).identifier ==
+          identifier) {
+        return typeAlias as FunctionTypeAliasElementImpl;
+      }
+    }
+    for (ClassElement type in _types) {
+      if ((type as ClassElementImpl).identifier == identifier) {
+        return type as ClassElementImpl;
+      }
+    }
+    for (ClassElement type in _enums) {
+      if ((type as ClassElementImpl).identifier == identifier) {
+        return type as ClassElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  Element getElementAt(int offset) {
+    if (_offsetToElementMap.isEmpty) {
+      accept(new _BuildOffsetToElementMap(_offsetToElementMap));
+    }
+    return _offsetToElementMap[offset];
+  }
+
+  @override
+  ClassElement getEnum(String enumName) {
+    for (ClassElement enumDeclaration in _enums) {
+      if (enumDeclaration.name == enumName) {
+        return enumDeclaration;
+      }
+    }
+    return null;
+  }
+
+  @override
+  ClassElement getType(String className) {
+    for (ClassElement type in _types) {
+      if (type.name == className) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Replace the given [from] top-level variable with [to] in this compilation unit.
+   */
+  void replaceTopLevelVariable(
+      TopLevelVariableElement from, TopLevelVariableElement to) {
+    int index = _variables.indexOf(from);
+    _variables[index] = to;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(_enums, visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_typeAliases, visitor);
+    safelyVisitChildren(_types, visitor);
+    safelyVisitChildren(_variables, visitor);
+  }
+}
+
+/**
+ * A [FieldElement] for a 'const' or 'final' field that has an initializer.
+ *
+ * TODO(paulberry): we should rename this class to reflect the fact that it's
+ * used for both const and final fields.  However, we shouldn't do so until
+ * we've created an API for reading the values of constants; until that API is
+ * available, clients are likely to read constant values by casting to
+ * ConstFieldElementImpl, so it would be a breaking change to rename this
+ * class.
+ */
+class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created synthetic field element to have the given
+   * [name] and [offset].
+   */
+  ConstFieldElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created field element to have the given [name].
+   */
+  ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A [LocalVariableElement] for a local 'const' variable that has an
+ * initializer.
+ */
+class ConstLocalVariableElementImpl extends LocalVariableElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created local variable element to have the given [name]
+   * and [offset].
+   */
+  ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created local variable element to have the given [name].
+   */
+  ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A concrete implementation of a [ConstructorElement].
+ */
+class ConstructorElementImpl extends ExecutableElementImpl
+    implements ConstructorElement {
+  /**
+   * The constructor to which this constructor is redirecting.
+   */
+  ConstructorElement redirectedConstructor;
+
+  /**
+   * The initializers for this constructor (used for evaluating constant
+   * instance creation expressions).
+   */
+  List<ConstructorInitializer> constantInitializers;
+
+  /**
+   * The offset of the `.` before this constructor name or `null` if not named.
+   */
+  int periodOffset;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this constructor's name, or `null` if not named.
+   */
+  int nameEnd;
+
+  /**
+   * True if this constructor has been found by constant evaluation to be free
+   * of redirect cycles, and is thus safe to evaluate.
+   */
+  bool isCycleFree = false;
+
+  /**
+   * Initialize a newly created constructor element to have the given [name] and
+   * [offset].
+   */
+  ConstructorElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created constructor element to have the given [name].
+   */
+  ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this constructor represents a 'const' constructor.
+   */
+  void set const2(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  /**
+   * Set whether this constructor represents a factory method.
+   */
+  void set factory(bool isFactory) {
+    setModifier(Modifier.FACTORY, isFactory);
+  }
+
+  @override
+  bool get isConst => hasModifier(Modifier.CONST);
+
+  @override
+  bool get isDefaultConstructor {
+    // unnamed
+    String name = this.name;
+    if (name != null && name.length != 0) {
+      return false;
+    }
+    // no required parameters
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        return false;
+      }
+    }
+    // OK, can be used as default constructor
+    return true;
+  }
+
+  @override
+  bool get isFactory => hasModifier(Modifier.FACTORY);
+
+  @override
+  bool get isStatic => false;
+
+  @override
+  ElementKind get kind => ElementKind.CONSTRUCTOR;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (enclosingElement == null) {
+      String message;
+      String name = displayName;
+      if (name != null && !name.isEmpty) {
+        message =
+            'Found constructor element named $name with no enclosing element';
+      } else {
+        message = 'Found unnamed constructor element with no enclosing element';
+      }
+      AnalysisEngine.instance.logger.logError(message);
+      buffer.write('<unknown class>');
+    } else {
+      buffer.write(enclosingElement.displayName);
+    }
+    String name = displayName;
+    if (name != null && !name.isEmpty) {
+      buffer.write(".");
+      buffer.write(name);
+    }
+    super.appendTo(buffer);
+  }
+
+  @override
+  ConstructorDeclaration computeNode() =>
+      getNodeMatching((node) => node is ConstructorDeclaration);
+}
+
+/**
+ * A [TopLevelVariableElement] for a top-level 'const' variable that has an
+ * initializer.
+ */
+class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
+   */
+  ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * Mixin used by elements that represent constant variables and have
+ * initializers.
+ *
+ * Note that in correct Dart code, all constant variables must have
+ * initializers.  However, analyzer also needs to handle incorrect Dart code,
+ * in which case there might be some constant variables that lack initializers.
+ * This interface is only used for constant variables that have initializers.
+ *
+ * This class is not intended to be part of the public API for analyzer.
+ */
+abstract class ConstVariableElement {
+  /**
+   * If this element represents a constant variable, and it has an initializer,
+   * a copy of the initializer for the constant.  Otherwise `null`.
+   *
+   * Note that in correct Dart code, all constant variables must have
+   * initializers.  However, analyzer also needs to handle incorrect Dart code,
+   * in which case there might be some constant variables that lack
+   * initializers.
+   */
+  Expression constantInitializer;
+}
+
+/**
+ * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
+ */
+class DefaultFieldFormalParameterElementImpl
+    extends FieldFormalParameterElementImpl with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+}
+
+/**
+ * A [ParameterElement] for parameters that have an initializer.
+ */
+class DefaultParameterElementImpl extends ParameterElementImpl
+    with ConstVariableElement {
+  /**
+   * The result of evaluating this variable's initializer.
+   */
+  EvaluationResultImpl _result;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  DefaultParameterElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  DartObject get constantValue => _result.value;
+
+  @override
+  EvaluationResultImpl get evaluationResult => _result;
+
+  @override
+  void set evaluationResult(EvaluationResultImpl result) {
+    this._result = result;
+  }
+
+  @override
+  DefaultFormalParameter computeNode() =>
+      getNodeMatching((node) => node is DefaultFormalParameter);
+}
+
+/**
+ * The synthetic element representing the declaration of the type `dynamic`.
+ */
+class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
+  /**
+   * Return the unique instance of this class.
+   */
+  static DynamicElementImpl get instance =>
+      DynamicTypeImpl.instance.element as DynamicElementImpl;
+
+  @override
+  DynamicTypeImpl type;
+
+  /**
+   * Initialize a newly created instance of this class. Instances of this class
+   * should <b>not</b> be created except as part of creating the type associated
+   * with this element. The single instance of this class should be accessed
+   * through the method [getInstance].
+   */
+  DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
+    setModifier(Modifier.SYNTHETIC, true);
+  }
+
+  @override
+  ElementKind get kind => ElementKind.DYNAMIC;
+
+  @override
+  accept(ElementVisitor visitor) => null;
+}
+
+/**
+ * A concrete implementation of an [ElementAnnotation].
+ */
+class ElementAnnotationImpl implements ElementAnnotation {
+  /**
+   * The name of the class used to mark an element as being deprecated.
+   */
+  static String _DEPRECATED_CLASS_NAME = "Deprecated";
+
+  /**
+   * The name of the top-level variable used to mark an element as being
+   * deprecated.
+   */
+  static String _DEPRECATED_VARIABLE_NAME = "deprecated";
+
+  /**
+   * The name of the top-level variable used to mark a method as being expected
+   * to override an inherited method.
+   */
+  static String _OVERRIDE_VARIABLE_NAME = "override";
+
+  /**
+   * The name of the top-level variable used to mark a class as implementing a
+   * proxy object.
+   */
+  static String PROXY_VARIABLE_NAME = "proxy";
+
+  /**
+   * The element representing the field, variable, or constructor being used as
+   * an annotation.
+   */
+  final Element element;
+
+  /**
+   * The result of evaluating this annotation as a compile-time constant
+   * expression, or `null` if the compilation unit containing the variable has
+   * not been resolved.
+   */
+  EvaluationResultImpl evaluationResult;
+
+  /**
+   * Initialize a newly created annotation. The given [element] is the element
+   * representing the field, variable, or constructor being used as an
+   * annotation.
+   */
+  ElementAnnotationImpl(this.element);
+
+  @override
+  DartObject get constantValue => evaluationResult.value;
+
+  @override
+  bool get isDeprecated {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is ConstructorElement) {
+          ConstructorElement constructorElement = element as ConstructorElement;
+          if (constructorElement.enclosingElement.name ==
+              _DEPRECATED_CLASS_NAME) {
+            return true;
+          }
+        } else if (element is PropertyAccessorElement &&
+            element.name == _DEPRECATED_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isOverride {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is PropertyAccessorElement &&
+            element.name == _OVERRIDE_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isProxy {
+    if (element != null) {
+      LibraryElement library = element.library;
+      if (library != null && library.isDartCore) {
+        if (element is PropertyAccessorElement &&
+            element.name == PROXY_VARIABLE_NAME) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  String toString() => '@$element';
+}
+
+/**
+ * A base class for concrete implementations of an [Element].
+ */
+abstract class ElementImpl implements Element {
+  /**
+   * An Unicode right arrow.
+   */
+  static final String RIGHT_ARROW = " \u2192 ";
+
+  static int _NEXT_ID = 0;
+
+  final int id = _NEXT_ID++;
+
+  /**
+   * The enclosing element of this element, or `null` if this element is at the
+   * root of the element structure.
+   */
+  ElementImpl _enclosingElement;
+
+  /**
+   * The name of this element.
+   */
+  String _name;
+
+  /**
+   * The offset of the name of this element in the file that contains the
+   * declaration of this element.
+   */
+  int _nameOffset = 0;
+
+  /**
+   * A bit-encoded form of the modifiers associated with this element.
+   */
+  int _modifiers = 0;
+
+  /**
+   * A list containing all of the metadata associated with this element.
+   */
+  List<ElementAnnotation> metadata = ElementAnnotation.EMPTY_LIST;
+
+  /**
+   * A cached copy of the calculated hashCode for this element.
+   */
+  int _cachedHashCode;
+
+  /**
+   * A cached copy of the calculated location for this element.
+   */
+  ElementLocation _cachedLocation;
+
+  /**
+   * The documentation comment for this element.
+   */
+  String _docComment;
+
+  /**
+   * The offset to the beginning of the documentation comment,
+   * or `null` if this element does not have a documentation comment.
+   */
+  int _docRangeOffset;
+
+  /**
+   * The length of the documentation comment range for this element.
+   */
+  int _docRangeLength;
+
+  /**
+   * Initialize a newly created element to have the given [name] at the given
+   * [_nameOffset].
+   */
+  ElementImpl(String name, this._nameOffset) {
+    this._name = StringUtilities.intern(name);
+  }
+
+  /**
+   * Initialize a newly created element to have the given [name].
+   */
+  ElementImpl.forNode(Identifier name)
+      : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
+
+  @override
+  AnalysisContext get context {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.context;
+  }
+
+  @override
+  String get displayName => _name;
+
+  @override
+  SourceRange get docRange {
+    if (_docRangeOffset != null && _docRangeLength != null) {
+      return new SourceRange(_docRangeOffset, _docRangeLength);
+    }
+    return null;
+  }
+
+  @override
+  String get documentationComment => _docComment;
+
+  /**
+   * The documentation comment source for this element.
+   */
+  void set documentationComment(String doc) {
+    _docComment = doc?.replaceAll('\r\n', '\n');
+  }
+
+  @override
+  Element get enclosingElement => _enclosingElement;
+
+  /**
+   * Set the enclosing element of this element to the given [element].
+   */
+  void set enclosingElement(Element element) {
+    _enclosingElement = element as ElementImpl;
+    _cachedLocation = null;
+    _cachedHashCode = null;
+  }
+
+  @override
+  int get hashCode {
+    // TODO: We might want to re-visit this optimization in the future.
+    // We cache the hash code value as this is a very frequently called method.
+    if (_cachedHashCode == null) {
+      int hashIdentifier = identifier.hashCode;
+      Element enclosing = enclosingElement;
+      if (enclosing != null) {
+        _cachedHashCode = hashIdentifier + enclosing.hashCode;
+      } else {
+        _cachedHashCode = hashIdentifier;
+      }
+    }
+    return _cachedHashCode;
+  }
+
+  /**
+   * Return an identifier that uniquely identifies this element among the
+   * children of this element's parent.
+   */
+  String get identifier => name;
+
+  @override
+  bool get isDeprecated {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isDeprecated) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isOverride {
+    for (ElementAnnotation annotation in metadata) {
+      if (annotation.isOverride) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return true;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  @override
+  bool get isPublic => !isPrivate;
+
+  @override
+  bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
+
+  @override
+  LibraryElement get library =>
+      getAncestor((element) => element is LibraryElement);
+
+  @override
+  ElementLocation get location {
+    if (_cachedLocation == null) {
+      _cachedLocation = new ElementLocationImpl.con1(this);
+    }
+    return _cachedLocation;
+  }
+
+  @override
+  String get name => _name;
+
+  void set name(String name) {
+    this._name = name;
+    _cachedLocation = null;
+    _cachedHashCode = null;
+  }
+
+  @override
+  int get nameLength => displayName != null ? displayName.length : 0;
+
+  @override
+  int get nameOffset => _nameOffset;
+
+  /**
+   * Sets the offset of the name of this element in the file that contains the
+   * declaration of this element.
+   */
+  void set nameOffset(int offset) {
+    _nameOffset = offset;
+    _cachedHashCode = null;
+    _cachedLocation = null;
+  }
+
+  @override
+  Source get source {
+    if (_enclosingElement == null) {
+      return null;
+    }
+    return _enclosingElement.source;
+  }
+
+  /**
+   * Set whether this element is synthetic.
+   */
+  void set synthetic(bool isSynthetic) {
+    setModifier(Modifier.SYNTHETIC, isSynthetic);
+  }
+
+  @override
+  CompilationUnit get unit => context.resolveCompilationUnit(source, library);
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
+    if (object == null || hashCode != object.hashCode) {
+      return false;
+    }
+    return object.runtimeType == runtimeType &&
+        (object as Element).location == location;
+  }
+
+  /**
+   * Append a textual representation of this element to the given [buffer].
+   */
+  void appendTo(StringBuffer buffer) {
+    if (_name == null) {
+      buffer.write("<unnamed ");
+      buffer.write(runtimeType.toString());
+      buffer.write(">");
+    } else {
+      buffer.write(_name);
+    }
+  }
+
+  @override
+  String computeDocumentationComment() => documentationComment;
+
+  @override
+  AstNode computeNode() => getNodeMatching((node) => node is AstNode);
+
+  /**
+   * Set this element as the enclosing element for given [element].
+   */
+  void encloseElement(ElementImpl element) {
+    element.enclosingElement = this;
+  }
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) {
+    Element ancestor = _enclosingElement;
+    while (ancestor != null && !predicate(ancestor)) {
+      ancestor = ancestor.enclosingElement;
+    }
+    return ancestor;
+  }
+
+  /**
+   * Return the child of this element that is uniquely identified by the given
+   * [identifier], or `null` if there is no such child.
+   */
+  ElementImpl getChild(String identifier) => null;
+
+  @override
+  String getExtendedDisplayName(String shortName) {
+    if (shortName == null) {
+      shortName = displayName;
+    }
+    Source source = this.source;
+    if (source != null) {
+      return "$shortName (${source.fullName})";
+    }
+    return shortName;
+  }
+
+  /**
+   * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
+   */
+  AstNode getNodeMatching(Predicate<AstNode> predicate) {
+    CompilationUnit unit = this.unit;
+    if (unit == null) {
+      return null;
+    }
+    int offset = nameOffset;
+    AstNode node = new NodeLocator(offset).searchWithin(unit);
+    if (node == null) {
+      return null;
+    }
+    return node.getAncestor(predicate);
+  }
+
+  /**
+   * Return `true` if this element has the given [modifier] associated with it.
+   */
+  bool hasModifier(Modifier modifier) =>
+      BooleanArray.getEnum(_modifiers, modifier);
+
+  @override
+  bool isAccessibleIn(LibraryElement library) {
+    if (Identifier.isPrivateName(_name)) {
+      return library == this.library;
+    }
+    return true;
+  }
+
+  /**
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
+   */
+  void safelyVisitChild(Element child, ElementVisitor visitor) {
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+
+  /**
+   * Use the given [visitor] to visit all of the [children] in the given array.
+   */
+  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
+    if (children != null) {
+      for (Element child in children) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Set the documentation comment source range for this element.
+   */
+  void setDocRange(int offset, int length) {
+    _docRangeOffset = offset;
+    _docRangeLength = length;
+  }
+
+  /**
+   * Set whether the given [modifier] is associated with this element to
+   * correspond to the given [value].
+   */
+  void setModifier(Modifier modifier, bool value) {
+    _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    appendTo(buffer);
+    return buffer.toString();
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+}
+
+/**
+ * A concrete implementation of an [ElementLocation].
+ */
+class ElementLocationImpl implements ElementLocation {
+  /**
+   * The character used to separate components in the encoded form.
+   */
+  static int _SEPARATOR_CHAR = 0x3B;
+
+  /**
+   * The path to the element whose location is represented by this object.
+   */
+  List<String> _components;
+
+  /**
+   * The object managing [indexKeyId] and [indexLocationId].
+   */
+  Object indexOwner;
+
+  /**
+   * A cached id of this location in index.
+   */
+  int indexKeyId;
+
+  /**
+   * A cached id of this location in index.
+   */
+  int indexLocationId;
+
+  /**
+   * Initialize a newly created location to represent the given [element].
+   */
+  ElementLocationImpl.con1(Element element) {
+    List<String> components = new List<String>();
+    Element ancestor = element;
+    while (ancestor != null) {
+      components.insert(0, (ancestor as ElementImpl).identifier);
+      ancestor = ancestor.enclosingElement;
+    }
+    this._components = components;
+  }
+
+  /**
+   * Initialize a newly created location from the given [encoding].
+   */
+  ElementLocationImpl.con2(String encoding) {
+    this._components = _decode(encoding);
+  }
+
+  /**
+   * Initialize a newly created location from the given [components].
+   */
+  ElementLocationImpl.con3(List<String> components) {
+    this._components = components;
+  }
+
+  @override
+  List<String> get components => _components;
+
+  @override
+  String get encoding {
+    StringBuffer buffer = new StringBuffer();
+    int length = _components.length;
+    for (int i = 0; i < length; i++) {
+      if (i > 0) {
+        buffer.writeCharCode(_SEPARATOR_CHAR);
+      }
+      _encode(buffer, _components[i]);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  int get hashCode {
+    int result = 1;
+    for (int i = 0; i < _components.length; i++) {
+      String component = _components[i];
+      result = 31 * result + component.hashCode;
+    }
+    return result;
+  }
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(this, object)) {
+      return true;
+    }
+    if (object is! ElementLocationImpl) {
+      return false;
+    }
+    ElementLocationImpl location = object as ElementLocationImpl;
+    List<String> otherComponents = location._components;
+    int length = _components.length;
+    if (otherComponents.length != length) {
+      return false;
+    }
+    for (int i = 0; i < length; i++) {
+      if (_components[i] != otherComponents[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  String toString() => encoding;
+
+  /**
+   * Decode the [encoding] of a location into a list of components and return
+   * the components.
+   */
+  List<String> _decode(String encoding) {
+    List<String> components = new List<String>();
+    StringBuffer buffer = new StringBuffer();
+    int index = 0;
+    int length = encoding.length;
+    while (index < length) {
+      int currentChar = encoding.codeUnitAt(index);
+      if (currentChar == _SEPARATOR_CHAR) {
+        if (index + 1 < length &&
+            encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
+          buffer.writeCharCode(_SEPARATOR_CHAR);
+          index += 2;
+        } else {
+          components.add(buffer.toString());
+          buffer = new StringBuffer();
+          index++;
+        }
+      } else {
+        buffer.writeCharCode(currentChar);
+        index++;
+      }
+    }
+    components.add(buffer.toString());
+    return components;
+  }
+
+  /**
+   * Append an encoded form of the given [component] to the given [buffer].
+   */
+  void _encode(StringBuffer buffer, String component) {
+    int length = component.length;
+    for (int i = 0; i < length; i++) {
+      int currentChar = component.codeUnitAt(i);
+      if (currentChar == _SEPARATOR_CHAR) {
+        buffer.writeCharCode(_SEPARATOR_CHAR);
+      }
+      buffer.writeCharCode(currentChar);
+    }
+  }
+}
+
+/**
+ * A base class for concrete implementations of an [ExecutableElement].
+ */
+abstract class ExecutableElementImpl extends ElementImpl
+    implements ExecutableElement {
+  /**
+   * A list containing all of the functions defined within this executable
+   * element.
+   */
+  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the labels defined within this executable element.
+   */
+  List<LabelElement> _labels = LabelElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the local variables defined within this executable
+   * element.
+   */
+  List<LocalVariableElement> _localVariables = LocalVariableElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the parameters defined by this executable element.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the type parameters defined for this executable
+   * element.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The return type defined by this executable element.
+   */
+  DartType returnType;
+
+  /**
+   * The type of function defined by this executable element.
+   */
+  FunctionType type;
+
+  /**
+   * Initialize a newly created executable element to have the given [name] and
+   * [offset].
+   */
+  ExecutableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created executable element to have the given [name].
+   */
+  ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this executable element's body is asynchronous.
+   */
+  void set asynchronous(bool isAsynchronous) {
+    setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
+  }
+
+  /**
+   * Set whether this executable element is external.
+   */
+  void set external(bool isExternal) {
+    setModifier(Modifier.EXTERNAL, isExternal);
+  }
+
+  @override
+  List<FunctionElement> get functions => _functions;
+
+  /**
+   * Set the functions defined within this executable element to the given
+   * [functions].
+   */
+  void set functions(List<FunctionElement> functions) {
+    for (FunctionElement function in functions) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._functions = functions;
+  }
+
+  /**
+   * Set whether this method's body is a generator.
+   */
+  void set generator(bool isGenerator) {
+    setModifier(Modifier.GENERATOR, isGenerator);
+  }
+
+  @override
+  bool get hasImplicitReturnType => hasModifier(Modifier.IMPLICIT_TYPE);
+
+  /**
+   * Set whether this executable element has an implicit return type.
+   */
+  void set hasImplicitReturnType(bool hasImplicitReturnType) {
+    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitReturnType);
+  }
+
+  @override
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+
+  @override
+  bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
+
+  @override
+  bool get isExternal => hasModifier(Modifier.EXTERNAL);
+
+  @override
+  bool get isGenerator => hasModifier(Modifier.GENERATOR);
+
+  @override
+  bool get isOperator => false;
+
+  @override
+  bool get isSynchronous => !hasModifier(Modifier.ASYNCHRONOUS);
+
+  @override
+  List<LabelElement> get labels => _labels;
+
+  /**
+   * Set the labels defined within this executable element to the given
+   * [labels].
+   */
+  void set labels(List<LabelElement> labels) {
+    for (LabelElement label in labels) {
+      (label as LabelElementImpl).enclosingElement = this;
+    }
+    this._labels = labels;
+  }
+
+  @override
+  List<LocalVariableElement> get localVariables => _localVariables;
+
+  /**
+   * Set the local variables defined within this executable element to the given
+   * [variables].
+   */
+  void set localVariables(List<LocalVariableElement> variables) {
+    for (LocalVariableElement variable in variables) {
+      (variable as LocalVariableElementImpl).enclosingElement = this;
+    }
+    this._localVariables = variables;
+  }
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
+      (parameter as ParameterElementImpl).enclosingElement = this;
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined by this executable element to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement parameter in typeParameters) {
+      (parameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (this.kind != ElementKind.GETTER) {
+      int typeParameterCount = _typeParameters.length;
+      if (typeParameterCount > 0) {
+        buffer.write('<');
+        for (int i = 0; i < typeParameterCount; i++) {
+          if (i > 0) {
+            buffer.write(", ");
+          }
+          (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+        }
+        buffer.write('>');
+      }
+      buffer.write("(");
+      String closing = null;
+      ParameterKind kind = ParameterKind.REQUIRED;
+      int parameterCount = _parameters.length;
+      for (int i = 0; i < parameterCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
+        ParameterKind parameterKind = parameter.parameterKind;
+        if (parameterKind != kind) {
+          if (closing != null) {
+            buffer.write(closing);
+          }
+          if (parameterKind == ParameterKind.POSITIONAL) {
+            buffer.write("[");
+            closing = "]";
+          } else if (parameterKind == ParameterKind.NAMED) {
+            buffer.write("{");
+            closing = "}";
+          } else {
+            closing = null;
+          }
+        }
+        kind = parameterKind;
+        parameter.appendToWithoutDelimiters(buffer);
+      }
+      if (closing != null) {
+        buffer.write(closing);
+      }
+      buffer.write(")");
+    }
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (ExecutableElement function in _functions) {
+      if ((function as ExecutableElementImpl).identifier == identifier) {
+        return function as ExecutableElementImpl;
+      }
+    }
+    for (LabelElement label in _labels) {
+      if ((label as LabelElementImpl).identifier == identifier) {
+        return label as LabelElementImpl;
+      }
+    }
+    for (VariableElement variable in _localVariables) {
+      if ((variable as VariableElementImpl).identifier == identifier) {
+        return variable as VariableElementImpl;
+      }
+    }
+    for (ParameterElement parameter in _parameters) {
+      if ((parameter as ParameterElementImpl).identifier == identifier) {
+        return parameter as ParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(_labels, visitor);
+    safelyVisitChildren(_localVariables, visitor);
+    safelyVisitChildren(_parameters, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of an [ExportElement].
+ */
+class ExportElementImpl extends UriReferencedElementImpl
+    implements ExportElement {
+  /**
+   * The library that is exported from this library by this export directive.
+   */
+  LibraryElement exportedLibrary;
+
+  /**
+   * The combinators that were specified as part of the export directive in the
+   * order in which they were specified.
+   */
+  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created export element at the given [offset].
+   */
+  ExportElementImpl(int offset) : super(null, offset);
+
+  @override
+  String get identifier => exportedLibrary.name;
+
+  @override
+  ElementKind get kind => ElementKind.EXPORT;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitExportElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("export ");
+    (exportedLibrary as LibraryElementImpl).appendTo(buffer);
+  }
+}
+
+/**
+ * A concrete implementation of a [FieldElement].
+ */
+class FieldElementImpl extends PropertyInducingElementImpl
+    implements FieldElement {
+  /**
+   * Initialize a newly created synthetic field element to have the given [name]
+   * at the given [offset].
+   */
+  FieldElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created field element to have the given [name].
+   */
+  FieldElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  @override
+  bool get isEnumConstant =>
+      enclosingElement != null ? enclosingElement.isEnum : false;
+
+  @override
+  ElementKind get kind => ElementKind.FIELD;
+
+  /**
+   * Set whether this field is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+
+  @override
+  AstNode computeNode() {
+    if (isEnumConstant) {
+      return getNodeMatching((node) => node is EnumConstantDeclaration);
+    } else {
+      return getNodeMatching((node) => node is VariableDeclaration);
+    }
+  }
+}
+
+/**
+ * A [ParameterElementImpl] that has the additional information of the
+ * [FieldElement] associated with the parameter.
+ */
+class FieldFormalParameterElementImpl extends ParameterElementImpl
+    implements FieldFormalParameterElement {
+  /**
+   * The field associated with this field formal parameter.
+   */
+  FieldElement field;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
+
+  @override
+  bool get isInitializingFormal => true;
+
+  @override
+  accept(ElementVisitor visitor) =>
+      visitor.visitFieldFormalParameterElement(this);
+}
+
+/**
+ * A concrete implementation of a [FunctionElement].
+ */
+class FunctionElementImpl extends ExecutableElementImpl
+    implements FunctionElement {
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created function element to have the given [name] and
+   * [offset].
+   */
+  FunctionElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created function element to have the given [name].
+   */
+  FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize a newly created function element to have no name and the given
+   * [offset]. This is used for function expressions, that have no name.
+   */
+  FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
+
+  @override
+  String get identifier {
+    String identifier = super.identifier;
+    if (!isStatic) {
+      identifier += "@$nameOffset";
+    }
+    return identifier;
+  }
+
+  @override
+  bool get isEntryPoint {
+    return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
+  }
+
+  @override
+  bool get isStatic => enclosingElement is CompilationUnitElement;
+
+  @override
+  ElementKind get kind => ElementKind.FUNCTION;
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    String name = displayName;
+    if (name != null) {
+      buffer.write(name);
+    }
+    super.appendTo(buffer);
+  }
+
+  @override
+  FunctionDeclaration computeNode() =>
+      getNodeMatching((node) => node is FunctionDeclaration);
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+
+  /**
+   * Set the parameters defined by this type alias to the given [parameters]
+   * without becoming the parent of the parameters. This should only be used by
+   * the [TypeResolverVisitor] when creating a synthetic type alias.
+   */
+  void shareParameters(List<ParameterElement> parameters) {
+    this._parameters = parameters;
+  }
+}
+
+/**
+ * A concrete implementation of a [FunctionTypeAliasElement].
+ */
+class FunctionTypeAliasElementImpl extends ElementImpl
+    implements FunctionTypeAliasElement {
+  /**
+   * A list containing all of the parameters defined by this type alias.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * The return type defined by this type alias.
+   */
+  DartType returnType;
+
+  /**
+   * The type of function defined by this type alias.
+   */
+  FunctionType type;
+
+  /**
+   * A list containing all of the type parameters defined for this type.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created type alias element to have the given name.
+   *
+   * [name] the name of this element
+   * [nameOffset] the offset of the name of this element in the file that
+   *    contains the declaration of this element
+   */
+  FunctionTypeAliasElementImpl(String name, int nameOffset)
+      : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created type alias element to have the given [name].
+   */
+  FunctionTypeAliasElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  CompilationUnitElement get enclosingElement =>
+      super.enclosingElement as CompilationUnitElement;
+
+  @override
+  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this type alias to the given [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    if (parameters != null) {
+      for (ParameterElement parameter in parameters) {
+        (parameter as ParameterElementImpl).enclosingElement = this;
+      }
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined for this type to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement typeParameter in typeParameters) {
+      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("typedef ");
+    buffer.write(displayName);
+    int typeParameterCount = _typeParameters.length;
+    if (typeParameterCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < typeParameterCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+    buffer.write("(");
+    int parameterCount = _parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      (_parameters[i] as ParameterElementImpl).appendTo(buffer);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    } else if (returnType != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(returnType);
+    }
+  }
+
+  @override
+  FunctionTypeAlias computeNode() =>
+      getNodeMatching((node) => node is FunctionTypeAlias);
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (VariableElement parameter in _parameters) {
+      if ((parameter as VariableElementImpl).identifier == identifier) {
+        return parameter as VariableElementImpl;
+      }
+    }
+    for (TypeParameterElement typeParameter in _typeParameters) {
+      if ((typeParameter as TypeParameterElementImpl).identifier ==
+          identifier) {
+        return typeParameter as TypeParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_parameters, visitor);
+    safelyVisitChildren(_typeParameters, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of a [HideElementCombinator].
+ */
+class HideElementCombinatorImpl implements HideElementCombinator {
+  /**
+   * The names that are not to be made visible in the importing library even if
+   * they are defined in the imported library.
+   */
+  List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("show ");
+    int count = hiddenNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(hiddenNames[i]);
+    }
+    return buffer.toString();
+  }
+}
+
+/**
+ * A concrete implementation of an [ImportElement].
+ */
+class ImportElementImpl extends UriReferencedElementImpl
+    implements ImportElement {
+  /**
+   * The offset of the prefix of this import in the file that contains the this
+   * import directive, or `-1` if this import is synthetic.
+   */
+  int prefixOffset = 0;
+
+  /**
+   * The library that is imported into this library by this import directive.
+   */
+  LibraryElement importedLibrary;
+
+  /**
+   * The combinators that were specified as part of the import directive in the
+   * order in which they were specified.
+   */
+  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+
+  /**
+   * The prefix that was specified as part of the import directive, or `null` if
+   * there was no prefix specified.
+   */
+  PrefixElement prefix;
+
+  /**
+   * Initialize a newly created import element at the given [offset].
+   * The offset may be `-1` if the import is synthetic.
+   */
+  ImportElementImpl(int offset) : super(null, offset);
+
+  /**
+   * Set whether this import is for a deferred library.
+   */
+  void set deferred(bool isDeferred) {
+    setModifier(Modifier.DEFERRED, isDeferred);
+  }
+
+  @override
+  String get identifier => "${importedLibrary.identifier}@$nameOffset";
+
+  @override
+  bool get isDeferred => hasModifier(Modifier.DEFERRED);
+
+  @override
+  ElementKind get kind => ElementKind.IMPORT;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitImportElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("import ");
+    (importedLibrary as LibraryElementImpl).appendTo(buffer);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(prefix, visitor);
+  }
+}
+
+/**
+ * A concrete implementation of a [LabelElement].
+ */
+class LabelElementImpl extends ElementImpl implements LabelElement {
+  /**
+   * A flag indicating whether this label is associated with a `switch`
+   * statement.
+   */
+  // TODO(brianwilkerson) Make this a modifier.
+  final bool _onSwitchStatement;
+
+  /**
+   * A flag indicating whether this label is associated with a `switch` member
+   * (`case` or `default`).
+   */
+  // TODO(brianwilkerson) Make this a modifier.
+  final bool _onSwitchMember;
+
+  /**
+   * Initialize a newly created label element to have the given [name].
+   * [onSwitchStatement] should be `true` if this label is associated with a
+   * `switch` statement and [onSwitchMember] should be `true` if this label is
+   * associated with a `switch` member.
+   */
+  LabelElementImpl(
+      Identifier name, this._onSwitchStatement, this._onSwitchMember)
+      : super.forNode(name);
+
+  @override
+  ExecutableElement get enclosingElement =>
+      super.enclosingElement as ExecutableElement;
+
+  /**
+   * Return `true` if this label is associated with a `switch` member (`case` or
+   * `default`).
+   */
+  bool get isOnSwitchMember => _onSwitchMember;
+
+  /**
+   * Return `true` if this label is associated with a `switch` statement.
+   */
+  bool get isOnSwitchStatement => _onSwitchStatement;
+
+  @override
+  ElementKind get kind => ElementKind.LABEL;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
+}
+
+/**
+ * A concrete implementation of a [LibraryElement].
+ */
+class LibraryElementImpl extends ElementImpl implements LibraryElement {
+  /**
+   * The analysis context in which this library is defined.
+   */
+  final AnalysisContext context;
+
+  /**
+   * The compilation unit that defines this library.
+   */
+  CompilationUnitElement _definingCompilationUnit;
+
+  /**
+   * The entry point for this library, or `null` if this library does not have
+   * an entry point.
+   */
+  FunctionElement entryPoint;
+
+  /**
+   * A list containing specifications of all of the imports defined in this
+   * library.
+   */
+  List<ImportElement> _imports = ImportElement.EMPTY_LIST;
+
+  /**
+   * A list containing specifications of all of the exports defined in this
+   * library.
+   */
+  List<ExportElement> _exports = ExportElement.EMPTY_LIST;
+
+  /**
+   * A list containing the strongly connected component in the import/export
+   * graph in which the current library resides.  Computed on demand, null
+   * if not present.  If _libraryCycle is set, then the _libraryCycle field
+   * for all libraries reachable from this library in the import/export graph
+   * is also set.
+   */
+  List<LibraryElement> _libraryCycle = null;
+
+  /**
+   * A list containing all of the compilation units that are included in this
+   * library using a `part` directive.
+   */
+  List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
+
+  /**
+   * The element representing the synthetic function `loadLibrary` that is
+   * defined for this library, or `null` if the element has not yet been created.
+   */
+  FunctionElement _loadLibraryFunction;
+
+  @override
+  final int nameLength;
+
+  /**
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  @override
+  Namespace exportNamespace;
+
+  /**
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  @override
+  Namespace publicNamespace;
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name] and [offset].
+   */
+  LibraryElementImpl(this.context, String name, int offset, this.nameLength)
+      : super(name, offset);
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name].
+   */
+  LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
+      : super.forNode(name),
+        nameLength = name != null ? name.length : 0;
+
+  @override
+  CompilationUnitElement get definingCompilationUnit =>
+      _definingCompilationUnit;
+
+  /**
+   * Set the compilation unit that defines this library to the given compilation
+   * [unit].
+   */
+  void set definingCompilationUnit(CompilationUnitElement unit) {
+    assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
+    (unit as CompilationUnitElementImpl).enclosingElement = this;
+    this._definingCompilationUnit = unit;
+  }
+
+  @override
+  List<LibraryElement> get exportedLibraries {
+    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
+    for (ExportElement element in _exports) {
+      LibraryElement library = element.exportedLibrary;
+      if (library != null) {
+        libraries.add(library);
+      }
+    }
+    return new List.from(libraries);
+  }
+
+  @override
+  List<ExportElement> get exports => _exports;
+
+  /**
+   * Set the specifications of all of the exports defined in this library to the
+   * given list of [exports].
+   */
+  void set exports(List<ExportElement> exports) {
+    for (ExportElement exportElement in exports) {
+      (exportElement as ExportElementImpl).enclosingElement = this;
+    }
+    this._exports = exports;
+  }
+
+  @override
+  bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
+
+  /**
+   * Set whether this library has an import of a "dart-ext" URI.
+   */
+  void set hasExtUri(bool hasExtUri) {
+    setModifier(Modifier.HAS_EXT_URI, hasExtUri);
+  }
+
+  @override
+  int get hashCode => _definingCompilationUnit.hashCode;
+
+  @override
+  bool get hasLoadLibraryFunction {
+    if (_definingCompilationUnit.hasLoadLibraryFunction) {
+      return true;
+    }
+    for (int i = 0; i < _parts.length; i++) {
+      if (_parts[i].hasLoadLibraryFunction) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String get identifier => _definingCompilationUnit.source.encoding;
+
+  @override
+  List<LibraryElement> get importedLibraries {
+    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
+    for (ImportElement element in _imports) {
+      LibraryElement library = element.importedLibrary;
+      if (library != null) {
+        libraries.add(library);
+      }
+    }
+    return new List.from(libraries);
+  }
+
+  @override
+  List<ImportElement> get imports => _imports;
+
+  /**
+   * Set the specifications of all of the imports defined in this library to the
+   * given list of [imports].
+   */
+  void set imports(List<ImportElement> imports) {
+    for (ImportElement importElement in imports) {
+      (importElement as ImportElementImpl).enclosingElement = this;
+      PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
+      if (prefix != null) {
+        prefix.enclosingElement = this;
+      }
+    }
+    this._imports = imports;
+  }
+
+  @override
+  bool get isBrowserApplication =>
+      entryPoint != null && isOrImportsBrowserLibrary;
+
+  @override
+  bool get isDartCore => name == "dart.core";
+
+  @override
+  bool get isInSdk =>
+      StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
+
+  /**
+   * Return `true` if the receiver directly or indirectly imports the
+   * 'dart:html' libraries.
+   */
+  bool get isOrImportsBrowserLibrary {
+    List<LibraryElement> visited = new List<LibraryElement>();
+    Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
+    visited.add(this);
+    for (int index = 0; index < visited.length; index++) {
+      LibraryElement library = visited[index];
+      Source source = library.definingCompilationUnit.source;
+      if (source == htmlLibSource) {
+        return true;
+      }
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!visited.contains(importedLibrary)) {
+          visited.add(importedLibrary);
+        }
+      }
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!visited.contains(exportedLibrary)) {
+          visited.add(exportedLibrary);
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  ElementKind get kind => ElementKind.LIBRARY;
+
+  @override
+  LibraryElement get library => this;
+
+  List<LibraryElement> get libraryCycle {
+    if (_libraryCycle != null) {
+      return _libraryCycle;
+    }
+
+    // Global counter for this run of the algorithm
+    int counter = 0;
+    // The discovery times of each library
+    Map<LibraryElementImpl, int> indices = {};
+    // The set of scc candidates
+    Set<LibraryElementImpl> active = new Set();
+    // The stack of discovered elements
+    List<LibraryElementImpl> stack = [];
+    // For a given library that has not yet been processed by this run of the
+    // algorithm, compute the strongly connected components.
+    int scc(LibraryElementImpl library) {
+      int index = counter++;
+      int root = index;
+      indices[library] = index;
+      active.add(library);
+      stack.add(library);
+      void recurse(LibraryElementImpl child) {
+        if (!indices.containsKey(child)) {
+          // We haven't visited this child yet, so recurse on the child,
+          // returning the lowest numbered node reachable from the child.  If
+          // the child can reach a root which is lower numbered than anything
+          // we've reached so far, update the root.
+          root = min(root, scc(child));
+        } else if (active.contains(child)) {
+          // The child has been visited, but has not yet been placed into a
+          // component.  If the child is higher than anything we've seen so far
+          // update the root appropriately.
+          root = min(root, indices[child]);
+        }
+      }
+      // Recurse on all of the children in the import/export graph, filtering
+      // out those for which library cycles have already been computed.
+      library.exportedLibraries
+          .where((l) => l._libraryCycle == null)
+          .forEach(recurse);
+      library.importedLibraries
+          .where((l) => l._libraryCycle == null)
+          .forEach(recurse);
+
+      if (root == index) {
+        // This is the root of a strongly connected component.
+        // Pop the elements, and share the component across all
+        // of the elements.
+        List<LibraryElement> component = <LibraryElement>[];
+        LibraryElementImpl cur = null;
+        do {
+          cur = stack.removeLast();
+          active.remove(cur);
+          component.add(cur);
+          cur._libraryCycle = component;
+        } while (cur != library);
+      }
+      return root;
+    }
+    scc(library);
+    return _libraryCycle;
+  }
+
+  @override
+  FunctionElement get loadLibraryFunction {
+    assert(_loadLibraryFunction != null);
+    return _loadLibraryFunction;
+  }
+
+  @override
+  List<CompilationUnitElement> get parts => _parts;
+
+  /**
+   * Set the compilation units that are included in this library using a `part`
+   * directive to the given list of [parts].
+   */
+  void set parts(List<CompilationUnitElement> parts) {
+    for (CompilationUnitElement compilationUnit in parts) {
+      assert((compilationUnit as CompilationUnitElementImpl).librarySource ==
+          source);
+      (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
+    }
+    this._parts = parts;
+  }
+
+  @override
+  List<PrefixElement> get prefixes {
+    HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
+    for (ImportElement element in _imports) {
+      PrefixElement prefix = element.prefix;
+      if (prefix != null) {
+        prefixes.add(prefix);
+      }
+    }
+    return new List.from(prefixes);
+  }
+
+  @override
+  Source get source {
+    if (_definingCompilationUnit == null) {
+      return null;
+    }
+    return _definingCompilationUnit.source;
+  }
+
+  @override
+  List<CompilationUnitElement> get units {
+    List<CompilationUnitElement> units = new List<CompilationUnitElement>();
+    units.add(_definingCompilationUnit);
+    units.addAll(_parts);
+    return units;
+  }
+
+  @override
+  List<LibraryElement> get visibleLibraries {
+    Set<LibraryElement> visibleLibraries = new Set();
+    _addVisibleLibraries(visibleLibraries, false);
+    return new List.from(visibleLibraries);
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      object is LibraryElementImpl &&
+      _definingCompilationUnit == object.definingCompilationUnit;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
+
+  /**
+   * Create the [FunctionElement] to be returned by [loadLibraryFunction],
+   * using types provided by [typeProvider].
+   */
+  void createLoadLibraryFunction(TypeProvider typeProvider) {
+    FunctionElementImpl function =
+        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
+    function.synthetic = true;
+    function.enclosingElement = this;
+    function.returnType = typeProvider.futureDynamicType;
+    function.type = new FunctionTypeImpl(function);
+    _loadLibraryFunction = function;
+  }
+
+  @override
+  ElementImpl getChild(String identifier) {
+    if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier ==
+        identifier) {
+      return _definingCompilationUnit as CompilationUnitElementImpl;
+    }
+    for (CompilationUnitElement part in _parts) {
+      if ((part as CompilationUnitElementImpl).identifier == identifier) {
+        return part as CompilationUnitElementImpl;
+      }
+    }
+    for (ImportElement importElement in _imports) {
+      if ((importElement as ImportElementImpl).identifier == identifier) {
+        return importElement as ImportElementImpl;
+      }
+    }
+    for (ExportElement exportElement in _exports) {
+      if ((exportElement as ExportElementImpl).identifier == identifier) {
+        return exportElement as ExportElementImpl;
+      }
+    }
+    return null;
+  }
+
+  @override
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
+    int count = _imports.length;
+    List<ImportElement> importList = new List<ImportElement>();
+    for (int i = 0; i < count; i++) {
+      if (identical(_imports[i].prefix, prefixElement)) {
+        importList.add(_imports[i]);
+      }
+    }
+    return importList;
+  }
+
+  @override
+  ClassElement getType(String className) {
+    ClassElement type = _definingCompilationUnit.getType(className);
+    if (type != null) {
+      return type;
+    }
+    for (CompilationUnitElement part in _parts) {
+      type = part.getType(className);
+      if (type != null) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  /** Given an update to this library which may have added or deleted edges
+   * in the import/export graph originating from this node only, remove any
+   * cached library cycles in the element model which may have been invalidated.
+   */
+  void invalidateLibraryCycles() {
+    if (_libraryCycle == null) {
+      // We have already invalidated this node, or we have never computed
+      // library cycle information for it.  In the former case, we're done. In
+      // the latter case, this node cannot be reachable from any node for which
+      // we have computed library cycle information.  Therefore, any edges added
+      // or deleted in the update causing this invalidation can only be edges to
+      // nodes which either have no library cycle information (and hence do not
+      // need invalidation), or which do not reach this node by any path.
+      // In either case, no further invalidation is needed.
+      return;
+    }
+    // If we have pre-computed library cycle information, then we must
+    // invalidate the information both on this element, and on certain
+    // other elements.  Edges originating at this node may have been
+    // added or deleted.  A deleted edge that points outside of this cycle
+    // cannot change the cycle information for anything outside of this cycle,
+    // and so it is sufficient to delete the cached library information on this
+    // cycle.  An added edge which points to another node within the cycle
+    // only invalidates the cycle.  An added edge which points to a node earlier
+    // in the topological sort of cycles induces no invalidation (since there
+    // are by definition no back edges from earlier cycles in the topological
+    // order, and hence no possible cycle can have been introduced.  The only
+    // remaining case is that we have added an edge to a node which is later
+    // in the topological sort of cycles.  This can induce cycles, since it
+    // represents a new back edge.  It would be sufficient to invalidate the
+    // cycle information for all nodes that are between the target and the
+    // node in the topological order.  For simplicity, we simply invalidate
+    // all nodes which are reachable from the the source node.
+    // Note that in the invalidation phase, we do not cut off when we encounter
+    // a node with no library cycle information, since we do not know whether
+    // we are in the case where invalidation has already been performed, or we
+    // are in the case where library cycles have simply never been computed from
+    // a newly reachable node.
+    Set<LibraryElementImpl> active = new HashSet();
+    void invalidate(LibraryElementImpl library) {
+      if (!active.add(library)) return;
+      if (library._libraryCycle != null) {
+        library._libraryCycle.forEach(invalidate);
+        library._libraryCycle = null;
+      }
+      library.exportedLibraries.forEach(invalidate);
+      library.importedLibraries.forEach(invalidate);
+    }
+    invalidate(this);
+  }
+
+  @override
+  bool isUpToDate(int timeStamp) {
+    Set<LibraryElement> visitedLibraries = new Set();
+    return _safeIsUpToDate(this, timeStamp, visitedLibraries);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_definingCompilationUnit, visitor);
+    safelyVisitChildren(_exports, visitor);
+    safelyVisitChildren(_imports, visitor);
+    safelyVisitChildren(_parts, visitor);
+  }
+
+  /**
+   * Recursively fills set of visible libraries for
+   * [getVisibleElementsLibraries].
+   */
+  void _addVisibleLibraries(
+      Set<LibraryElement> visibleLibraries, bool includeExports) {
+    // maybe already processed
+    if (!visibleLibraries.add(this)) {
+      return;
+    }
+    // add imported libraries
+    for (ImportElement importElement in _imports) {
+      LibraryElement importedLibrary = importElement.importedLibrary;
+      if (importedLibrary != null) {
+        (importedLibrary as LibraryElementImpl)
+            ._addVisibleLibraries(visibleLibraries, true);
+      }
+    }
+    // add exported libraries
+    if (includeExports) {
+      for (ExportElement exportElement in _exports) {
+        LibraryElement exportedLibrary = exportElement.exportedLibrary;
+        if (exportedLibrary != null) {
+          (exportedLibrary as LibraryElementImpl)
+              ._addVisibleLibraries(visibleLibraries, true);
+        }
+      }
+    }
+  }
+
+  /**
+   * Return `true` if the given [library] is up to date with respect to the
+   * given [timeStamp]. The set of [visitedLibraries] is used to prevent
+   * infinite recursion in the case of mutually dependent libraries.
+   */
+  static bool _safeIsUpToDate(LibraryElement library, int timeStamp,
+      Set<LibraryElement> visitedLibraries) {
+    if (!visitedLibraries.contains(library)) {
+      visitedLibraries.add(library);
+      AnalysisContext context = library.context;
+      // Check the defining compilation unit.
+      if (timeStamp <
+          context
+              .getModificationStamp(library.definingCompilationUnit.source)) {
+        return false;
+      }
+      // Check the parted compilation units.
+      for (CompilationUnitElement element in library.parts) {
+        if (timeStamp < context.getModificationStamp(element.source)) {
+          return false;
+        }
+      }
+      // Check the imported libraries.
+      for (LibraryElement importedLibrary in library.importedLibraries) {
+        if (!_safeIsUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+      // Check the exported libraries.
+      for (LibraryElement exportedLibrary in library.exportedLibraries) {
+        if (!_safeIsUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+}
+
+/**
+ * A concrete implementation of a [LocalVariableElement].
+ */
+class LocalVariableElementImpl extends VariableElementImpl
+    implements LocalVariableElement {
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  LocalVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created local variable element to have the given [name].
+   */
+  LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  String get identifier {
+    int enclosingOffset =
+        enclosingElement != null ? enclosingElement.nameOffset : 0;
+    int delta = nameOffset - enclosingOffset;
+    return '${super.identifier}@$delta';
+  }
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+
+  @override
+  ElementKind get kind => ElementKind.LOCAL_VARIABLE;
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+  }
+
+  @override
+  VariableDeclaration computeNode() =>
+      getNodeMatching((node) => node is VariableDeclaration);
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in closure.
+   */
+  void markPotentiallyMutatedInClosure() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutatedInScope() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
+  }
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+}
+
+/**
+ * A concrete implementation of a [MethodElement].
+ */
+class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
+  /**
+   * Initialize a newly created method element to have the given [name] at the
+   * given [offset].
+   */
+  MethodElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created method element to have the given [name].
+   */
+  MethodElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this method is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  String get displayName {
+    String displayName = super.displayName;
+    if ("unary-" == displayName) {
+      return "-";
+    }
+    return displayName;
+  }
+
+  @override
+  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
+
+  @override
+  bool get isOperator {
+    String name = displayName;
+    if (name.isEmpty) {
+      return false;
+    }
+    int first = name.codeUnitAt(0);
+    return !((0x61 <= first && first <= 0x7A) ||
+        (0x41 <= first && first <= 0x5A) ||
+        first == 0x5F ||
+        first == 0x24);
+  }
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  ElementKind get kind => ElementKind.METHOD;
+
+  @override
+  String get name {
+    String name = super.name;
+    if (isOperator && name == "-") {
+      if (parameters.length == 0) {
+        return "unary-";
+      }
+    }
+    return super.name;
+  }
+
+  /**
+   * Set whether this method is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(displayName);
+    super.appendTo(buffer);
+  }
+
+  @override
+  MethodDeclaration computeNode() =>
+      getNodeMatching((node) => node is MethodDeclaration);
+}
+
+/**
+ * A concrete implementation of a [MultiplyDefinedElement].
+ */
+class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
+  /**
+   * The unique integer identifier of this element.
+   */
+  final int id = ElementImpl._NEXT_ID++;
+
+  /**
+   * The analysis context in which the multiply defined elements are defined.
+   */
+  final AnalysisContext context;
+
+  /**
+   * The name of the conflicting elements.
+   */
+  String _name;
+
+  /**
+   * A list containing all of the elements that conflict.
+   */
+  final List<Element> conflictingElements;
+
+  /**
+   * Initialize a newly created element in the given [context] to represent a
+   * list of [conflictingElements].
+   */
+  MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
+    _name = conflictingElements[0].name;
+  }
+
+  @override
+  String get displayName => _name;
+
+  @override
+  SourceRange get docRange => null;
+
+  @override
+  String get documentationComment => null;
+
+  @override
+  Element get enclosingElement => null;
+
+  @override
+  bool get isDeprecated => false;
+
+  @override
+  bool get isOverride => false;
+
+  @override
+  bool get isPrivate {
+    String name = displayName;
+    if (name == null) {
+      return false;
+    }
+    return Identifier.isPrivateName(name);
+  }
+
+  @override
+  bool get isPublic => !isPrivate;
+
+  @override
+  bool get isSynthetic => true;
+
+  @override
+  ElementKind get kind => ElementKind.ERROR;
+
+  @override
+  LibraryElement get library => null;
+
+  @override
+  ElementLocation get location => null;
+
+  @override
+  List<ElementAnnotation> get metadata => ElementAnnotation.EMPTY_LIST;
+
+  @override
+  String get name => _name;
+
+  @override
+  int get nameLength => displayName != null ? displayName.length : 0;
+
+  @override
+  int get nameOffset => -1;
+
+  @override
+  Source get source => null;
+
+  @override
+  DartType get type => DynamicTypeImpl.instance;
+
+  @override
+  CompilationUnit get unit => null;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
+
+  @override
+  String computeDocumentationComment() => null;
+
+  @override
+  AstNode computeNode() => null;
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) => null;
+
+  @override
+  String getExtendedDisplayName(String shortName) {
+    if (shortName != null) {
+      return shortName;
+    }
+    return displayName;
+  }
+
+  @override
+  bool isAccessibleIn(LibraryElement library) {
+    for (Element element in conflictingElements) {
+      if (element.isAccessibleIn(library)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("[");
+    int count = conflictingElements.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      (conflictingElements[i] as ElementImpl).appendTo(buffer);
+    }
+    buffer.write("]");
+    return buffer.toString();
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+
+  /**
+   * Return an element in the given [context] that represents the fact that the
+   * [firstElement] and [secondElement] conflict. (If the elements are the same,
+   * then one of the two will be returned directly.)
+   */
+  static Element fromElements(
+      AnalysisContext context, Element firstElement, Element secondElement) {
+    List<Element> conflictingElements =
+        _computeConflictingElements(firstElement, secondElement);
+    int length = conflictingElements.length;
+    if (length == 0) {
+      return null;
+    } else if (length == 1) {
+      return conflictingElements[0];
+    }
+    return new MultiplyDefinedElementImpl(context, conflictingElements);
+  }
+
+  /**
+   * Add the given [element] to the list of [elements]. If the element is a
+   * multiply-defined element, add all of the conflicting elements that it
+   * represents.
+   */
+  static void _add(HashSet<Element> elements, Element element) {
+    if (element is MultiplyDefinedElementImpl) {
+      for (Element conflictingElement in element.conflictingElements) {
+        elements.add(conflictingElement);
+      }
+    } else {
+      elements.add(element);
+    }
+  }
+
+  /**
+   * Use the given elements to construct a list of conflicting elements. If
+   * either the [firstElement] or [secondElement] are multiply-defined elements
+   * then the conflicting elements they represent will be included in the array.
+   * Otherwise, the element itself will be included.
+   */
+  static List<Element> _computeConflictingElements(
+      Element firstElement, Element secondElement) {
+    HashSet<Element> elements = new HashSet<Element>();
+    _add(elements, firstElement);
+    _add(elements, secondElement);
+    return new List.from(elements);
+  }
+}
+
+/**
+ * A [MethodElementImpl], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ */
+class MultiplyInheritedMethodElementImpl extends MethodElementImpl
+    implements MultiplyInheritedExecutableElement {
+  /**
+   * A list the array of executable elements that were used to compose this
+   * element.
+   */
+  List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
+
+  MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
+    synthetic = true;
+  }
+
+  @override
+  List<ExecutableElement> get inheritedElements => _elements;
+
+  void set inheritedElements(List<ExecutableElement> elements) {
+    this._elements = elements;
+  }
+}
+
+/**
+ * A [PropertyAccessorElementImpl], with the additional information of a list of
+ * [ExecutableElement]s from which this element was composed.
+ */
+class MultiplyInheritedPropertyAccessorElementImpl
+    extends PropertyAccessorElementImpl
+    implements MultiplyInheritedExecutableElement {
+  /**
+   * A list the array of executable elements that were used to compose this
+   * element.
+   */
+  List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
+
+  MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
+      : super.forNode(name) {
+    synthetic = true;
+  }
+
+  @override
+  List<ExecutableElement> get inheritedElements => _elements;
+
+  void set inheritedElements(List<ExecutableElement> elements) {
+    this._elements = elements;
+  }
+}
+
+/**
+ * A concrete implementation of a [ParameterElement].
+ */
+class ParameterElementImpl extends VariableElementImpl
+    with ParameterElementMixin
+    implements ParameterElement {
+  /**
+   * A list containing all of the parameters defined by this parameter element.
+   * There will only be parameters if this parameter is a function typed
+   * parameter.
+   */
+  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
+
+  /**
+   * A list containing all of the type parameters defined for this parameter
+   * element. There will only be parameters if this parameter is a function
+   * typed parameter.
+   */
+  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
+
+  /**
+   * The kind of this parameter.
+   */
+  ParameterKind parameterKind;
+
+  /**
+   * The Dart code of the default value.
+   */
+  String _defaultValueCode;
+
+  /**
+   * The offset to the beginning of the visible range for this element.
+   */
+  int _visibleRangeOffset = 0;
+
+  /**
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
+   */
+  int _visibleRangeLength = -1;
+
+  /**
+   * Initialize a newly created parameter element to have the given [name] and
+   * [offset].
+   */
+  ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created parameter element to have the given [name].
+   */
+  ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  String get defaultValueCode => _defaultValueCode;
+
+  /**
+   * Set Dart code of the default value.
+   */
+  void set defaultValueCode(String defaultValueCode) {
+    this._defaultValueCode = StringUtilities.intern(defaultValueCode);
+  }
+
+  @override
+  bool get isInitializingFormal => false;
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+
+  @override
+  ElementKind get kind => ElementKind.PARAMETER;
+
+  @override
+  List<ParameterElement> get parameters => _parameters;
+
+  /**
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
+   */
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
+      (parameter as ParameterElementImpl).enclosingElement = this;
+    }
+    this._parameters = parameters;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters defined by this parameter element to the given
+   * [typeParameters].
+   */
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement parameter in typeParameters) {
+      (parameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
+  }
+
+  @override
+  SourceRange get visibleRange {
+    if (_visibleRangeLength < 0) {
+      return null;
+    }
+    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    String left = "";
+    String right = "";
+    while (true) {
+      if (parameterKind == ParameterKind.NAMED) {
+        left = "{";
+        right = "}";
+      } else if (parameterKind == ParameterKind.POSITIONAL) {
+        left = "[";
+        right = "]";
+      } else if (parameterKind == ParameterKind.REQUIRED) {}
+      break;
+    }
+    buffer.write(left);
+    appendToWithoutDelimiters(buffer);
+    buffer.write(right);
+  }
+
+  @override
+  FormalParameter computeNode() =>
+      getNodeMatching((node) => node is FormalParameter);
+
+  @override
+  ElementImpl getChild(String identifier) {
+    for (ParameterElement parameter in _parameters) {
+      if ((parameter as ParameterElementImpl).identifier == identifier) {
+        return parameter as ParameterElementImpl;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in closure.
+   */
+  void markPotentiallyMutatedInClosure() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
+  }
+
+  /**
+   * Specifies that this variable is potentially mutated somewhere in its scope.
+   */
+  void markPotentiallyMutatedInScope() {
+    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
+  }
+
+  /**
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
+   */
+  void setVisibleRange(int offset, int length) {
+    _visibleRangeOffset = offset;
+    _visibleRangeLength = length;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(_parameters, visitor);
+  }
+}
+
+/**
+ * A mixin that provides a common implementation for methods defined in
+ * [ParameterElement].
+ */
+abstract class ParameterElementMixin implements ParameterElement {
+  @override
+  void appendToWithoutDelimiters(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+    if (defaultValueCode != null) {
+      if (parameterKind == ParameterKind.NAMED) {
+        buffer.write(": ");
+      }
+      if (parameterKind == ParameterKind.POSITIONAL) {
+        buffer.write(" = ");
+      }
+      buffer.write(defaultValueCode);
+    }
+  }
+}
+
+/**
+ * A concrete implementation of a [PrefixElement].
+ */
+class PrefixElementImpl extends ElementImpl implements PrefixElement {
+  /**
+   * A list containing all of the libraries that are imported using this prefix.
+   */
+  List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created prefix element to have the given [name].
+   */
+  PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  LibraryElement get enclosingElement =>
+      super.enclosingElement as LibraryElement;
+
+  @override
+  String get identifier => "_${super.identifier}";
+
+  @override
+  List<LibraryElement> get importedLibraries => _importedLibraries;
+
+  /**
+   * Set the libraries that are imported using this prefix to the given
+   * [libraries].
+   */
+  void set importedLibraries(List<LibraryElement> libraries) {
+    for (LibraryElement library in libraries) {
+      (library as LibraryElementImpl).enclosingElement = this;
+    }
+    _importedLibraries = libraries;
+  }
+
+  @override
+  ElementKind get kind => ElementKind.PREFIX;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write("as ");
+    super.appendTo(buffer);
+  }
+}
+
+/**
+ * A concrete implementation of a [PropertyAccessorElement].
+ */
+class PropertyAccessorElementImpl extends ExecutableElementImpl
+    implements PropertyAccessorElement {
+  /**
+   * The variable associated with this accessor.
+   */
+  PropertyInducingElement variable;
+
+  /**
+   * Initialize a newly created property accessor element to have the given
+   * [name] and [offset].
+   */
+  PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created property accessor element to have the given
+   * [name].
+   */
+  PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize a newly created synthetic property accessor element to be
+   * associated with the given [variable].
+   */
+  PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
+      : super(variable.name, variable.nameOffset) {
+    this.variable = variable;
+    static = variable.isStatic;
+    synthetic = true;
+  }
+
+  /**
+   * Set whether this accessor is abstract.
+   */
+  void set abstract(bool isAbstract) {
+    setModifier(Modifier.ABSTRACT, isAbstract);
+  }
+
+  @override
+  PropertyAccessorElement get correspondingGetter {
+    if (isGetter || variable == null) {
+      return null;
+    }
+    return variable.getter;
+  }
+
+  @override
+  PropertyAccessorElement get correspondingSetter {
+    if (isSetter || variable == null) {
+      return null;
+    }
+    return variable.setter;
+  }
+
+  /**
+   * Set whether this accessor is a getter.
+   */
+  void set getter(bool isGetter) {
+    setModifier(Modifier.GETTER, isGetter);
+  }
+
+  @override
+  int get hashCode => JenkinsSmiHash.hash2(super.hashCode, isGetter ? 1 : 2);
+
+  @override
+  String get identifier {
+    String name = displayName;
+    String suffix = isGetter ? "?" : "=";
+    return "$name$suffix";
+  }
+
+  @override
+  bool get isGetter => hasModifier(Modifier.GETTER);
+
+  @override
+  bool get isSetter => hasModifier(Modifier.SETTER);
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  ElementKind get kind {
+    if (isGetter) {
+      return ElementKind.GETTER;
+    }
+    return ElementKind.SETTER;
+  }
+
+  @override
+  String get name {
+    if (isSetter) {
+      return "${super.name}=";
+    }
+    return super.name;
+  }
+
+  /**
+   * Set whether this accessor is a setter.
+   */
+  void set setter(bool isSetter) {
+    setModifier(Modifier.SETTER, isSetter);
+  }
+
+  /**
+   * Set whether this accessor is static.
+   */
+  void set static(bool isStatic) {
+    setModifier(Modifier.STATIC, isStatic);
+  }
+
+  @override
+  bool operator ==(Object object) =>
+      super == object &&
+      isGetter == (object as PropertyAccessorElement).isGetter;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(isGetter ? "get " : "set ");
+    buffer.write(variable.displayName);
+    super.appendTo(buffer);
+  }
+
+  @override
+  AstNode computeNode() {
+    if (isSynthetic) {
+      return null;
+    }
+    if (enclosingElement is ClassElement) {
+      return getNodeMatching((node) => node is MethodDeclaration);
+    }
+    if (enclosingElement is CompilationUnitElement) {
+      return getNodeMatching((node) => node is FunctionDeclaration);
+    }
+    return null;
+  }
+}
+
+/**
+ * A concrete implementation of a [PropertyInducingElement].
+ */
+abstract class PropertyInducingElementImpl extends VariableElementImpl
+    implements PropertyInducingElement {
+  /**
+   * The getter associated with this element.
+   */
+  PropertyAccessorElement getter;
+
+  /**
+   * The setter associated with this element, or `null` if the element is
+   * effectively `final` and therefore does not have a setter associated with
+   * it.
+   */
+  PropertyAccessorElement setter;
+
+  /**
+   * The propagated type of this variable, or `null` if type propagation has not
+   * been performed.
+   */
+  DartType propagatedType;
+
+  /**
+   * Initialize a newly created synthetic element to have the given [name] and
+   * [offset].
+   */
+  PropertyInducingElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created element to have the given [name].
+   */
+  PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
+}
+
+/**
+ * A concrete implementation of a [ShowElementCombinator].
+ */
+class ShowElementCombinatorImpl implements ShowElementCombinator {
+  /**
+   * The names that are to be made visible in the importing library if they are
+   * defined in the imported library.
+   */
+  List<String> shownNames = StringUtilities.EMPTY_ARRAY;
+
+  /**
+   * The offset of the character immediately following the last character of
+   * this node.
+   */
+  int end = -1;
+
+  /**
+   * The offset of the 'show' keyword of this element.
+   */
+  int offset = 0;
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("show ");
+    int count = shownNames.length;
+    for (int i = 0; i < count; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(shownNames[i]);
+    }
+    return buffer.toString();
+  }
+}
+
+/**
+ * A concrete implementation of a [TopLevelVariableElement].
+ */
+class TopLevelVariableElementImpl extends PropertyInducingElementImpl
+    implements TopLevelVariableElement {
+  /**
+   * Initialize a newly created synthetic top-level variable element to have the
+   * given [name] and [offset].
+   */
+  TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
+   */
+  TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  bool get isStatic => true;
+
+  @override
+  ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
+
+  @override
+  VariableDeclaration computeNode() =>
+      getNodeMatching((node) => node is VariableDeclaration);
+}
+
+/**
+ * A concrete implementation of a [TypeParameterElement].
+ */
+class TypeParameterElementImpl extends ElementImpl
+    implements TypeParameterElement {
+  /**
+   * The type defined by this type parameter.
+   */
+  TypeParameterType type;
+
+  /**
+   * The type representing the bound associated with this parameter, or `null`
+   * if this parameter does not have an explicit bound.
+   */
+  DartType bound;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
+   */
+  TypeParameterElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created type parameter element to have the given [name].
+   */
+  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  @override
+  ElementKind get kind => ElementKind.TYPE_PARAMETER;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(displayName);
+    if (bound != null) {
+      buffer.write(" extends ");
+      buffer.write(bound);
+    }
+  }
+}
+
+/**
+ * A concrete implementation of a [UriReferencedElement].
+ */
+abstract class UriReferencedElementImpl extends ElementImpl
+    implements UriReferencedElement {
+  /**
+   * The offset of the URI in the file, may be `-1` if synthetic.
+   */
+  int uriOffset = -1;
+
+  /**
+   * The offset of the character immediately following the last character of
+   * this node's URI, may be `-1` if synthetic.
+   */
+  int uriEnd = -1;
+
+  /**
+   * The URI that is specified by this directive.
+   */
+  String uri;
+
+  /**
+   * Initialize a newly created import element to have the given [name] and
+   * [offset]. The offset may be `-1` if the element is synthetic.
+   */
+  UriReferencedElementImpl(String name, int offset) : super(name, offset);
+}
+
+/**
+ * A concrete implementation of a [VariableElement].
+ */
+abstract class VariableElementImpl extends ElementImpl
+    implements VariableElement {
+  /**
+   * The declared type of this variable.
+   */
+  DartType type;
+
+  /**
+   * A synthetic function representing this variable's initializer, or `null` if
+   * this variable does not have an initializer.
+   */
+  FunctionElement _initializer;
+
+  /**
+   * Initialize a newly created variable element to have the given [name] and
+   * [offset].
+   */
+  VariableElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created variable element to have the given [name].
+   */
+  VariableElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Set whether this variable is const.
+   */
+  void set const3(bool isConst) {
+    setModifier(Modifier.CONST, isConst);
+  }
+
+  /**
+   * If this element represents a constant variable, and it has an initializer,
+   * a copy of the initializer for the constant.  Otherwise `null`.
+   *
+   * Note that in correct Dart code, all constant variables must have
+   * initializers.  However, analyzer also needs to handle incorrect Dart code,
+   * in which case there might be some constant variables that lack
+   * initializers.
+   */
+  Expression get constantInitializer => null;
+
+  @override
+  DartObject get constantValue => null;
+
+  /**
+   * Return the result of evaluating this variable's initializer as a
+   * compile-time constant expression, or `null` if this variable is not a
+   * 'const' variable, if it does not have an initializer, or if the compilation
+   * unit containing the variable has not been resolved.
+   */
+  EvaluationResultImpl get evaluationResult => null;
+
+  /**
+   * Set the result of evaluating this variable's initializer as a compile-time
+   * constant expression to the given [result].
+   */
+  void set evaluationResult(EvaluationResultImpl result) {
+    throw new IllegalStateException(
+        "Invalid attempt to set a compile-time constant result");
+  }
+
+  /**
+   * Set whether this variable is final.
+   */
+  void set final2(bool isFinal) {
+    setModifier(Modifier.FINAL, isFinal);
+  }
+
+  @override
+  bool get hasImplicitType => hasModifier(Modifier.IMPLICIT_TYPE);
+
+  /**
+   * Set whether this variable element has an implicit type.
+   */
+  void set hasImplicitType(bool hasImplicitType) {
+    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
+  }
+
+  @override
+  FunctionElement get initializer => _initializer;
+
+  /**
+   * Set the function representing this variable's initializer to the given
+   * [function].
+   */
+  void set initializer(FunctionElement function) {
+    if (function != null) {
+      (function as FunctionElementImpl).enclosingElement = this;
+    }
+    this._initializer = function;
+  }
+
+  @override
+  bool get isConst => hasModifier(Modifier.CONST);
+
+  @override
+  bool get isFinal => hasModifier(Modifier.FINAL);
+
+  @override
+  bool get isPotentiallyMutatedInClosure => false;
+
+  @override
+  bool get isPotentiallyMutatedInScope => false;
+
+  @override
+  bool get isStatic => hasModifier(Modifier.STATIC);
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(type);
+    buffer.write(" ");
+    buffer.write(displayName);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChild(_initializer, visitor);
+  }
+}
+
+/**
+ * A visitor that visit all the elements recursively and fill the given [map].
+ */
+class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
+  final Map<int, Element> map;
+
+  _BuildOffsetToElementMap(this.map);
+
+  @override
+  void visitElement(Element element) {
+    int offset = element.nameOffset;
+    if (offset != -1) {
+      map[offset] = element;
+    }
+    super.visitElement(element);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
new file mode 100644
index 0000000..fea415f
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -0,0 +1,967 @@
+// 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.member;
+
+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/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A constructor element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class ConstructorMember extends ExecutableMember implements ConstructorElement {
+  /**
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
+   */
+  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  ConstructorElement get baseElement => super.baseElement as ConstructorElement;
+
+  @override
+  InterfaceType get definingType => super.definingType as InterfaceType;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isConst => baseElement.isConst;
+
+  @override
+  bool get isDefaultConstructor => baseElement.isDefaultConstructor;
+
+  @override
+  bool get isFactory => baseElement.isFactory;
+
+  @override
+  int get nameEnd => baseElement.nameEnd;
+
+  @override
+  int get periodOffset => baseElement.periodOffset;
+
+  @override
+  ConstructorElement get redirectedConstructor =>
+      from(baseElement.redirectedConstructor, definingType);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
+
+  @override
+  ConstructorDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    ConstructorElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.enclosingElement.displayName);
+    String name = displayName;
+    if (name != null && !name.isEmpty) {
+      buffer.write(".");
+      buffer.write(name);
+    }
+    buffer.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(parameters[i]);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [constructor]'s type is different when any type parameters
+   * from the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a constructor member representing
+   * the given constructor. Return the member that was created, or the original
+   * constructor if no member was created.
+   */
+  static ConstructorElement from(
+      ConstructorElement constructor, InterfaceType definingType) {
+    if (constructor == null || definingType.typeArguments.length == 0) {
+      return constructor;
+    }
+    FunctionType baseType = constructor.type;
+    if (baseType == null) {
+      // TODO(brianwilkerson) We need to understand when this can happen.
+      return constructor;
+    }
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes = definingType.element.type.typeArguments;
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return constructor;
+    }
+    return new ConstructorMember(constructor, definingType, substitutedType);
+  }
+}
+
+/**
+ * An executable element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+abstract class ExecutableMember extends Member implements ExecutableElement {
+  @override
+  final FunctionType type;
+
+  /**
+   * Initialize a newly created element to represent a callable element (like a
+   * method or function or property), based on the [baseElement], defined by the
+   * [definingType]. If [type] is passed, it represents the full type of the
+   * member, and will take precedence over the [definingType].
+   */
+  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
+
+  @override
+  ExecutableElement get baseElement => super.baseElement as ExecutableElement;
+
+  @override
+  List<FunctionElement> get functions {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+//    return getBaseElement().getFunctions();
+  }
+
+  @override
+  bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
+
+  @override
+  bool get isAbstract => baseElement.isAbstract;
+
+  @override
+  bool get isAsynchronous => baseElement.isAsynchronous;
+
+  @override
+  bool get isExternal => baseElement.isExternal;
+
+  @override
+  bool get isGenerator => baseElement.isGenerator;
+
+  @override
+  bool get isOperator => baseElement.isOperator;
+
+  @override
+  bool get isStatic => baseElement.isStatic;
+
+  @override
+  bool get isSynchronous => baseElement.isSynchronous;
+
+  @override
+  List<LabelElement> get labels => baseElement.labels;
+
+  @override
+  List<LocalVariableElement> get localVariables {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+//    return getBaseElement().getLocalVariables();
+  }
+
+  @override
+  List<ParameterElement> get parameters => type.parameters;
+
+  @override
+  DartType get returnType => type.returnType;
+
+  @override
+  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used
+    // below so that we can safely invoke them.
+    super.visitChildren(visitor);
+    safelyVisitChildren(baseElement.functions, visitor);
+    safelyVisitChildren(labels, visitor);
+    safelyVisitChildren(baseElement.localVariables, visitor);
+    safelyVisitChildren(parameters, visitor);
+  }
+}
+
+/**
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class FieldFormalParameterMember extends ParameterMember
+    implements FieldFormalParameterElement {
+  /**
+   * Initialize a newly created element to represent a field formal parameter,
+   * based on the [baseElement], defined by the [definingType]. If [type]
+   * is passed it will be used as the substituted type for this member.
+   */
+  FieldFormalParameterMember(
+      FieldFormalParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  FieldElement get field {
+    FieldElement field = (baseElement as FieldFormalParameterElement).field;
+    if (field is FieldElement) {
+      return FieldMember.from(
+          field, substituteFor(field.enclosingElement.type));
+    }
+    return field;
+  }
+
+  @override
+  accept(ElementVisitor visitor) =>
+      visitor.visitFieldFormalParameterElement(this);
+}
+
+/**
+ * A field element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+class FieldMember extends VariableMember implements FieldElement {
+  /**
+   * Initialize a newly created element to represent a field, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  FieldMember(FieldElement baseElement, InterfaceType definingType)
+      : super(baseElement, definingType);
+
+  @override
+  FieldElement get baseElement => super.baseElement as FieldElement;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  PropertyAccessorElement get getter =>
+      PropertyAccessorMember.from(baseElement.getter, definingType);
+
+  @override
+  bool get isEnumConstant => baseElement.isEnumConstant;
+
+  @override
+  DartType get propagatedType => substituteFor(baseElement.propagatedType);
+
+  @override
+  PropertyAccessorElement get setter =>
+      PropertyAccessorMember.from(baseElement.setter, definingType);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+
+  @override
+  VariableDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() => '$type $displayName';
+
+  /**
+   * If the given [field]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a field member representing the given
+   * field. Return the member that was created, or the base field if no member
+   * was created.
+   */
+  static FieldElement from(FieldElement field, ParameterizedType definingType) {
+    if (!_isChangedByTypeSubstitution(field, definingType)) {
+      return field;
+    }
+    // TODO(brianwilkerson) Consider caching the substituted type in the
+    // instance. It would use more memory but speed up some operations.
+    // We need to see how often the type is being re-computed.
+    return new FieldMember(field, definingType);
+  }
+
+  /**
+   * Determine whether the given [field]'s type is changed when type parameters
+   * from the [definingType]'s declaration are replaced with the actual type
+   * arguments from the defining type.
+   */
+  static bool _isChangedByTypeSubstitution(
+      FieldElement field, ParameterizedType definingType) {
+    List<DartType> argumentTypes = definingType.typeArguments;
+    if (field != null && argumentTypes.length != 0) {
+      DartType baseType = field.type;
+      List<DartType> parameterTypes =
+          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+      if (baseType != null) {
+        DartType substitutedType =
+            baseType.substitute2(argumentTypes, parameterTypes);
+        if (baseType != substitutedType) {
+          return true;
+        }
+      }
+      // If the field has a propagated type, then we need to check whether the
+      // propagated type needs substitution.
+      DartType basePropagatedType = field.propagatedType;
+      if (basePropagatedType != null) {
+        DartType substitutedPropagatedType =
+            basePropagatedType.substitute2(argumentTypes, parameterTypes);
+        if (basePropagatedType != substitutedPropagatedType) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * An element of a generic function, where the type parameters are known.
+ */
+// TODO(jmesserly): the term "function member" is a bit weird, but it allows
+// a certain consistency.
+class FunctionMember extends ExecutableMember implements FunctionElement {
+  /**
+   * Initialize a newly created element to represent a function, based on the
+   * [baseElement], with the corresponding function [type].
+   */
+  FunctionMember(FunctionElement baseElement, [DartType type])
+      : super(baseElement, null, type);
+
+  @override
+  FunctionElement get baseElement => super.baseElement as FunctionElement;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isEntryPoint => baseElement.isEntryPoint;
+
+  @override
+  SourceRange get visibleRange => baseElement.visibleRange;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+  @override
+  FunctionDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.displayName);
+    (type as FunctionTypeImpl).appendTo(buffer);
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
+   */
+  static MethodElement from(
+      MethodElement method, ParameterizedType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
+    }
+    FunctionType baseType = method.type;
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return method;
+    }
+    return new MethodMember(method, definingType, substitutedType);
+  }
+}
+
+/**
+ * An element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+abstract class Member implements Element {
+  /**
+   * The element on which the parameterized element was created.
+   */
+  final Element _baseElement;
+
+  /**
+   * The type in which the element is defined.
+   */
+  final ParameterizedType _definingType;
+
+  /**
+   * Initialize a newly created element to represent a member, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  Member(this._baseElement, this._definingType);
+
+  /**
+   * Return the element on which the parameterized element was created.
+   */
+  Element get baseElement => _baseElement;
+
+  @override
+  AnalysisContext get context => _baseElement.context;
+
+  /**
+   * Return the type in which the element is defined.
+   */
+  ParameterizedType get definingType => _definingType;
+
+  @override
+  String get displayName => _baseElement.displayName;
+
+  @override
+  SourceRange get docRange => _baseElement.docRange;
+
+  @override
+  String get documentationComment => _baseElement.documentationComment;
+
+  int get id => _baseElement.id;
+
+  @override
+  bool get isDeprecated => _baseElement.isDeprecated;
+
+  @override
+  bool get isOverride => _baseElement.isOverride;
+
+  @override
+  bool get isPrivate => _baseElement.isPrivate;
+
+  @override
+  bool get isPublic => _baseElement.isPublic;
+
+  @override
+  bool get isSynthetic => _baseElement.isSynthetic;
+
+  @override
+  ElementKind get kind => _baseElement.kind;
+
+  @override
+  LibraryElement get library => _baseElement.library;
+
+  @override
+  ElementLocation get location => _baseElement.location;
+
+  @override
+  List<ElementAnnotation> get metadata => _baseElement.metadata;
+
+  @override
+  String get name => _baseElement.name;
+
+  @override
+  int get nameLength => _baseElement.nameLength;
+
+  @override
+  int get nameOffset => _baseElement.nameOffset;
+
+  @override
+  Source get source => _baseElement.source;
+
+  @override
+  CompilationUnit get unit => _baseElement.unit;
+
+  @override
+  String computeDocumentationComment() => documentationComment;
+
+  @override
+  AstNode computeNode() => _baseElement.computeNode();
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) =>
+      baseElement.getAncestor(predicate);
+
+  @override
+  String getExtendedDisplayName(String shortName) =>
+      _baseElement.getExtendedDisplayName(shortName);
+
+  @override
+  bool isAccessibleIn(LibraryElement library) =>
+      _baseElement.isAccessibleIn(library);
+
+  /**
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
+   */
+  void safelyVisitChild(Element child, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+
+  /**
+   * Use the given [visitor] to visit all of the [children].
+   */
+  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
+    if (children != null) {
+      for (Element child in children) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Return the type that results from replacing the type parameters in the
+   * given [type] with the type arguments associated with this member.
+   */
+  DartType substituteFor(DartType type) {
+    if (type == null) {
+      return null;
+    }
+    List<DartType> argumentTypes = _definingType.typeArguments;
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
+    return type.substitute2(argumentTypes, parameterTypes);
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // There are no children to visit
+  }
+}
+
+/**
+ * A method element defined in a parameterized type where the values of the type
+ * parameters are known.
+ */
+class MethodMember extends ExecutableMember implements MethodElement {
+  /**
+   * Initialize a newly created element to represent a method, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
+   */
+  MethodMember(MethodElement baseElement, InterfaceType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
+
+  @override
+  MethodElement get baseElement => super.baseElement as MethodElement;
+
+  @override
+  ClassElement get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
+
+  @override
+  MethodDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    MethodElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.enclosingElement.displayName);
+    buffer.write(".");
+    buffer.write(baseElement.displayName);
+    buffer.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        buffer.write(", ");
+      }
+      buffer.write(parameters[i]);
+    }
+    buffer.write(")");
+    if (type != null) {
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      buffer.write(type.returnType);
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
+   */
+  static MethodElement from(MethodElement method, InterfaceType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
+    }
+    FunctionType baseType = method.type;
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes = definingType.element.type.typeArguments;
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return method;
+    }
+    return new MethodMember(method, definingType, substitutedType);
+  }
+}
+
+/**
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+class ParameterMember extends VariableMember
+    with ParameterElementMixin
+    implements ParameterElement {
+  /**
+   * Initialize a newly created element to represent a parameter, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed it will
+   * represent the already substituted type.
+   */
+  ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super._(baseElement, definingType, type);
+
+  @override
+  ParameterElement get baseElement => super.baseElement as ParameterElement;
+
+  @override
+  String get defaultValueCode => baseElement.defaultValueCode;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  int get hashCode => baseElement.hashCode;
+
+  @override
+  bool get isInitializingFormal => baseElement.isInitializingFormal;
+
+  @override
+  ParameterKind get parameterKind => baseElement.parameterKind;
+
+  @override
+  List<ParameterElement> get parameters {
+    DartType type = this.type;
+    if (type is FunctionType) {
+      return type.parameters;
+    }
+    return ParameterElement.EMPTY_LIST;
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
+
+  @override
+  SourceRange get visibleRange => baseElement.visibleRange;
+
+  // TODO(jmesserly): this equality is broken. It should consider the defining
+  // type as well, otherwise we're dropping the substitution.
+  @override
+  bool operator ==(Object object) =>
+      object is ParameterMember && baseElement == object.baseElement;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
+
+  @override
+  FormalParameter computeNode() => baseElement.computeNode();
+
+  @override
+  Element getAncestor(Predicate<Element> predicate) {
+    Element element = baseElement.getAncestor(predicate);
+    ParameterizedType definingType = this.definingType;
+    if (definingType is InterfaceType) {
+      InterfaceType definingInterfaceType = definingType;
+      if (element is ConstructorElement) {
+        return ConstructorMember.from(element, definingInterfaceType);
+      } else if (element is MethodElement) {
+        return MethodMember.from(element, definingInterfaceType);
+      } else if (element is PropertyAccessorElement) {
+        return PropertyAccessorMember.from(element, definingInterfaceType);
+      }
+    }
+    return element;
+  }
+
+  @override
+  String toString() {
+    ParameterElement baseElement = this.baseElement;
+    String left = "";
+    String right = "";
+    while (true) {
+      if (baseElement.parameterKind == ParameterKind.NAMED) {
+        left = "{";
+        right = "}";
+      } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
+        left = "[";
+        right = "]";
+      } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
+      break;
+    }
+    return '$left$type ${baseElement.displayName}$right';
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    super.visitChildren(visitor);
+    safelyVisitChildren(parameters, visitor);
+  }
+
+  /**
+   * If the given [parameter]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a parameter member representing
+   * the given parameter. Return the member that was created, or the base
+   * parameter if no member was created.
+   */
+  static ParameterElement from(
+      ParameterElement parameter, ParameterizedType definingType) {
+    if (parameter == null || definingType.typeArguments.length == 0) {
+      return parameter;
+    }
+    // Check if parameter type depends on defining type type arguments.
+    // It is possible that we did not resolve field formal parameter yet,
+    // so skip this check for it.
+    if (parameter is FieldFormalParameterElement) {
+      return new FieldFormalParameterMember(parameter, definingType);
+    } else {
+      DartType baseType = parameter.type;
+      List<DartType> argumentTypes = definingType.typeArguments;
+      List<DartType> parameterTypes =
+          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+      DartType substitutedType =
+          baseType.substitute2(argumentTypes, parameterTypes);
+      if (baseType == substitutedType) {
+        return parameter;
+      }
+      return new ParameterMember(parameter, definingType, substitutedType);
+    }
+  }
+}
+
+/**
+ * A property accessor element defined in a parameterized type where the values
+ * of the type parameters are known.
+ */
+class PropertyAccessorMember extends ExecutableMember
+    implements PropertyAccessorElement {
+  /**
+   * Initialize a newly created element to represent a property, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  PropertyAccessorMember(
+      PropertyAccessorElement baseElement, InterfaceType definingType)
+      : super(baseElement, definingType);
+
+  @override
+  PropertyAccessorElement get baseElement =>
+      super.baseElement as PropertyAccessorElement;
+
+  @override
+  PropertyAccessorElement get correspondingGetter =>
+      from(baseElement.correspondingGetter, definingType);
+
+  @override
+  PropertyAccessorElement get correspondingSetter =>
+      from(baseElement.correspondingSetter, definingType);
+
+  @override
+  InterfaceType get definingType => super.definingType as InterfaceType;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isGetter => baseElement.isGetter;
+
+  @override
+  bool get isSetter => baseElement.isSetter;
+
+  @override
+  PropertyInducingElement get variable {
+    PropertyInducingElement variable = baseElement.variable;
+    if (variable is FieldElement) {
+      return FieldMember.from(variable, definingType);
+    }
+    return variable;
+  }
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
+
+  @override
+  String toString() {
+    PropertyAccessorElement baseElement = this.baseElement;
+    List<ParameterElement> parameters = this.parameters;
+    FunctionType type = this.type;
+    StringBuffer builder = new StringBuffer();
+    if (isGetter) {
+      builder.write("get ");
+    } else {
+      builder.write("set ");
+    }
+    builder.write(baseElement.enclosingElement.displayName);
+    builder.write(".");
+    builder.write(baseElement.displayName);
+    builder.write("(");
+    int parameterCount = parameters.length;
+    for (int i = 0; i < parameterCount; i++) {
+      if (i > 0) {
+        builder.write(", ");
+      }
+      builder.write(parameters[i]);
+    }
+    builder.write(")");
+    if (type != null) {
+      builder.write(ElementImpl.RIGHT_ARROW);
+      builder.write(type.returnType);
+    }
+    return builder.toString();
+  }
+
+  /**
+   * If the given [accessor]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create an accessor member representing
+   * the given accessor. Return the member that was created, or the base
+   * accessor if no member was created.
+   */
+  static PropertyAccessorElement from(
+      PropertyAccessorElement accessor, InterfaceType definingType) {
+    if (!_isChangedByTypeSubstitution(accessor, definingType)) {
+      return accessor;
+    }
+    // TODO(brianwilkerson) Consider caching the substituted type in the
+    // instance. It would use more memory but speed up some operations.
+    // We need to see how often the type is being re-computed.
+    return new PropertyAccessorMember(accessor, definingType);
+  }
+
+  /**
+   * Determine whether the given property [accessor]'s type is changed when type
+   * parameters from the defining type's declaration are replaced with the
+   * actual type arguments from the [definingType].
+   */
+  static bool _isChangedByTypeSubstitution(
+      PropertyAccessorElement accessor, InterfaceType definingType) {
+    List<DartType> argumentTypes = definingType.typeArguments;
+    if (accessor != null && argumentTypes.length != 0) {
+      FunctionType baseType = accessor.type;
+      if (baseType == null) {
+        AnalysisEngine.instance.logger.logInformation(
+            'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
+        return false;
+      }
+      List<DartType> parameterTypes = definingType.element.type.typeArguments;
+      FunctionType substitutedType =
+          baseType.substitute2(argumentTypes, parameterTypes);
+      if (baseType != substitutedType) {
+        return true;
+      }
+      // If this property accessor is based on a field, that field might have a
+      // propagated type. In which case we need to check whether the propagated
+      // type of the field needs substitution.
+      PropertyInducingElement field = accessor.variable;
+      if (!field.isSynthetic) {
+        DartType baseFieldType = field.propagatedType;
+        if (baseFieldType != null) {
+          DartType substitutedFieldType =
+              baseFieldType.substitute2(argumentTypes, parameterTypes);
+          if (baseFieldType != substitutedFieldType) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * A variable element defined in a parameterized type where the values of the
+ * type parameters are known.
+ */
+abstract class VariableMember extends Member implements VariableElement {
+  @override
+  final DartType type;
+
+  /**
+   * Initialize a newly created element to represent a variable, based on the
+   * [baseElement], defined by the [definingType].
+   */
+  VariableMember(VariableElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
+
+  // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
+  // Apparently mixins don't work with optional params.
+  VariableMember._(VariableElement baseElement, ParameterizedType definingType,
+      DartType type)
+      : this(baseElement, definingType, type);
+
+  @override
+  VariableElement get baseElement => super.baseElement as VariableElement;
+
+  @override
+  DartObject get constantValue => baseElement.constantValue;
+
+  @override
+  bool get hasImplicitType => baseElement.hasImplicitType;
+
+  @override
+  FunctionElement get initializer {
+    //
+    // Elements within this element should have type parameters substituted,
+    // just like this element.
+    //
+    throw new UnsupportedOperationException();
+    //    return getBaseElement().getInitializer();
+  }
+
+  @override
+  bool get isConst => baseElement.isConst;
+
+  @override
+  bool get isFinal => baseElement.isFinal;
+
+  @override
+  bool get isPotentiallyMutatedInClosure =>
+      baseElement.isPotentiallyMutatedInClosure;
+
+  @override
+  bool get isPotentiallyMutatedInScope =>
+      baseElement.isPotentiallyMutatedInScope;
+
+  @override
+  bool get isStatic => baseElement.isStatic;
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    // TODO(brianwilkerson) We need to finish implementing the accessors used
+    // below so that we can safely invoke them.
+    super.visitChildren(visitor);
+    safelyVisitChild(baseElement.initializer, visitor);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
new file mode 100644
index 0000000..4268f1c
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -0,0 +1,2410 @@
+// 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.type;
+
+import 'dart:collection';
+
+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/member.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A [Type] that represents the type 'bottom'.
+ */
+class BottomTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static BottomTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  BottomTypeImpl._() : super(null, "<bottom>");
+
+  @override
+  int get hashCode => 0;
+
+  @override
+  bool get isBottom => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      true;
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => false;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  BottomTypeImpl substitute2(
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
+}
+
+/**
+ * Type created internally if a circular reference is ever detected.  Behaves
+ * like `dynamic`, except that when converted to a string it is displayed as
+ * `...`.
+ */
+class CircularTypeImpl extends DynamicTypeImpl {
+  CircularTypeImpl() : super._circular();
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool operator ==(Object object) => object is CircularTypeImpl;
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write('...');
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+}
+
+/**
+ * The [Type] representing the type `dynamic`.
+ */
+class DynamicTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static DynamicTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  DynamicTypeImpl._()
+      : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
+    (element as DynamicElementImpl).type = this;
+  }
+
+  /**
+   * Constructor used by [CircularTypeImpl].
+   */
+  DynamicTypeImpl._circular()
+      : super(_INSTANCE.element, Keyword.DYNAMIC.syntax);
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool get isDynamic => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // T is S
+    if (identical(this, type)) {
+      return true;
+    }
+    // else
+    return withDynamic;
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => true;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+}
+
+/**
+ * The type of a function, method, constructor, getter, or setter.
+ */
+class FunctionTypeImpl extends TypeImpl implements FunctionType {
+  /**
+   * The list of [typeArguments].
+   */
+  List<DartType> _typeArguments;
+
+  /**
+   * The list of [typeParameters].
+   */
+  List<TypeParameterElement> _typeParameters;
+
+  /**
+   * The list of [boundTypeParameters].
+   */
+  List<TypeParameterElement> _boundTypeParameters;
+
+  /**
+   * The set of typedefs which should not be expanded when exploring this type,
+   * to avoid creating infinite types in response to self-referential typedefs.
+   */
+  final List<FunctionTypeAliasElement> prunedTypedefs;
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element], and also initialize [typeArguments] to match the
+   * [typeParameters], which permits later substitution.
+   */
+  FunctionTypeImpl(ExecutableElement element,
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, null, prunedTypedefs, null, null, null);
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element], with the given [name].
+   */
+  FunctionTypeImpl.elementWithName(Element element, String name)
+      : prunedTypedefs = null,
+        super(element, name);
+
+  /**
+   * Initialize a newly created function type to be declared by the given
+   * [element].
+   */
+  FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
+      [List<FunctionTypeAliasElement> prunedTypedefs])
+      : this._(element, element?.name, prunedTypedefs, null, null, null);
+
+  /**
+   * Private constructor.
+   */
+  FunctionTypeImpl._(
+      TypeParameterizedElement element,
+      String name,
+      this.prunedTypedefs,
+      List<DartType> typeArguments,
+      List<TypeParameterElement> typeParameters,
+      List<TypeParameterElement> boundTypeParameters)
+      : super(element, name) {
+    _boundTypeParameters = boundTypeParameters ??
+        element?.typeParameters ??
+        TypeParameterElement.EMPTY_LIST;
+
+    if (typeParameters == null) {
+      // Combine the generic type variables from all enclosing contexts, except
+      // for this generic function's type variables. Those variables are
+      // tracked in [boundTypeParameters].
+      typeParameters = <TypeParameterElement>[];
+      Element e = element?.enclosingElement;
+      while (e != null) {
+        if (e is TypeParameterizedElement) {
+          typeParameters.addAll((e as TypeParameterizedElement).typeParameters);
+        }
+        e = e.enclosingElement;
+      }
+    }
+    _typeParameters = typeParameters;
+
+    if (typeArguments == null) {
+      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
+      // make it generic, which will allow it to return List<DartType> instead
+      // of List<TypeParameterType>.
+      if (typeParameters.isEmpty) {
+        typeArguments = DartType.EMPTY_LIST;
+      } else {
+        typeArguments = new List<DartType>.from(
+            typeParameters.map((t) => t.type),
+            growable: false);
+      }
+    }
+    _typeArguments = typeArguments;
+  }
+
+  /**
+   * Return the base parameter elements of this function element.
+   */
+  List<ParameterElement> get baseParameters => element.parameters;
+
+  /**
+   * Return the return type defined by this function's element.
+   */
+  DartType get baseReturnType => element.returnType;
+
+  @override
+  List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters;
+
+  @override
+  String get displayName {
+    String name = this.name;
+    if (name == null || name.length == 0) {
+      // Function types have an empty name when they are defined implicitly by
+      // either a closure or as part of a parameter declaration.
+      List<DartType> normalParameterTypes = this.normalParameterTypes;
+      List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+      Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
+      DartType returnType = this.returnType;
+      StringBuffer buffer = new StringBuffer();
+      buffer.write("(");
+      bool needsComma = false;
+      if (normalParameterTypes.length > 0) {
+        for (DartType type in normalParameterTypes) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(type.displayName);
+        }
+      }
+      if (optionalParameterTypes.length > 0) {
+        if (needsComma) {
+          buffer.write(", ");
+          needsComma = false;
+        }
+        buffer.write("[");
+        for (DartType type in optionalParameterTypes) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(type.displayName);
+        }
+        buffer.write("]");
+        needsComma = true;
+      }
+      if (namedParameterTypes.length > 0) {
+        if (needsComma) {
+          buffer.write(", ");
+          needsComma = false;
+        }
+        buffer.write("{");
+        namedParameterTypes.forEach((String name, DartType type) {
+          if (needsComma) {
+            buffer.write(", ");
+          } else {
+            needsComma = true;
+          }
+          buffer.write(name);
+          buffer.write(": ");
+          buffer.write(type.displayName);
+        });
+        buffer.write("}");
+        needsComma = true;
+      }
+      buffer.write(")");
+      buffer.write(ElementImpl.RIGHT_ARROW);
+      if (returnType == null) {
+        buffer.write("null");
+      } else {
+        buffer.write(returnType.displayName);
+      }
+      name = buffer.toString();
+    }
+    return name;
+  }
+
+  @override
+  FunctionTypedElement get element => super.element;
+
+  @override
+  int get hashCode {
+    if (element == null) {
+      return 0;
+    }
+    // Reference the arrays of parameters
+    List<DartType> normalParameterTypes = this.normalParameterTypes;
+    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+    Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
+    // Generate the hashCode
+    int code = (returnType as TypeImpl).hashCode;
+    for (int i = 0; i < normalParameterTypes.length; i++) {
+      code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode;
+    }
+    for (int i = 0; i < optionalParameterTypes.length; i++) {
+      code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode;
+    }
+    for (DartType type in namedParameterTypes) {
+      code = (code << 1) + (type as TypeImpl).hashCode;
+    }
+    return code;
+  }
+
+  /**
+   * The type arguments that were used to instantiate this function type, if
+   * any, otherwise this will return an empty list.
+   *
+   * Given a function type `f`:
+   *
+   *     f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
+   *
+   * Will always hold.
+   */
+  List<DartType> get instantiatedTypeArguments {
+    int typeParameterCount = element.type.boundTypeParameters.length;
+    if (typeParameterCount == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    // The substituted types at the end should be our bound type parameters.
+    int skipCount = typeArguments.length - typeParameterCount;
+    return new List<DartType>.from(typeArguments.skip(skipCount));
+  }
+
+  @override
+  Map<String, DartType> get namedParameterTypes {
+    LinkedHashMap<String, DartType> namedParameterTypes =
+        new LinkedHashMap<String, DartType>();
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return namedParameterTypes;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.NAMED) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        namedParameterTypes[parameter.name] = type;
+      }
+    }
+    return namedParameterTypes;
+  }
+
+  /**
+   * Determine the new set of typedefs which should be pruned when expanding
+   * this function type.
+   */
+  List<FunctionTypeAliasElement> get newPrune {
+    Element element = this.element;
+    if (element is FunctionTypeAliasElement && !element.isSynthetic) {
+      // This typedef should be pruned, along with anything that was previously
+      // pruned.
+      if (prunedTypedefs == null) {
+        return <FunctionTypeAliasElement>[element];
+      } else {
+        return new List<FunctionTypeAliasElement>.from(prunedTypedefs)
+          ..add(element);
+      }
+    } else {
+      // This is not a typedef, so nothing additional needs to be pruned.
+      return prunedTypedefs;
+    }
+  }
+
+  @override
+  List<DartType> get normalParameterTypes {
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    List<DartType> types = new List<DartType>();
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.REQUIRED) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        types.add(type);
+      }
+    }
+    return types;
+  }
+
+  @override
+  List<DartType> get optionalParameterTypes {
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.length == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    List<DartType> typeParameters =
+        TypeParameterTypeImpl.getTypes(this.typeParameters);
+    List<DartType> types = new List<DartType>();
+    for (ParameterElement parameter in parameters) {
+      if (parameter.parameterKind == ParameterKind.POSITIONAL) {
+        DartType type = parameter.type;
+        if (typeArguments.length != 0 &&
+            typeArguments.length == typeParameters.length) {
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
+        } else {
+          type = (type as TypeImpl).pruned(newPrune);
+        }
+        types.add(type);
+      }
+    }
+    return types;
+  }
+
+  /**
+   * If this is an instantiation of a generic function type, this will get
+   * the original function from which it was instantiated.
+   *
+   * Otherwise, this will return `this`.
+   */
+  FunctionTypeImpl get originalFunction {
+    if (element.type.boundTypeParameters.isEmpty) {
+      return this;
+    }
+    return (element.type as FunctionTypeImpl).substitute2(typeArguments,
+        TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
+  }
+
+  @override
+  List<ParameterElement> get parameters {
+    List<ParameterElement> baseParameters = this.baseParameters;
+    // no parameters, quick return
+    int parameterCount = baseParameters.length;
+    if (parameterCount == 0) {
+      return baseParameters;
+    }
+    // create specialized parameters
+    List<ParameterElement> specializedParameters =
+        new List<ParameterElement>(parameterCount);
+    for (int i = 0; i < parameterCount; i++) {
+      specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
+    }
+    return specializedParameters;
+  }
+
+  @override
+  DartType get returnType {
+    DartType baseReturnType = this.baseReturnType;
+    if (baseReturnType == null) {
+      // TODO(brianwilkerson) This is a patch. The return type should never be
+      // null and we need to understand why it is and fix it.
+      return DynamicTypeImpl.instance;
+    }
+    // If there are no arguments to substitute, or if the arguments size doesn't
+    // match the parameter size, return the base return type.
+    if (typeArguments.length == 0 ||
+        typeArguments.length != typeParameters.length) {
+      return (baseReturnType as TypeImpl).pruned(newPrune);
+    }
+    return (baseReturnType as TypeImpl).substitute2(typeArguments,
+        TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
+  }
+
+  /**
+   * A list containing the actual types of the type arguments.
+   */
+  List<DartType> get typeArguments => _typeArguments;
+
+  @override
+  List<TypeParameterElement> get typeParameters => _typeParameters;
+
+  @override
+  bool operator ==(Object object) {
+    if (object is! FunctionTypeImpl) {
+      return false;
+    }
+    FunctionTypeImpl otherType = object as FunctionTypeImpl;
+    if (boundTypeParameters.length != otherType.boundTypeParameters.length) {
+      return false;
+    }
+    // `<T>T -> T` should be equal to `<U>U -> U`
+    // To test this, we instantiate both types with the same (unique) type
+    // variables, and see if the result is equal.
+    if (boundTypeParameters.isNotEmpty) {
+      List<DartType> instantiateTypeArgs = new List<DartType>();
+      List<DartType> variablesThis = new List<DartType>();
+      List<DartType> variablesOther = new List<DartType>();
+      for (int i = 0; i < boundTypeParameters.length; i++) {
+        TypeParameterElement pThis = boundTypeParameters[i];
+        TypeParameterElement pOther = otherType.boundTypeParameters[i];
+        TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
+            new TypeParameterElementImpl(pThis.name, -1));
+        instantiateTypeArgs.add(pFresh);
+        variablesThis.add(pThis.type);
+        variablesOther.add(pOther.type);
+        // Check that the bounds are equal after equating the previous
+        // bound variables.
+        if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
+            pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
+          return false;
+        }
+      }
+      // After instantiation, they will no longer have boundTypeParameters,
+      // so we will continue below.
+      return this.instantiate(instantiateTypeArgs) ==
+          otherType.instantiate(instantiateTypeArgs);
+    }
+
+    return returnType == otherType.returnType &&
+        TypeImpl.equalArrays(
+            normalParameterTypes, otherType.normalParameterTypes) &&
+        TypeImpl.equalArrays(
+            optionalParameterTypes, otherType.optionalParameterTypes) &&
+        _equals(namedParameterTypes, otherType.namedParameterTypes);
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    if (boundTypeParameters.isNotEmpty) {
+      // To print a type with type variables, first make sure we have unique
+      // variable names to print.
+      Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
+      _freeVariablesInFunctionType(this, freeVariables);
+
+      Set<String> namesToAvoid = new HashSet<String>();
+      for (DartType arg in freeVariables) {
+        if (arg is TypeParameterType) {
+          namesToAvoid.add(arg.displayName);
+        }
+      }
+
+      List<DartType> instantiateTypeArgs = new List<DartType>();
+      List<DartType> variables = new List<DartType>();
+      buffer.write("<");
+      for (TypeParameterElement e in boundTypeParameters) {
+        if (e != boundTypeParameters[0]) {
+          buffer.write(",");
+        }
+        String name = e.name;
+        int counter = 0;
+        while (!namesToAvoid.add(name)) {
+          // Unicode subscript-zero is U+2080, zero is U+0030. Other digits
+          // are sequential from there. Thus +0x2050 will get us the subscript.
+          String subscript = new String.fromCharCodes(
+              counter.toString().codeUnits.map((n) => n + 0x2050));
+
+          name = e.name + subscript;
+          counter++;
+        }
+        TypeParameterTypeImpl t =
+            new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
+        t.appendTo(buffer);
+        instantiateTypeArgs.add(t);
+        variables.add(e.type);
+        if (e.bound != null) {
+          buffer.write(" extends ");
+          TypeImpl renamed =
+              e.bound.substitute2(instantiateTypeArgs, variables);
+          renamed.appendTo(buffer);
+        }
+      }
+      buffer.write(">");
+
+      // Instantiate it and print the resulting type. After instantiation, it
+      // will no longer have boundTypeParameters, so we will continue below.
+      this.instantiate(instantiateTypeArgs).appendTo(buffer);
+      return;
+    }
+
+    List<DartType> normalParameterTypes = this.normalParameterTypes;
+    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
+    Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
+    DartType returnType = this.returnType;
+    buffer.write("(");
+    bool needsComma = false;
+    if (normalParameterTypes.isNotEmpty) {
+      for (DartType type in normalParameterTypes) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        (type as TypeImpl).appendTo(buffer);
+      }
+    }
+    if (optionalParameterTypes.isNotEmpty) {
+      if (needsComma) {
+        buffer.write(", ");
+        needsComma = false;
+      }
+      buffer.write("[");
+      for (DartType type in optionalParameterTypes) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        (type as TypeImpl).appendTo(buffer);
+      }
+      buffer.write("]");
+      needsComma = true;
+    }
+    if (namedParameterTypes.isNotEmpty) {
+      if (needsComma) {
+        buffer.write(", ");
+        needsComma = false;
+      }
+      buffer.write("{");
+      namedParameterTypes.forEach((String name, DartType type) {
+        if (needsComma) {
+          buffer.write(", ");
+        } else {
+          needsComma = true;
+        }
+        buffer.write(name);
+        buffer.write(": ");
+        (type as TypeImpl).appendTo(buffer);
+      });
+      buffer.write("}");
+      needsComma = true;
+    }
+    buffer.write(")");
+    buffer.write(ElementImpl.RIGHT_ARROW);
+    if (returnType == null) {
+      buffer.write("null");
+    } else {
+      (returnType as TypeImpl).appendTo(buffer);
+    }
+  }
+
+  @override
+  FunctionTypeImpl instantiate(List<DartType> argumentTypes) {
+    if (argumentTypes.length != boundTypeParameters.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != "
+          "boundTypeParameters.length (${boundTypeParameters.length})");
+    }
+    if (argumentTypes.isEmpty) {
+      return this;
+    }
+
+    // Given:
+    //     {U/T} <S> T -> S
+    // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
+    // and <S> represents the boundTypeParameters.
+    //
+    // Now instantiate([V]), and the result should be:
+    //     {U/T, V/S} T -> S.
+    List<TypeParameterElement> newTypeParams = typeParameters.toList();
+    List<DartType> newTypeArgs = typeArguments.toList();
+    newTypeParams.addAll(boundTypeParameters);
+    newTypeArgs.addAll(argumentTypes);
+
+    return new FunctionTypeImpl._(element, name, prunedTypedefs, newTypeArgs,
+        newTypeParams, TypeParameterElement.EMPTY_LIST);
+  }
+
+  @override
+  bool isAssignableTo(DartType type) {
+    // A function type T may be assigned to a function type S, written T <=> S,
+    // iff T <: S.
+    return isSubtypeOf(type);
+  }
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // Note: visitedElements is only used for breaking recursion in the type
+    // hierarchy; we don't use it when recursing into the function type.
+
+    // trivial base cases
+    if (type == null) {
+      return false;
+    } else if (identical(this, type) ||
+        type.isDynamic ||
+        type.isDartCoreFunction ||
+        type.isObject) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    List<DartType> tTypes = t.normalParameterTypes;
+    List<DartType> tOpTypes = t.optionalParameterTypes;
+    List<DartType> sTypes = s.normalParameterTypes;
+    List<DartType> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters,
+    // return false.
+    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
+        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+      return false;
+    }
+    // named parameters case
+    if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal, and check that
+      // every t_i is more specific than every s_i
+      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+        return false;
+      } else if (t.normalParameterTypes.length > 0) {
+        for (int i = 0; i < tTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      }
+      Map<String, DartType> namedTypesT = t.namedParameterTypes;
+      Map<String, DartType> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more
+      // named parameter types than this
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      // Loop through each element in S verifying that T has a matching
+      // parameter name and that the corresponding type is more specific then
+      // the type in S.
+      for (String keyS in namedTypesS.keys) {
+        DartType typeT = namedTypesT[keyS];
+        if (typeT == null) {
+          return false;
+        }
+        if (!(typeT as TypeImpl)
+            .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    } else {
+      // positional parameter case
+      int tArgLength = tTypes.length + tOpTypes.length;
+      int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or equal
+      // to the number of parameters in s and that the number of required
+      // parameters in s is greater than or equal to the number of required
+      // parameters in t.
+      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+        return false;
+      }
+      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
+        for (int i = 0; i < sTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      } else {
+        // Else, we do have positional parameters, copy required and positional
+        // parameter types into arrays to do the compare (for loop below).
+        List<DartType> tAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < tTypes.length; i++) {
+          tAllTypes[i] = tTypes[i];
+        }
+        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
+          tAllTypes[i] = tOpTypes[j];
+        }
+        List<DartType> sAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < sTypes.length; i++) {
+          sAllTypes[i] = sTypes[i];
+        }
+        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
+          sAllTypes[i] = sOpTypes[j];
+        }
+        for (int i = 0; i < sAllTypes.length; i++) {
+          if (!(tAllTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
+            return false;
+          }
+        }
+      }
+    }
+    DartType tRetType = t.returnType;
+    DartType sRetType = s.returnType;
+    return sRetType.isVoid ||
+        (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic);
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) {
+    // trivial base cases
+    if (type == null) {
+      return false;
+    } else if (identical(this, type) ||
+        type.isDynamic ||
+        type.isDartCoreFunction ||
+        type.isObject) {
+      return true;
+    } else if (type is! FunctionType) {
+      return false;
+    } else if (this == type) {
+      return true;
+    }
+    FunctionType t = this;
+    FunctionType s = type as FunctionType;
+    List<DartType> tTypes = t.normalParameterTypes;
+    List<DartType> tOpTypes = t.optionalParameterTypes;
+    List<DartType> sTypes = s.normalParameterTypes;
+    List<DartType> sOpTypes = s.optionalParameterTypes;
+    // If one function has positional and the other has named parameters,
+    // return false.
+    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
+        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
+      return false;
+    }
+    // named parameters case
+    if (t.namedParameterTypes.length > 0) {
+      // check that the number of required parameters are equal,
+      // and check that every t_i is assignable to every s_i
+      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
+        return false;
+      } else if (t.normalParameterTypes.length > 0) {
+        for (int i = 0; i < tTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
+            return false;
+          }
+        }
+      }
+      Map<String, DartType> namedTypesT = t.namedParameterTypes;
+      Map<String, DartType> namedTypesS = s.namedParameterTypes;
+      // if k >= m is false, return false: the passed function type has more
+      // named parameter types than this
+      if (namedTypesT.length < namedTypesS.length) {
+        return false;
+      }
+      // Loop through each element in S verifying that T has a matching
+      // parameter name and that the corresponding type is assignable to the
+      // type in S.
+      for (String keyS in namedTypesS.keys) {
+        DartType typeT = namedTypesT[keyS];
+        if (typeT == null) {
+          return false;
+        }
+        if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) {
+          return false;
+        }
+      }
+    } else if (s.namedParameterTypes.length > 0) {
+      return false;
+    } else {
+      // positional parameter case
+      int tArgLength = tTypes.length + tOpTypes.length;
+      int sArgLength = sTypes.length + sOpTypes.length;
+      // Check that the total number of parameters in t is greater than or
+      // equal to the number of parameters in s and that the number of
+      // required parameters in s is greater than or equal to the number of
+      // required parameters in t.
+      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
+        return false;
+      }
+      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
+        // No positional arguments, don't copy contents to new array
+        for (int i = 0; i < sTypes.length; i++) {
+          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
+            return false;
+          }
+        }
+      } else {
+        // Else, we do have positional parameters, copy required and
+        // positional parameter types into arrays to do the compare (for loop
+        // below).
+        List<DartType> tAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < tTypes.length; i++) {
+          tAllTypes[i] = tTypes[i];
+        }
+        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
+          tAllTypes[i] = tOpTypes[j];
+        }
+        List<DartType> sAllTypes = new List<DartType>(sArgLength);
+        for (int i = 0; i < sTypes.length; i++) {
+          sAllTypes[i] = sTypes[i];
+        }
+        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
+          sAllTypes[i] = sOpTypes[j];
+        }
+        for (int i = 0; i < sAllTypes.length; i++) {
+          if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) {
+            return false;
+          }
+        }
+      }
+    }
+    DartType tRetType = t.returnType;
+    DartType sRetType = s.returnType;
+    return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType);
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) {
+    if (prune == null) {
+      return this;
+    } else if (prune.contains(element)) {
+      // Circularity found.  Prune the type declaration.
+      return new CircularTypeImpl();
+    } else {
+      // There should never be a reason to prune a type that has already been
+      // pruned, since pruning is only done when expanding a function type
+      // alias, and function type aliases are always expanded by starting with
+      // base types.
+      assert(this.prunedTypedefs == null);
+      List<DartType> typeArgs = typeArguments
+          .map((TypeImpl t) => t.pruned(prune))
+          .toList(growable: false);
+      return new FunctionTypeImpl._(element, name, prune, typeArgs,
+          _typeParameters, _boundTypeParameters);
+    }
+  }
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    // Pruned types should only ever result from performing type variable
+    // substitution, and it doesn't make sense to substitute again after
+    // substituting once.
+    assert(this.prunedTypedefs == null);
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    Element element = this.element;
+    if (prune != null && prune.contains(element)) {
+      // Circularity found.  Prune the type declaration.
+      return new CircularTypeImpl();
+    }
+    if (argumentTypes.length == 0) {
+      return this.pruned(prune);
+    }
+    List<DartType> typeArgs =
+        TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
+    return new FunctionTypeImpl._(
+        element, name, prune, typeArgs, _typeParameters, _boundTypeParameters);
+  }
+
+  @override
+  FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
+      substitute2(argumentTypes, typeArguments);
+
+  void _freeVariablesInFunctionType(
+      FunctionType type, Set<TypeParameterType> free) {
+    // Make some fresh variables to avoid capture.
+    List<DartType> typeArgs = DartType.EMPTY_LIST;
+    if (type.boundTypeParameters.isNotEmpty) {
+      typeArgs = new List<DartType>.from(type.boundTypeParameters.map((e) =>
+          new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
+
+      type = type.instantiate(typeArgs);
+    }
+
+    for (ParameterElement p in type.parameters) {
+      _freeVariablesInType(p.type, free);
+    }
+    _freeVariablesInType(type.returnType, free);
+
+    // Remove all of our bound variables.
+    free.removeAll(typeArgs);
+  }
+
+  void _freeVariablesInInterfaceType(
+      InterfaceType type, Set<TypeParameterType> free) {
+    for (DartType typeArg in type.typeArguments) {
+      _freeVariablesInType(typeArg, free);
+    }
+  }
+
+  void _freeVariablesInType(DartType type, Set<TypeParameterType> free) {
+    if (type is TypeParameterType) {
+      free.add(type);
+    } else if (type is FunctionType) {
+      _freeVariablesInFunctionType(type, free);
+    } else if (type is InterfaceType) {
+      _freeVariablesInInterfaceType(type, free);
+    }
+  }
+
+  /**
+   * 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
+   * same order in which those entries were added to the map.
+   */
+  static bool _equals(
+      Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
+    if (secondTypes.length != firstTypes.length) {
+      return false;
+    }
+    Iterator<String> firstKeys = firstTypes.keys.iterator;
+    Iterator<String> secondKeys = secondTypes.keys.iterator;
+    while (firstKeys.moveNext() && secondKeys.moveNext()) {
+      String firstKey = firstKeys.current;
+      String secondKey = secondKeys.current;
+      TypeImpl firstType = firstTypes[firstKey];
+      TypeImpl secondType = secondTypes[secondKey];
+      if (firstKey != secondKey || firstType != secondType) {
+        return false;
+      }
+    }
+    return true;
+  }
+}
+
+/**
+ * A concrete implementation of an [InterfaceType].
+ */
+class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
+  /**
+   * A list containing the actual types of the type arguments.
+   */
+  List<DartType> typeArguments = DartType.EMPTY_LIST;
+
+  /**
+   * The set of typedefs which should not be expanded when exploring this type,
+   * to avoid creating infinite types in response to self-referential typedefs.
+   */
+  final List<FunctionTypeAliasElement> prunedTypedefs;
+
+  /**
+   * Initialize a newly created type to be declared by the given [element].
+   */
+  InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs])
+      : super(element, element.displayName);
+
+  /**
+   * Initialize a newly created type to be declared by the given [element],
+   * with the given [name].
+   */
+  InterfaceTypeImpl.elementWithName(ClassElement element, String name)
+      : prunedTypedefs = null,
+        super(element, name);
+
+  /**
+   * Initialize a newly created type to have the given [name]. This constructor
+   * should only be used in cases where there is no declaration of the type.
+   */
+  InterfaceTypeImpl.named(String name)
+      : prunedTypedefs = null,
+        super(null, name);
+
+  /**
+   * Private constructor.
+   */
+  InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
+      : super(element, name);
+
+  @override
+  List<PropertyAccessorElement> get accessors {
+    List<PropertyAccessorElement> accessors = element.accessors;
+    List<PropertyAccessorElement> members =
+        new List<PropertyAccessorElement>(accessors.length);
+    for (int i = 0; i < accessors.length; i++) {
+      members[i] = PropertyAccessorMember.from(accessors[i], this);
+    }
+    return members;
+  }
+
+  @override
+  List<ConstructorElement> get constructors {
+    List<ConstructorElement> constructors = element.constructors;
+    List<ConstructorElement> members =
+        new List<ConstructorElement>(constructors.length);
+    for (int i = 0; i < constructors.length; i++) {
+      members[i] = ConstructorMember.from(constructors[i], this);
+    }
+    return members;
+  }
+
+  @override
+  String get displayName {
+    String name = this.name;
+    List<DartType> typeArguments = this.typeArguments;
+    bool allDynamic = true;
+    for (DartType type in typeArguments) {
+      if (type != null && !type.isDynamic) {
+        allDynamic = false;
+        break;
+      }
+    }
+    // If there is at least one non-dynamic type, then list them out
+    if (!allDynamic) {
+      StringBuffer buffer = new StringBuffer();
+      buffer.write(name);
+      buffer.write("<");
+      for (int i = 0; i < typeArguments.length; i++) {
+        if (i != 0) {
+          buffer.write(", ");
+        }
+        DartType typeArg = typeArguments[i];
+        buffer.write(typeArg.displayName);
+      }
+      buffer.write(">");
+      name = buffer.toString();
+    }
+    return name;
+  }
+
+  @override
+  ClassElement get element => super.element as ClassElement;
+
+  @override
+  int get hashCode {
+    ClassElement element = this.element;
+    if (element == null) {
+      return 0;
+    }
+    return element.hashCode;
+  }
+
+  @override
+  List<InterfaceType> get interfaces {
+    ClassElement classElement = element;
+    List<InterfaceType> interfaces = classElement.interfaces;
+    List<TypeParameterElement> typeParameters = classElement.typeParameters;
+    List<DartType> parameterTypes = classElement.type.typeArguments;
+    if (typeParameters.length == 0) {
+      return interfaces;
+    }
+    int count = interfaces.length;
+    List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
+    for (int i = 0; i < count; i++) {
+      typedInterfaces[i] =
+          interfaces[i].substitute2(typeArguments, parameterTypes);
+    }
+    return typedInterfaces;
+  }
+
+  @override
+  bool get isDartCoreFunction {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "Function" && element.library.isDartCore;
+  }
+
+  @override
+  bool get isObject => element.supertype == null;
+
+  @override
+  List<MethodElement> get methods {
+    List<MethodElement> methods = element.methods;
+    List<MethodElement> members = new List<MethodElement>(methods.length);
+    for (int i = 0; i < methods.length; i++) {
+      members[i] = MethodMember.from(methods[i], this);
+    }
+    return members;
+  }
+
+  @override
+  List<InterfaceType> get mixins {
+    ClassElement classElement = element;
+    List<InterfaceType> mixins = classElement.mixins;
+    List<TypeParameterElement> typeParameters = classElement.typeParameters;
+    List<DartType> parameterTypes = classElement.type.typeArguments;
+    if (typeParameters.length == 0) {
+      return mixins;
+    }
+    int count = mixins.length;
+    List<InterfaceType> typedMixins = new List<InterfaceType>(count);
+    for (int i = 0; i < count; i++) {
+      typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
+    }
+    return typedMixins;
+  }
+
+  @override
+  InterfaceType get superclass {
+    ClassElement classElement = element;
+    InterfaceType supertype = classElement.supertype;
+    if (supertype == null) {
+      return null;
+    }
+    List<DartType> typeParameters = classElement.type.typeArguments;
+    if (typeArguments.length == 0 ||
+        typeArguments.length != typeParameters.length) {
+      return supertype;
+    }
+    return supertype.substitute2(typeArguments, typeParameters);
+  }
+
+  @override
+  List<TypeParameterElement> get typeParameters => element.typeParameters;
+
+  @override
+  bool operator ==(Object object) {
+    if (identical(object, this)) {
+      return true;
+    }
+    if (object is! InterfaceTypeImpl) {
+      return false;
+    }
+    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
+    return (element == otherType.element) &&
+        TypeImpl.equalArrays(typeArguments, otherType.typeArguments);
+  }
+
+  @override
+  void appendTo(StringBuffer buffer) {
+    buffer.write(name);
+    int argumentCount = typeArguments.length;
+    if (argumentCount > 0) {
+      buffer.write("<");
+      for (int i = 0; i < argumentCount; i++) {
+        if (i > 0) {
+          buffer.write(", ");
+        }
+        (typeArguments[i] as TypeImpl).appendTo(buffer);
+      }
+      buffer.write(">");
+    }
+  }
+
+  @override
+  PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember
+      .from((element as ClassElementImpl).getGetter(getterName), this);
+
+  @override
+  MethodElement getMethod(String methodName) => MethodMember.from(
+      (element as ClassElementImpl).getMethod(methodName), this);
+
+  @override
+  PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember
+      .from((element as ClassElementImpl).getSetter(setterName), this);
+
+  @override
+  bool isDirectSupertypeOf(InterfaceType type) {
+    InterfaceType i = this;
+    InterfaceType j = type;
+    ClassElement jElement = j.element;
+    InterfaceType supertype = jElement.supertype;
+    //
+    // If J has no direct supertype then it is Object, and Object has no direct
+    // supertypes.
+    //
+    if (supertype == null) {
+      return false;
+    }
+    //
+    // I is listed in the extends clause of J.
+    //
+    List<DartType> jArgs = j.typeArguments;
+    List<DartType> jVars = jElement.type.typeArguments;
+    supertype = supertype.substitute2(jArgs, jVars);
+    if (supertype == i) {
+      return true;
+    }
+    //
+    // I is listed in the implements clause of J.
+    //
+    for (InterfaceType interfaceType in jElement.interfaces) {
+      interfaceType = interfaceType.substitute2(jArgs, jVars);
+      if (interfaceType == i) {
+        return true;
+      }
+    }
+    //
+    // I is listed in the with clause of J.
+    //
+    for (InterfaceType mixinType in jElement.mixins) {
+      mixinType = mixinType.substitute2(jArgs, jVars);
+      if (mixinType == i) {
+        return true;
+      }
+    }
+    //
+    // J is a mixin application of the mixin of I.
+    //
+    // TODO(brianwilkerson) Determine whether this needs to be implemented or
+    // whether it is covered by the case above.
+    return false;
+  }
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    //
+    // S is dynamic.
+    // The test to determine whether S is dynamic is done here because dynamic
+    // is not an instance of InterfaceType.
+    //
+    if (type.isDynamic) {
+      return true;
+    }
+    //
+    // A type T is more specific than a type S, written T << S,
+    // if one of the following conditions is met:
+    //
+    // Reflexivity: T is S.
+    //
+    if (this == type) {
+      return true;
+    }
+    if (type is InterfaceType) {
+      //
+      // T is bottom. (This case is handled by the class BottomTypeImpl.)
+      //
+      // Direct supertype: S is a direct supertype of T.
+      //
+      if (type.isDirectSupertypeOf(this)) {
+        return true;
+      }
+      //
+      // Covariance: T is of the form I<T1, ..., Tn> and S is of the form
+      // I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
+      //
+      ClassElement tElement = this.element;
+      ClassElement sElement = type.element;
+      if (tElement == sElement) {
+        List<DartType> tArguments = typeArguments;
+        List<DartType> sArguments = type.typeArguments;
+        if (tArguments.length != sArguments.length) {
+          return false;
+        }
+        for (int i = 0; i < tArguments.length; i++) {
+          if (!(tArguments[i] as TypeImpl)
+              .isMoreSpecificThan(sArguments[i], withDynamic)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    }
+    //
+    // Transitivity: T << U and U << S.
+    //
+    // First check for infinite loops
+    if (element == null) {
+      return false;
+    }
+    if (visitedElements == null) {
+      visitedElements = new HashSet<ClassElement>();
+    } else if (visitedElements.contains(element)) {
+      return false;
+    }
+    visitedElements.add(element);
+    try {
+      // Iterate over all of the types U that are more specific than T because
+      // they are direct supertypes of T and return true if any of them are more
+      // specific than S.
+      InterfaceTypeImpl supertype = superclass;
+      if (supertype != null &&
+          supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) {
+        return true;
+      }
+      for (InterfaceType interfaceType in interfaces) {
+        if ((interfaceType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      for (InterfaceType mixinType in mixins) {
+        if ((mixinType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      // If a type I includes an instance method named `call`, and the type of
+      // `call` is the function type F, then I is considered to be more specific
+      // than F.
+      MethodElement callMethod = getMethod('call');
+      if (callMethod != null && !callMethod.isStatic) {
+        FunctionTypeImpl callType = callMethod.type;
+        if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) {
+          return true;
+        }
+      }
+      return false;
+    } finally {
+      visitedElements.remove(element);
+    }
+  }
+
+  @override
+  ConstructorElement lookUpConstructor(
+      String constructorName, LibraryElement library) {
+    // prepare base ConstructorElement
+    ConstructorElement constructorElement;
+    if (constructorName == null) {
+      constructorElement = element.unnamedConstructor;
+    } else {
+      constructorElement = element.getNamedConstructor(constructorName);
+    }
+    // not found or not accessible
+    if (constructorElement == null ||
+        !constructorElement.isAccessibleIn(library)) {
+      return null;
+    }
+    // return member
+    return ConstructorMember.from(constructorElement, this);
+  }
+
+  @override
+  PropertyAccessorElement lookUpGetter(
+      String getterName, LibraryElement library) {
+    PropertyAccessorElement element = getGetter(getterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpGetterInSuperclass(getterName, library);
+  }
+
+  @override
+  PropertyAccessorElement lookUpGetterInSuperclass(
+      String getterName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      PropertyAccessorElement element = mixin.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      PropertyAccessorElement element = supertype.getGetter(getterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getGetter(getterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement lookUpInheritedGetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpGetter(name, library);
+    } else {
+      result = lookUpGetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
+  }
+
+  @override
+  ExecutableElement lookUpInheritedGetterOrMethod(String name,
+      {LibraryElement library}) {
+    ExecutableElement result =
+        lookUpGetter(name, library) ?? lookUpMethod(name, library);
+
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(
+        this,
+        false,
+        library,
+        new HashSet<ClassElement>(),
+        (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
+  }
+
+  @override
+  MethodElement lookUpInheritedMethod(String name,
+      {LibraryElement library, bool thisType: true}) {
+    MethodElement result;
+    if (thisType) {
+      result = lookUpMethod(name, library);
+    } else {
+      result = lookUpMethodInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
+  }
+
+  @override
+  PropertyAccessorElement lookUpInheritedSetter(String name,
+      {LibraryElement library, bool thisType: true}) {
+    PropertyAccessorElement result;
+    if (thisType) {
+      result = lookUpSetter(name, library);
+    } else {
+      result = lookUpSetterInSuperclass(name, library);
+    }
+    if (result != null) {
+      return result;
+    }
+    return _lookUpMemberInInterfaces(this, false, library,
+        new HashSet<ClassElement>(), (t) => t.getSetter(name));
+  }
+
+  @override
+  MethodElement lookUpMethod(String methodName, LibraryElement library) {
+    MethodElement element = getMethod(methodName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpMethodInSuperclass(methodName, library);
+  }
+
+  @override
+  MethodElement lookUpMethodInSuperclass(
+      String methodName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      MethodElement element = mixin.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      MethodElement element = supertype.getMethod(methodName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getMethod(methodName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  PropertyAccessorElement lookUpSetter(
+      String setterName, LibraryElement library) {
+    PropertyAccessorElement element = getSetter(setterName);
+    if (element != null && element.isAccessibleIn(library)) {
+      return element;
+    }
+    return lookUpSetterInSuperclass(setterName, library);
+  }
+
+  @override
+  PropertyAccessorElement lookUpSetterInSuperclass(
+      String setterName, LibraryElement library) {
+    for (InterfaceType mixin in mixins.reversed) {
+      PropertyAccessorElement element = mixin.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+    }
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    InterfaceType supertype = superclass;
+    ClassElement supertypeElement =
+        supertype == null ? null : supertype.element;
+    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
+      visitedClasses.add(supertypeElement);
+      PropertyAccessorElement element = supertype.getSetter(setterName);
+      if (element != null && element.isAccessibleIn(library)) {
+        return element;
+      }
+      for (InterfaceType mixin in supertype.mixins.reversed) {
+        element = mixin.getSetter(setterName);
+        if (element != null && element.isAccessibleIn(library)) {
+          return element;
+        }
+      }
+      supertype = supertype.superclass;
+      supertypeElement = supertype == null ? null : supertype.element;
+    }
+    return null;
+  }
+
+  @override
+  InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) {
+    if (prune == null) {
+      return this;
+    } else {
+      // There should never be a reason to prune a type that has already been
+      // pruned, since pruning is only done when expanding a function type
+      // alias, and function type aliases are always expanded by starting with
+      // base types.
+      assert(this.prunedTypedefs == null);
+      InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
+      result.typeArguments =
+          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
+      return result;
+    }
+  }
+
+  @override
+  InterfaceTypeImpl substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    if (argumentTypes.length != parameterTypes.length) {
+      throw new IllegalArgumentException(
+          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
+    }
+    if (argumentTypes.length == 0 || typeArguments.length == 0) {
+      return this.pruned(prune);
+    }
+    List<DartType> newTypeArguments = TypeImpl.substitute(
+        typeArguments, argumentTypes, parameterTypes, prune);
+    if (JavaArrays.equals(newTypeArguments, typeArguments)) {
+      return this;
+    }
+    InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
+    newType.typeArguments = newTypeArguments;
+    return newType;
+  }
+
+  @override
+  InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
+      substitute2(argumentTypes, typeArguments);
+
+  /**
+   * Compute the least upper bound of types [i] and [j], both of which are
+   * known to be interface types.
+   *
+   * In the event that the algorithm fails (which might occur due to a bug in
+   * the analyzer), `null` is returned.
+   */
+  static InterfaceType computeLeastUpperBound(
+      InterfaceType i, InterfaceType j) {
+    // compute set of supertypes
+    Set<InterfaceType> si = computeSuperinterfaceSet(i);
+    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
+    // union si with i and sj with j
+    si.add(i);
+    sj.add(j);
+    // compute intersection, reference as set 's'
+    List<InterfaceType> s = _intersection(si, sj);
+    // for each element in Set s, compute the largest inheritance path to Object
+    List<int> depths = new List<int>.filled(s.length, 0);
+    int maxDepth = 0;
+    for (int n = 0; n < s.length; n++) {
+      depths[n] = computeLongestInheritancePathToObject(s[n]);
+      if (depths[n] > maxDepth) {
+        maxDepth = depths[n];
+      }
+    }
+    // ensure that the currently computed maxDepth is unique,
+    // otherwise, decrement and test for uniqueness again
+    for (; maxDepth >= 0; maxDepth--) {
+      int indexOfLeastUpperBound = -1;
+      int numberOfTypesAtMaxDepth = 0;
+      for (int m = 0; m < depths.length; m++) {
+        if (depths[m] == maxDepth) {
+          numberOfTypesAtMaxDepth++;
+          indexOfLeastUpperBound = m;
+        }
+      }
+      if (numberOfTypesAtMaxDepth == 1) {
+        return s[indexOfLeastUpperBound];
+      }
+    }
+    // Should be impossible--there should always be exactly one type with the
+    // maximum depth.
+    assert(false);
+    return null;
+  }
+
+  /**
+   * Return the length of the longest inheritance path from the given [type] to
+   * Object.
+   *
+   * See [computeLeastUpperBound].
+   */
+  static int computeLongestInheritancePathToObject(InterfaceType type) =>
+      _computeLongestInheritancePathToObject(
+          type, 0, new HashSet<ClassElement>());
+
+  /**
+   * Returns the set of all superinterfaces of the given [type].
+   *
+   * See [computeLeastUpperBound].
+   */
+  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
+      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
+
+  /**
+   * Returns a "smart" version of the "least upper bound" of the given types.
+   *
+   * If these types have the same element and differ only in terms of the type
+   * arguments, attempts to find a compatible set of type arguments.
+   *
+   * Otherwise, calls [DartType.getLeastUpperBound].
+   */
+  static InterfaceType getSmartLeastUpperBound(
+      InterfaceType first, InterfaceType second) {
+    // TODO(paulberry): this needs to be deprecated and replaced with a method
+    // in [TypeSystem], since it relies on the deprecated functionality of
+    // [DartType.getLeastUpperBound].
+    if (first.element == second.element) {
+      return _leastUpperBound(first, second);
+    }
+    AnalysisContext context = first.element.context;
+    return context.typeSystem
+        .getLeastUpperBound(context.typeProvider, first, second);
+  }
+
+  /**
+   * Return the length of the longest inheritance path from a subtype of the
+   * given [type] to Object, where the given [depth] is the length of the
+   * longest path from the subtype to this type. The set of [visitedTypes] is
+   * used to prevent infinite recursion in the case of a cyclic type structure.
+   *
+   * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
+   */
+  static int _computeLongestInheritancePathToObject(
+      InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
+    ClassElement classElement = type.element;
+    // Object case
+    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
+      return depth;
+    }
+    int longestPath = 1;
+    try {
+      visitedTypes.add(classElement);
+      List<InterfaceType> superinterfaces = classElement.interfaces;
+      int pathLength;
+      if (superinterfaces.length > 0) {
+        // loop through each of the superinterfaces recursively calling this
+        // method and keeping track of the longest path to return
+        for (InterfaceType superinterface in superinterfaces) {
+          pathLength = _computeLongestInheritancePathToObject(
+              superinterface, depth + 1, visitedTypes);
+          if (pathLength > longestPath) {
+            longestPath = pathLength;
+          }
+        }
+      }
+      // finally, perform this same check on the super type
+      // TODO(brianwilkerson) Does this also need to add in the number of mixin
+      // classes?
+      InterfaceType supertype = classElement.supertype;
+      pathLength = _computeLongestInheritancePathToObject(
+          supertype, depth + 1, visitedTypes);
+      if (pathLength > longestPath) {
+        longestPath = pathLength;
+      }
+    } finally {
+      visitedTypes.remove(classElement);
+    }
+    return longestPath;
+  }
+
+  /**
+   * Add all of the superinterfaces of the given [type] to the given [set].
+   * Return the [set] as a convenience.
+   *
+   * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
+   */
+  static Set<InterfaceType> _computeSuperinterfaceSet(
+      InterfaceType type, HashSet<InterfaceType> set) {
+    Element element = type.element;
+    if (element != null) {
+      List<InterfaceType> superinterfaces = type.interfaces;
+      for (InterfaceType superinterface in superinterfaces) {
+        if (set.add(superinterface)) {
+          _computeSuperinterfaceSet(superinterface, set);
+        }
+      }
+      InterfaceType supertype = type.superclass;
+      if (supertype != null) {
+        if (set.add(supertype)) {
+          _computeSuperinterfaceSet(supertype, set);
+        }
+      }
+    }
+    return set;
+  }
+
+  /**
+   * Return the intersection of the [first] and [second] sets of types, where
+   * intersection is based on the equality of the types themselves.
+   */
+  static List<InterfaceType> _intersection(
+      Set<InterfaceType> first, Set<InterfaceType> second) {
+    Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
+    result.retainAll(second);
+    return new List.from(result);
+  }
+
+  /**
+   * Return the "least upper bound" of the given types under the assumption that
+   * the types have the same element and differ only in terms of the type
+   * arguments.
+   *
+   * The resulting type is composed by comparing the corresponding type
+   * arguments, keeping those that are the same, and using 'dynamic' for those
+   * that are different.
+   */
+  static InterfaceType _leastUpperBound(
+      InterfaceType firstType, InterfaceType secondType) {
+    ClassElement firstElement = firstType.element;
+    ClassElement secondElement = secondType.element;
+    if (firstElement != secondElement) {
+      throw new IllegalArgumentException('The same elements expected, but '
+          '$firstElement and $secondElement are given.');
+    }
+    if (firstType == secondType) {
+      return firstType;
+    }
+    List<DartType> firstArguments = firstType.typeArguments;
+    List<DartType> secondArguments = secondType.typeArguments;
+    int argumentCount = firstArguments.length;
+    if (argumentCount == 0) {
+      return firstType;
+    }
+    List<DartType> lubArguments = new List<DartType>(argumentCount);
+    for (int i = 0; i < argumentCount; i++) {
+      //
+      // Ideally we would take the least upper bound of the two argument types,
+      // but this can cause an infinite recursion (such as when finding the
+      // least upper bound of String and num).
+      //
+      if (firstArguments[i] == secondArguments[i]) {
+        lubArguments[i] = firstArguments[i];
+      }
+      if (lubArguments[i] == null) {
+        lubArguments[i] = DynamicTypeImpl.instance;
+      }
+    }
+    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement);
+    lub.typeArguments = lubArguments;
+    return lub;
+  }
+
+  /**
+   * Look up the getter with the given [name] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the getter that was found, or `null` if
+   * there is no getter with the given name. The flag [includeTargetType] should
+   * be `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
+   */
+  static ExecutableElement _lookUpMemberInInterfaces(
+      InterfaceType targetType,
+      bool includeTargetType,
+      LibraryElement library,
+      HashSet<ClassElement> visitedInterfaces,
+      ExecutableElement getMember(InterfaceType type)) {
+    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
+    // specification (titled "Inheritance and Overriding" under "Interfaces")
+    // describes a much more complex scheme for finding the inherited member.
+    // We need to follow that scheme. The code below should cover the 80% case.
+    ClassElement targetClass = targetType.element;
+    if (!visitedInterfaces.add(targetClass)) {
+      return null;
+    }
+    if (includeTargetType) {
+      ExecutableElement member = getMember(targetType);
+      if (member != null && member.isAccessibleIn(library)) {
+        return member;
+      }
+    }
+    for (InterfaceType interfaceType in targetType.interfaces) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          interfaceType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    for (InterfaceType mixinType in targetType.mixins.reversed) {
+      ExecutableElement member = _lookUpMemberInInterfaces(
+          mixinType, true, library, visitedInterfaces, getMember);
+      if (member != null) {
+        return member;
+      }
+    }
+    InterfaceType superclass = targetType.superclass;
+    if (superclass == null) {
+      return null;
+    }
+    return _lookUpMemberInInterfaces(
+        superclass, true, library, visitedInterfaces, getMember);
+  }
+}
+
+/**
+ * The abstract class `TypeImpl` implements the behavior common to objects
+ * representing the declared type of elements in the element model.
+ */
+abstract class TypeImpl implements DartType {
+  /**
+   * The element representing the declaration of this type, or `null` if the
+   * type has not, or cannot, be associated with an element.
+   */
+  final Element _element;
+
+  /**
+   * The name of this type, or `null` if the type does not have a name.
+   */
+  final String name;
+
+  /**
+   * Initialize a newly created type to be declared by the given [element] and
+   * to have the given [name].
+   */
+  TypeImpl(this._element, this.name);
+
+  @override
+  String get displayName => name;
+
+  @override
+  Element get element => _element;
+
+  @override
+  bool get isBottom => false;
+
+  @override
+  bool get isDartCoreFunction => false;
+
+  @override
+  bool get isDynamic => false;
+
+  @override
+  bool get isObject => false;
+
+  @override
+  bool get isUndefined => false;
+
+  @override
+  bool get isVoid => false;
+
+  /**
+   * Append a textual representation of this type to the given [buffer]. The set
+   * of [visitedTypes] is used to prevent infinite recursion.
+   */
+  void appendTo(StringBuffer buffer) {
+    if (name == null) {
+      buffer.write("<unnamed type>");
+    } else {
+      buffer.write(name);
+    }
+  }
+
+  /**
+   * Return `true` if this type is assignable to the given [type] (written in
+   * the spec as "T <=> S", where T=[this] and S=[type]).
+   *
+   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
+   * function type aliases that have been expanded so far in the process of
+   * reaching [this] and [type], respectively.  These are used to avoid
+   * infinite regress when analyzing invalid code; since the language spec
+   * forbids a typedef from referring to itself directly or indirectly, we can
+   * use these as sets of function type aliases that don't need to be expanded.
+   */
+  @override
+  bool isAssignableTo(DartType type) {
+    // An interface type T may be assigned to a type S, written T <=> S, iff
+    // either T <: S or S <: T.
+    return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this);
+  }
+
+  /**
+   * Return `true` if this type is more specific than the given [type] (written
+   * in the spec as "T << S", where T=[this] and S=[type]).
+   *
+   * If [withDynamic] is `true`, then "dynamic" should be considered as a
+   * subtype of any type (as though "dynamic" had been replaced with bottom).
+   *
+   * The set [visitedElements], if given, is the set of classes and type
+   * parameters that have been visited so far while examining the class
+   * hierarchy of [this].  This is used to avoid infinite regress when
+   * analyzing invalid code; since the language spec forbids loops in the class
+   * hierarchy, we can use this as a set of classes that don't need to be
+   * examined when walking the class hierarchy.
+   */
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]);
+
+  /**
+   * Return `true` if this type is a subtype of the given [type] (written in
+   * the spec as "T <: S", where T=[this] and S=[type]).
+   *
+   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
+   * function type aliases that have been expanded so far in the process of
+   * reaching [this] and [type], respectively.  These are used to avoid
+   * infinite regress when analyzing invalid code; since the language spec
+   * forbids a typedef from referring to itself directly or indirectly, we can
+   * use these as sets of function type aliases that don't need to be expanded.
+   */
+  @override
+  bool isSubtypeOf(DartType type) {
+    // For non-function types, T <: S iff [_|_/dynamic]T << S.
+    return isMoreSpecificThan(type, true);
+  }
+
+  @override
+  bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
+
+  /**
+   * Create a new [TypeImpl] that is identical to [this] except that when
+   * visiting type parameters, function parameter types, and function return
+   * types, function types listed in [prune] will not be expanded.  This is
+   * used to avoid creating infinite types in the presence of circular
+   * typedefs.
+   *
+   * If [prune] is null, then [this] is returned unchanged.
+   *
+   * Only legal to call on a [TypeImpl] that is not already subject to pruning.
+   */
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune);
+
+  /**
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * the given [parameterTypes] in this type.
+   *
+   * In all classes derived from [TypeImpl], a new optional argument
+   * [prune] is added.  If specified, it is a list of function typdefs
+   * which should not be expanded.  This is used to avoid creating infinite
+   * types in response to self-referential typedefs.
+   */
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]);
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    appendTo(buffer);
+    return buffer.toString();
+  }
+
+  /**
+   * Return `true` if corresponding elements of the [first] and [second] lists
+   * of type arguments are all equal.
+   */
+  static bool equalArrays(List<DartType> first, List<DartType> second) {
+    if (first.length != second.length) {
+      return false;
+    }
+    for (int i = 0; i < first.length; i++) {
+      if (first[i] == null) {
+        AnalysisEngine.instance.logger
+            .logInformation('Found null type argument in TypeImpl.equalArrays');
+        return second[i] == null;
+      } else if (second[i] == null) {
+        AnalysisEngine.instance.logger
+            .logInformation('Found null type argument in TypeImpl.equalArrays');
+        return false;
+      }
+      if (first[i] != second[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Return a list containing the results of using the given [argumentTypes] and
+   * [parameterTypes] to perform a substitution on all of the given [types].
+   *
+   * If [prune] is specified, it is a list of function typdefs which should not
+   * be expanded.  This is used to avoid creating infinite types in response to
+   * self-referential typedefs.
+   */
+  static List<DartType> substitute(List<DartType> types,
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = types.length;
+    if (length == 0) {
+      return types;
+    }
+    List<DartType> newTypes = new List<DartType>(length);
+    for (int i = 0; i < length; i++) {
+      newTypes[i] = (types[i] as TypeImpl)
+          .substitute2(argumentTypes, parameterTypes, prune);
+    }
+    return newTypes;
+  }
+}
+
+/**
+ * A concrete implementation of a [TypeParameterType].
+ */
+class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
+  /**
+   * Initialize a newly created type parameter type to be declared by the given
+   * [element] and to have the given name.
+   */
+  TypeParameterTypeImpl(TypeParameterElement element)
+      : super(element, element.name);
+
+  @override
+  TypeParameterElement get element => super.element as TypeParameterElement;
+
+  @override
+  int get hashCode => element.hashCode;
+
+  @override
+  bool operator ==(Object object) =>
+      object is TypeParameterTypeImpl && (element == object.element);
+
+  @override
+  bool isMoreSpecificThan(DartType s,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    //
+    // A type T is more specific than a type S, written T << S,
+    // if one of the following conditions is met:
+    //
+    // Reflexivity: T is S.
+    //
+    if (this == s) {
+      return true;
+    }
+    // S is dynamic.
+    //
+    if (s.isDynamic) {
+      return true;
+    }
+    //
+    // T is a type parameter and S is the upper bound of T.
+    //
+    TypeImpl bound = element.bound;
+    if (s == bound) {
+      return true;
+    }
+    //
+    // T is a type parameter and S is Object.
+    //
+    if (s.isObject) {
+      return true;
+    }
+    // We need upper bound to continue.
+    if (bound == null) {
+      return false;
+    }
+    //
+    // Transitivity: T << U and U << S.
+    //
+    // First check for infinite loops
+    if (element == null) {
+      return false;
+    }
+    if (visitedElements == null) {
+      visitedElements = new HashSet<Element>();
+    } else if (visitedElements.contains(element)) {
+      return false;
+    }
+    visitedElements.add(element);
+    try {
+      return bound.isMoreSpecificThan(s, withDynamic, visitedElements);
+    } finally {
+      visitedElements.remove(element);
+    }
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true);
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+
+  /**
+   * Return a list containing the type parameter types defined by the given
+   * array of type parameter elements ([typeParameters]).
+   */
+  static List<TypeParameterType> getTypes(
+      List<TypeParameterElement> typeParameters) {
+    int count = typeParameters.length;
+    if (count == 0) {
+      return TypeParameterType.EMPTY_LIST;
+    }
+    List<TypeParameterType> types = new List<TypeParameterType>(count);
+    for (int i = 0; i < count; i++) {
+      types[i] = typeParameters[i].type;
+    }
+    return types;
+  }
+}
+
+/**
+ * The unique instance of the class `UndefinedTypeImpl` implements the type of
+ * type names that couldn't be resolved.
+ *
+ * This class behaves like DynamicTypeImpl in almost every respect, to reduce
+ * cascading errors.
+ */
+class UndefinedTypeImpl extends TypeImpl {
+  /**
+   * The unique instance of this class.
+   */
+  static UndefinedTypeImpl _INSTANCE = new UndefinedTypeImpl._();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static UndefinedTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  UndefinedTypeImpl._()
+      : super(DynamicElementImpl.instance, Keyword.DYNAMIC.syntax);
+
+  @override
+  int get hashCode => 1;
+
+  @override
+  bool get isDynamic => true;
+
+  @override
+  bool get isUndefined => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+      [bool withDynamic = false, Set<Element> visitedElements]) {
+    // T is S
+    if (identical(this, type)) {
+      return true;
+    }
+    // else
+    return withDynamic;
+  }
+
+  @override
+  bool isSubtypeOf(DartType type) => true;
+
+  @override
+  bool isSupertypeOf(DartType type) => true;
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  DartType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes,
+      [List<FunctionTypeAliasElement> prune]) {
+    int length = parameterTypes.length;
+    for (int i = 0; i < length; i++) {
+      if (parameterTypes[i] == this) {
+        return argumentTypes[i];
+      }
+    }
+    return this;
+  }
+}
+
+/**
+ * The type `void`.
+ */
+abstract class VoidType implements DartType {
+  @override
+  VoidType substitute2(
+      List<DartType> argumentTypes, List<DartType> parameterTypes);
+}
+
+/**
+ * A concrete implementation of a [VoidType].
+ */
+class VoidTypeImpl extends TypeImpl implements VoidType {
+  /**
+   * The unique instance of this class.
+   */
+  static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
+
+  /**
+   * Return the unique instance of this class.
+   */
+  static VoidTypeImpl get instance => _INSTANCE;
+
+  /**
+   * Prevent the creation of instances of this class.
+   */
+  VoidTypeImpl() : super(null, Keyword.VOID.syntax);
+
+  @override
+  int get hashCode => 2;
+
+  @override
+  bool get isVoid => true;
+
+  @override
+  bool operator ==(Object object) => identical(object, this);
+
+  @override
+  bool isMoreSpecificThan(DartType type,
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      isSubtypeOf(type);
+
+  @override
+  bool isSubtypeOf(DartType type) {
+    // The only subtype relations that pertain to void are therefore:
+    // void <: void (by reflexivity)
+    // bottom <: void (as bottom is a subtype of all types).
+    // void <: dynamic (as dynamic is a supertype of all types)
+    return identical(type, this) || type.isDynamic;
+  }
+
+  @override
+  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
+
+  @override
+  VoidTypeImpl substitute2(
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
+}
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 282b8b7..06ae37c 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -6,7 +6,10 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/element.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' show AnalysisEngine;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index f2a8c96..a561978 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -6,8 +6,11 @@
 
 import 'dart:collection';
 
+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/member.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisEngine, RecordingErrorListener;
@@ -186,6 +189,13 @@
     invocation.staticElement = node.staticElement;
     return invocation;
   }
+
+  @override
+  TypeName visitTypeName(TypeName node) {
+    TypeName typeName = super.visitTypeName(node);
+    typeName.type = node.type;
+    return typeName;
+  }
 }
 
 /**
@@ -714,7 +724,8 @@
         DartObjectImpl fieldValue = evaluationResult.value;
         if (fieldValue != null && !runtimeTypeMatch(fieldValue, fieldType)) {
           errorReporter.reportErrorForNode(
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
               node,
               [fieldValue.type, field.name, fieldType]);
         }
@@ -762,7 +773,8 @@
       if (argumentValue != null) {
         if (!runtimeTypeMatch(argumentValue, parameter.type)) {
           errorReporter.reportErrorForNode(
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
               errorTarget,
               [argumentValue.type, parameter.type]);
         }
@@ -776,7 +788,8 @@
               // the field.
               if (!runtimeTypeMatch(argumentValue, fieldType)) {
                 errorReporter.reportErrorForNode(
-                    CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+                    CheckedModeCompileTimeErrorCode
+                        .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
                     errorTarget,
                     [argumentValue.type, fieldType]);
               }
@@ -818,7 +831,8 @@
             PropertyInducingElement field = getter.variable;
             if (!runtimeTypeMatch(evaluationResult, field.type)) {
               errorReporter.reportErrorForNode(
-                  CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
+                  CheckedModeCompileTimeErrorCode
+                      .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
                   node,
                   [evaluationResult.type, fieldName, field.type]);
             }
@@ -992,7 +1006,8 @@
    * Determine whether the given string is a valid name for a public symbol
    * (i.e. whether it is allowed for a call to the Symbol constructor).
    */
-  static bool isValidPublicSymbol(String name) => name.isEmpty ||
+  static bool isValidPublicSymbol(String name) =>
+      name.isEmpty ||
       name == "void" ||
       new JavaPatternMatcher(_PUBLIC_SYMBOL_PATTERN, name).matches();
 
@@ -1215,6 +1230,59 @@
 
 /**
  * A visitor used to traverse the AST structures of all of the compilation units
+ * being resolved and build the full set of dependencies for all constant
+ * expressions.
+ */
+class ConstantExpressionsDependenciesFinder extends RecursiveAstVisitor {
+  /**
+   * The constants whose values need to be computed.
+   */
+  HashSet<ConstantEvaluationTarget> dependencies =
+      new HashSet<ConstantEvaluationTarget>();
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (node.isConst) {
+      _find(node);
+    } else {
+      super.visitInstanceCreationExpression(node);
+    }
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    if (node.constKeyword != null) {
+      _find(node);
+    } else {
+      super.visitListLiteral(node);
+    }
+  }
+
+  @override
+  void visitMapLiteral(MapLiteral node) {
+    if (node.constKeyword != null) {
+      _find(node);
+    } else {
+      super.visitMapLiteral(node);
+    }
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    _find(node.expression);
+    node.statements.accept(this);
+  }
+
+  void _find(Expression node) {
+    if (node != null) {
+      ReferenceFinder referenceFinder = new ReferenceFinder(dependencies.add);
+      node.accept(referenceFinder);
+    }
+  }
+}
+
+/**
+ * A visitor used to traverse the AST structures of all of the compilation units
  * being resolved and build tables of the constant variables, constant
  * constructors, constant constructor invocations, and annotations found in
  * those compilation units.
@@ -1276,6 +1344,16 @@
   }
 
   @override
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    super.visitDefaultFormalParameter(node);
+    Expression defaultValue = node.defaultValue;
+    if (defaultValue != null && node.element != null) {
+      constantsToCompute.add(node.element);
+    }
+    return null;
+  }
+
+  @override
   Object visitVariableDeclaration(VariableDeclaration node) {
     super.visitVariableDeclaration(node);
     Expression initializer = node.initializer;
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index fcf2511..968d797 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -2,10822 +2,22 @@
 // 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 library is deprecated. Please convert all references to this library to
+ * reference one of the following public libraries:
+ * * package:analyzer/dart/element/element.dart
+ * * package:analyzer/dart/element/type.dart
+ * * package:analyzer/dart/element/visitor.dart
+ *
+ * If your code is using API's not available in these public libraries, please
+ * contact the analyzer team to either find an alternate API or have the API you
+ * depend on added to the public API.
+ */
 library analyzer.src.generated.element;
 
-import 'dart:collection';
-import 'dart:math' show min;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/constant.dart'
-    show DartObject, EvaluationResultImpl;
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisContext, AnalysisEngine, AnalysisException;
-import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart' show Keyword;
-import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/model.dart' show AnalysisTarget;
-
-/**
- * For AST nodes that could be in both the getter and setter contexts
- * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
- * elements are stored in the AST node, in an [AuxiliaryElements]. Because
- * resolved elements are either statically resolved or resolved using propagated
- * type information, this class is a wrapper for a pair of [ExecutableElement]s,
- * not just a single [ExecutableElement].
- */
-class AuxiliaryElements {
-  /**
-   * The element based on propagated type information, or `null` if the AST
-   * structure has not been resolved or if the node could not be resolved.
-   */
-  final ExecutableElement propagatedElement;
-
-  /**
-   * The element based on static type information, or `null` if the AST
-   * structure has not been resolved or if the node could not be resolved.
-   */
-  final ExecutableElement staticElement;
-
-  /**
-   * Initialize a newly created pair to have both the [staticElement] and the
-   * [propagatedElement].
-   */
-  AuxiliaryElements(this.staticElement, this.propagatedElement);
-}
-
-/**
- * A [Type] that represents the type 'bottom'.
- */
-class BottomTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static BottomTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  BottomTypeImpl._() : super(null, "<bottom>");
-
-  @override
-  int get hashCode => 0;
-
-  @override
-  bool get isBottom => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-          [bool withDynamic = false, Set<Element> visitedElements]) =>
-      true;
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => false;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  BottomTypeImpl substitute2(
-          List<DartType> argumentTypes, List<DartType> parameterTypes,
-          [List<FunctionTypeAliasElement> prune]) =>
-      this;
-}
-
-/**
- * Type created internally if a circular reference is ever detected.  Behaves
- * like `dynamic`, except that when converted to a string it is displayed as
- * `...`.
- */
-class CircularTypeImpl extends DynamicTypeImpl {
-  CircularTypeImpl() : super._circular();
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool operator ==(Object object) => object is CircularTypeImpl;
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write('...');
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-}
-
-/**
- * An element that represents a class.
- */
-abstract class ClassElement
-    implements TypeDefiningElement, TypeParameterizedElement {
-  /**
-   * An empty list of class elements.
-   */
-  static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
-
-  /**
-   * Return a list containing all of the accessors (getters and setters)
-   * declared in this class.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return a list containing all the supertypes defined for this class and its
-   * supertypes. This includes superclasses, mixins and interfaces.
-   */
-  List<InterfaceType> get allSupertypes;
-
-  /**
-   * Return a list containing all of the constructors declared in this class.
-   */
-  List<ConstructorElement> get constructors;
-
-  /**
-   * Return a list containing all of the fields declared in this class.
-   */
-  List<FieldElement> get fields;
-
-  /**
-   * Return `true` if this class or its superclass declares a non-final instance
-   * field.
-   */
-  bool get hasNonFinalField;
-
-  /**
-   * Return `true` if this class has reference to super (so, for example, cannot
-   * be used as a mixin).
-   */
-  bool get hasReferenceToSuper;
-
-  /**
-   * Return `true` if this class declares a static member.
-   */
-  bool get hasStaticMember;
-
-  /**
-   * Return a list containing all of the interfaces that are implemented by this
-   * class.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  List<InterfaceType> get interfaces;
-
-  /**
-   * Return `true` if this class is abstract. A class is abstract if it has an
-   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
-   * is different from <i>has unimplemented members</i>.
-   */
-  bool get isAbstract;
-
-  /**
-   * Return `true` if this class is defined by an enum declaration.
-   */
-  bool get isEnum;
-
-  /**
-   * Return `true` if this class is a mixin application.  A class is a mixin
-   * application if it was declared using the syntax "class A = B with C;".
-   */
-  bool get isMixinApplication;
-
-  /**
-   * Return `true` if this class [isProxy], or if it inherits the proxy
-   * annotation from a supertype.
-   */
-  bool get isOrInheritsProxy;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@proxy'.
-   */
-  bool get isProxy;
-
-  /**
-   * Return `true` if this class can validly be used as a mixin when defining
-   * another class. The behavior of this method is defined by the Dart Language
-   * Specification in section 9:
-   * <blockquote>
-   * It is a compile-time error if a declared or derived mixin refers to super.
-   * It is a compile-time error if a declared or derived mixin explicitly
-   * declares a constructor. It is a compile-time error if a mixin is derived
-   * from a class whose superclass is not Object.
-   * </blockquote>
-   */
-  bool get isValidMixin;
-
-  /**
-   * Return a list containing all of the methods declared in this class.
-   */
-  List<MethodElement> get methods;
-
-  /**
-   * Return a list containing all of the mixins that are applied to the class
-   * being extended in order to derive the superclass of this class.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  List<InterfaceType> get mixins;
-
-  /**
-   * Return the superclass of this class, or `null` if the class represents the
-   * class 'Object'. All other classes will have a non-`null` superclass. If the
-   * superclass was not explicitly declared then the implicit superclass
-   * 'Object' will be returned.
-   *
-   * <b>Note:</b> Because the element model represents the state of the code, it
-   * is possible for it to be semantically invalid. In particular, it is not
-   * safe to assume that the inheritance structure of a class does not contain a
-   * cycle. Clients that traverse the inheritance structure must explicitly
-   * guard against infinite loops.
-   */
-  InterfaceType get supertype;
-
-  @override
-  InterfaceType get type;
-
-  /**
-   * Return the unnamed constructor declared in this class, or `null` if this
-   * class does not declare an unnamed constructor but does declare named
-   * constructors. The returned constructor will be synthetic if this class does
-   * not declare any constructors, in which case it will represent the default
-   * constructor for the class.
-   */
-  ConstructorElement get unnamedConstructor;
-
-  /**
-   * Return the resolved [ClassDeclaration] or [EnumDeclaration] node that
-   * declares this [ClassElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  NamedCompilationUnitMember computeNode();
-
-  /**
-   * Return the field (synthetic or explicit) defined in this class that has the
-   * given [name], or `null` if this class does not define a field with the
-   * given name.
-   */
-  FieldElement getField(String name);
-
-  /**
-   * Return the element representing the getter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a getter
-   * with the given name.
-   */
-  PropertyAccessorElement getGetter(String name);
-
-  /**
-   * Return the element representing the method with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a method
-   * with the given name.
-   */
-  MethodElement getMethod(String name);
-
-  /**
-   * Return the named constructor declared in this class with the given [name],
-   * or `null` if this class does not declare a named constructor with the given
-   * name.
-   */
-  ConstructorElement getNamedConstructor(String name);
-
-  /**
-   * Return the element representing the setter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a setter
-   * with the given name.
-   */
-  PropertyAccessorElement getSetter(String name);
-
-  /**
-   * Determine whether the given [constructor], which exists in the superclass
-   * of this class, is accessible to constructors in this class.
-   */
-  bool isSuperConstructorAccessible(ConstructorElement constructor);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in this class with respect to the given [library],
-   * ignoring abstract methods, or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is: If <i>C</i> declares an instance method named <i>m</i>
-   * that is accessible to <i>L</i>, then that method is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up method <i>m</i> in <i>S</i> with
-   * respect to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * given [getterName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetter(
-      String getterName, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * given [getterName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract getters, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpInheritedConcreteGetter(
-      String getterName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract methods, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpInheritedConcreteMethod(
-      String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * given [setterName] in the superclass of this class with respect to the
-   * given [library], ignoring abstract setters, or `null` if the look up fails.
-   * The behavior of this method is defined by the Dart Language Specification
-   * in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpInheritedConcreteSetter(
-      String setterName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in the superclass of this class with respect to the
-   * given [library], or `null` if the look up fails. The behavior of this
-   * method is defined by the Dart Language Specification in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpInheritedMethod(
-      String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * given [methodName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:  If <i>C</i> declares an instance method named
-   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
-   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
-   * result of the lookup is the result of looking up method <i>m</i> in
-   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
-   * failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethod(String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * given [setterName] in this class with respect to the given [library], or
-   * `null` if the look up fails. The behavior of this method is defined by the
-   * Dart Language Specification in section 16.15.2:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
-   * instance getter (respectively setter) named <i>m</i> that is accessible to
-   * <i>L</i>, then that getter (respectively setter) is the result of the
-   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
-   * of the lookup is the result of looking up getter (respectively setter)
-   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
-   * lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetter(
-      String setterName, LibraryElement library);
-}
-
-/**
- * A concrete implementation of a [ClassElement].
- */
-class ClassElementImpl extends ElementImpl implements ClassElement {
-  /**
-   * A list containing all of the accessors (getters and setters) contained in
-   * this class.
-   */
-  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
-
-  /**
-   * For classes which are not mixin applications, a list containing all of the
-   * constructors contained in this class, or `null` if the list of
-   * constructors has not yet been built.
-   *
-   * For classes which are mixin applications, the list of constructors is
-   * computed on the fly by the [constructors] getter, and this field is
-   * `null`.
-   */
-  List<ConstructorElement> _constructors;
-
-  /**
-   * A list containing all of the fields contained in this class.
-   */
-  List<FieldElement> _fields = FieldElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the mixins that are applied to the class being
-   * extended in order to derive the superclass of this class.
-   */
-  List<InterfaceType> mixins = InterfaceType.EMPTY_LIST;
-
-  /**
-   * A list containing all of the interfaces that are implemented by this class.
-   */
-  List<InterfaceType> interfaces = InterfaceType.EMPTY_LIST;
-
-  /**
-   * A list containing all of the methods contained in this class.
-   */
-  List<MethodElement> _methods = MethodElement.EMPTY_LIST;
-
-  /**
-   * The superclass of the class, or `null` if the class does not have an
-   * explicit superclass.
-   */
-  InterfaceType supertype;
-
-  /**
-   * The type defined by the class.
-   */
-  InterfaceType type;
-
-  /**
-   * A list containing all of the type parameters defined for this class.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The [SourceRange] of the `with` clause, `null` if there is no one.
-   */
-  SourceRange withClauseRange;
-
-  /**
-   * A flag indicating whether the types associated with the instance members of
-   * this class have been inferred.
-   */
-  bool hasBeenInferred = false;
-
-  /**
-   * Initialize a newly created class element to have the given [name] at the
-   * given [offset] in the file that contains the declaration of this element.
-   */
-  ClassElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created class element to have the given [name].
-   */
-  ClassElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this class is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  List<PropertyAccessorElement> get accessors => _accessors;
-
-  /**
-   * Set the accessors contained in this class to the given [accessors].
-   */
-  void set accessors(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
-    }
-    this._accessors = accessors;
-  }
-
-  @override
-  List<InterfaceType> get allSupertypes {
-    List<InterfaceType> list = new List<InterfaceType>();
-    _collectAllSupertypes(list);
-    return list;
-  }
-
-  @override
-  List<ConstructorElement> get constructors {
-    if (!isMixinApplication) {
-      assert(_constructors != null);
-      return _constructors == null
-          ? ConstructorElement.EMPTY_LIST
-          : _constructors;
-    }
-
-    return _computeMixinAppConstructors();
-  }
-
-  /**
-   * Set the constructors contained in this class to the given [constructors].
-   *
-   * Should only be used for class elements that are not mixin applications.
-   */
-  void set constructors(List<ConstructorElement> constructors) {
-    assert(!isMixinApplication);
-    for (ConstructorElement constructor in constructors) {
-      (constructor as ConstructorElementImpl).enclosingElement = this;
-    }
-    this._constructors = constructors;
-  }
-
-  /**
-   * Return `true` if [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] should
-   * be reported for this class.
-   */
-  bool get doesMixinLackConstructors {
-    if (!isMixinApplication && mixins.isEmpty) {
-      // This class is not a mixin application and it doesn't have a "with"
-      // clause, so CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS is
-      // inapplicable.
-      return false;
-    }
-    if (supertype == null) {
-      // Should never happen, since Object is the only class that has no
-      // supertype, and it should have been caught by the test above.
-      assert(false);
-      return false;
-    }
-    // Find the nearest class in the supertype chain that is not a mixin
-    // application.
-    ClassElement nearestNonMixinClass = supertype.element;
-    if (nearestNonMixinClass.isMixinApplication) {
-      // Use a list to keep track of the classes we've seen, so that we won't
-      // go into an infinite loop in the event of a non-trivial loop in the
-      // class hierarchy.
-      List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
-      while (nearestNonMixinClass.isMixinApplication) {
-        if (classesSeen.contains(nearestNonMixinClass)) {
-          // Loop in the class hierarchy (which is reported elsewhere).  Don't
-          // confuse the user with further errors.
-          return false;
-        }
-        classesSeen.add(nearestNonMixinClass);
-        if (nearestNonMixinClass.supertype == null) {
-          // Should never happen, since Object is the only class that has no
-          // supertype, and it is not a mixin application.
-          assert(false);
-          return false;
-        }
-        nearestNonMixinClass = nearestNonMixinClass.supertype.element;
-      }
-    }
-    return !nearestNonMixinClass.constructors.any(isSuperConstructorAccessible);
-  }
-
-  /**
-   * Set whether this class is defined by an enum declaration.
-   */
-  void set enum2(bool isEnum) {
-    setModifier(Modifier.ENUM, isEnum);
-  }
-
-  @override
-  List<FieldElement> get fields => _fields;
-
-  /**
-   * Set the fields contained in this class to the given [fields].
-   */
-  void set fields(List<FieldElement> fields) {
-    for (FieldElement field in fields) {
-      (field as FieldElementImpl).enclosingElement = this;
-    }
-    this._fields = fields;
-  }
-
-  @override
-  bool get hasNonFinalField {
-    List<ClassElement> classesToVisit = new List<ClassElement>();
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    classesToVisit.add(this);
-    while (!classesToVisit.isEmpty) {
-      ClassElement currentElement = classesToVisit.removeAt(0);
-      if (visitedClasses.add(currentElement)) {
-        // check fields
-        for (FieldElement field in currentElement.fields) {
-          if (!field.isFinal &&
-              !field.isConst &&
-              !field.isStatic &&
-              !field.isSynthetic) {
-            return true;
-          }
-        }
-        // check mixins
-        for (InterfaceType mixinType in currentElement.mixins) {
-          ClassElement mixinElement = mixinType.element;
-          classesToVisit.add(mixinElement);
-        }
-        // check super
-        InterfaceType supertype = currentElement.supertype;
-        if (supertype != null) {
-          ClassElement superElement = supertype.element;
-          if (superElement != null) {
-            classesToVisit.add(superElement);
-          }
-        }
-      }
-    }
-    // not found
-    return false;
-  }
-
-  @override
-  bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
-
-  /**
-   * Set whether this class references 'super'.
-   */
-  void set hasReferenceToSuper(bool isReferencedSuper) {
-    setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
-  }
-
-  @override
-  bool get hasStaticMember {
-    for (MethodElement method in _methods) {
-      if (method.isStatic) {
-        return true;
-      }
-    }
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isStatic) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
-  bool get isEnum => hasModifier(Modifier.ENUM);
-
-  @override
-  bool get isMixinApplication => hasModifier(Modifier.MIXIN_APPLICATION);
-
-  @override
-  bool get isOrInheritsProxy =>
-      _safeIsOrInheritsProxy(this, new HashSet<ClassElement>());
-
-  @override
-  bool get isProxy {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isProxy) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isValidMixin => hasModifier(Modifier.MIXIN);
-
-  @override
-  ElementKind get kind => ElementKind.CLASS;
-
-  @override
-  List<MethodElement> get methods => _methods;
-
-  /**
-   * Set the methods contained in this class to the given [methods].
-   */
-  void set methods(List<MethodElement> methods) {
-    for (MethodElement method in methods) {
-      (method as MethodElementImpl).enclosingElement = this;
-    }
-    this._methods = methods;
-  }
-
-  /**
-   * Set whether this class is a mixin application.
-   */
-  void set mixinApplication(bool isMixinApplication) {
-    setModifier(Modifier.MIXIN_APPLICATION, isMixinApplication);
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined for this class to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  ConstructorElement get unnamedConstructor {
-    for (ConstructorElement element in constructors) {
-      String name = element.displayName;
-      if (name == null || name.isEmpty) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Set whether this class is a valid mixin.
-   */
-  void set validMixin(bool isValidMixin) {
-    setModifier(Modifier.MIXIN, isValidMixin);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitClassElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String name = displayName;
-    if (name == null) {
-      buffer.write("{unnamed class}");
-    } else {
-      buffer.write(name);
-    }
-    int variableCount = _typeParameters.length;
-    if (variableCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < variableCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-  }
-
-  @override
-  NamedCompilationUnitMember computeNode() {
-    if (isEnum) {
-      return getNodeMatching((node) => node is EnumDeclaration);
-    } else {
-      return getNodeMatching(
-          (node) => node is ClassDeclaration || node is ClassTypeAlias);
-    }
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
-      }
-    }
-    for (ConstructorElement constructor in _constructors) {
-      if ((constructor as ConstructorElementImpl).identifier == identifier) {
-        return constructor as ConstructorElementImpl;
-      }
-    }
-    for (FieldElement field in _fields) {
-      if ((field as FieldElementImpl).identifier == identifier) {
-        return field as FieldElementImpl;
-      }
-    }
-    for (MethodElement method in _methods) {
-      if ((method as MethodElementImpl).identifier == identifier) {
-        return method as MethodElementImpl;
-      }
-    }
-    for (TypeParameterElement typeParameter in _typeParameters) {
-      if ((typeParameter as TypeParameterElementImpl).identifier ==
-          identifier) {
-        return typeParameter as TypeParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  FieldElement getField(String name) {
-    for (FieldElement fieldElement in _fields) {
-      if (name == fieldElement.name) {
-        return fieldElement;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) {
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isGetter && accessor.name == getterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  MethodElement getMethod(String methodName) {
-    for (MethodElement method in _methods) {
-      if (method.name == methodName) {
-        return method;
-      }
-    }
-    return null;
-  }
-
-  @override
-  ConstructorElement getNamedConstructor(String name) {
-    for (ConstructorElement element in constructors) {
-      String elementName = element.name;
-      if (elementName != null && elementName == name) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) {
-    // TODO (jwren) revisit- should we append '=' here or require clients to
-    // include it?
-    // Do we need the check for isSetter below?
-    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
-      setterName += '=';
-    }
-    for (PropertyAccessorElement accessor in _accessors) {
-      if (accessor.isSetter && accessor.name == setterName) {
-        return accessor;
-      }
-    }
-    return null;
-  }
-
-  @override
-  bool isSuperConstructorAccessible(ConstructorElement constructor) {
-    // If this class has no mixins, then all superclass constructors are
-    // accessible.
-    if (mixins.isEmpty) {
-      return true;
-    }
-    // Otherwise only constructors that lack optional parameters are
-    // accessible (see dartbug.com/19576).
-    for (ParameterElement parameter in constructor.parameters) {
-      if (parameter.parameterKind != ParameterKind.REQUIRED) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
-  MethodElement lookUpConcreteMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpConcreteMethod(methodName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpGetter(
-          String getterName, LibraryElement library) =>
-      _internalLookUpGetter(getterName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpInheritedConcreteGetter(
-          String getterName, LibraryElement library) =>
-      _internalLookUpConcreteGetter(getterName, library, false);
-
-  @override
-  MethodElement lookUpInheritedConcreteMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpConcreteMethod(methodName, library, false);
-
-  @override
-  PropertyAccessorElement lookUpInheritedConcreteSetter(
-          String setterName, LibraryElement library) =>
-      _internalLookUpConcreteSetter(setterName, library, false);
-
-  @override
-  MethodElement lookUpInheritedMethod(
-          String methodName, LibraryElement library) =>
-      _internalLookUpMethod(methodName, library, false);
-
-  @override
-  MethodElement lookUpMethod(String methodName, LibraryElement library) =>
-      _internalLookUpMethod(methodName, library, true);
-
-  @override
-  PropertyAccessorElement lookUpSetter(
-          String setterName, LibraryElement library) =>
-      _internalLookUpSetter(setterName, library, true);
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_accessors, visitor);
-    safelyVisitChildren(_constructors, visitor);
-    safelyVisitChildren(_fields, visitor);
-    safelyVisitChildren(_methods, visitor);
-    safelyVisitChildren(_typeParameters, visitor);
-  }
-
-  void _collectAllSupertypes(List<InterfaceType> supertypes) {
-    List<InterfaceType> typesToVisit = new List<InterfaceType>();
-    List<ClassElement> visitedClasses = new List<ClassElement>();
-    typesToVisit.add(this.type);
-    while (!typesToVisit.isEmpty) {
-      InterfaceType currentType = typesToVisit.removeAt(0);
-      ClassElement currentElement = currentType.element;
-      if (!visitedClasses.contains(currentElement)) {
-        visitedClasses.add(currentElement);
-        if (!identical(currentType, this.type)) {
-          supertypes.add(currentType);
-        }
-        InterfaceType supertype = currentType.superclass;
-        if (supertype != null) {
-          typesToVisit.add(supertype);
-        }
-        for (InterfaceType type in currentElement.interfaces) {
-          typesToVisit.add(type);
-        }
-        for (InterfaceType type in currentElement.mixins) {
-          ClassElement element = type.element;
-          if (!visitedClasses.contains(element)) {
-            supertypes.add(type);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Compute a list of constructors for this class, which is a mixin
-   * application.  If specified, [visitedClasses] is a list of the other mixin
-   * application classes which have been visited on the way to reaching this
-   * one (this is used to detect circularities).
-   */
-  List<ConstructorElement> _computeMixinAppConstructors(
-      [List<ClassElementImpl> visitedClasses = null]) {
-    // First get the list of constructors of the superclass which need to be
-    // forwarded to this class.
-    Iterable<ConstructorElement> constructorsToForward;
-    if (supertype == null) {
-      // Shouldn't ever happen, since the only class with no supertype is
-      // Object, and it isn't a mixin application.  But for safety's sake just
-      // assume an empty list.
-      assert(false);
-      constructorsToForward = <ConstructorElement>[];
-    } else if (!supertype.element.isMixinApplication) {
-      List<ConstructorElement> superclassConstructors =
-          supertype.element.constructors;
-      // Filter out any constructors with optional parameters (see
-      // dartbug.com/15101).
-      constructorsToForward =
-          superclassConstructors.where(isSuperConstructorAccessible);
-    } else {
-      if (visitedClasses == null) {
-        visitedClasses = <ClassElementImpl>[this];
-      } else {
-        if (visitedClasses.contains(this)) {
-          // Loop in the class hierarchy.  Don't try to forward any
-          // constructors.
-          return <ConstructorElement>[];
-        }
-        visitedClasses.add(this);
-      }
-      try {
-        ClassElementImpl superclass = supertype.element;
-        constructorsToForward =
-            superclass._computeMixinAppConstructors(visitedClasses);
-      } finally {
-        visitedClasses.removeLast();
-      }
-    }
-
-    // Figure out the type parameter substitution we need to perform in order
-    // to produce constructors for this class.  We want to be robust in the
-    // face of errors, so drop any extra type arguments and fill in any missing
-    // ones with `dynamic`.
-    List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(supertype.typeParameters);
-    List<DartType> argumentTypes = new List<DartType>.filled(
-        parameterTypes.length, DynamicTypeImpl.instance);
-    for (int i = 0; i < supertype.typeArguments.length; i++) {
-      if (i >= argumentTypes.length) {
-        break;
-      }
-      argumentTypes[i] = supertype.typeArguments[i];
-    }
-
-    // Now create an implicit constructor for every constructor found above,
-    // substituting type parameters as appropriate.
-    return constructorsToForward
-        .map((ConstructorElement superclassConstructor) {
-      ConstructorElementImpl implicitConstructor =
-          new ConstructorElementImpl(superclassConstructor.name, -1);
-      implicitConstructor.synthetic = true;
-      implicitConstructor.redirectedConstructor = superclassConstructor;
-      implicitConstructor.const2 = superclassConstructor.isConst;
-      implicitConstructor.returnType = type;
-      List<ParameterElement> superParameters = superclassConstructor.parameters;
-      int count = superParameters.length;
-      if (count > 0) {
-        List<ParameterElement> implicitParameters =
-            new List<ParameterElement>(count);
-        for (int i = 0; i < count; i++) {
-          ParameterElement superParameter = superParameters[i];
-          ParameterElementImpl implicitParameter =
-              new ParameterElementImpl(superParameter.name, -1);
-          implicitParameter.const3 = superParameter.isConst;
-          implicitParameter.final2 = superParameter.isFinal;
-          implicitParameter.parameterKind = superParameter.parameterKind;
-          implicitParameter.synthetic = true;
-          implicitParameter.type =
-              superParameter.type.substitute2(argumentTypes, parameterTypes);
-          implicitParameters[i] = implicitParameter;
-        }
-        implicitConstructor.parameters = implicitParameters;
-      }
-      implicitConstructor.enclosingElement = this;
-      implicitConstructor.type = new FunctionTypeImpl(implicitConstructor);
-      return implicitConstructor;
-    }).toList();
-  }
-
-  PropertyAccessorElement _internalLookUpConcreteGetter(
-      String getterName, LibraryElement library, bool includeThisClass) {
-    PropertyAccessorElement getter =
-        _internalLookUpGetter(getterName, library, includeThisClass);
-    while (getter != null && getter.isAbstract) {
-      Element definingClass = getter.enclosingElement;
-      if (definingClass is! ClassElementImpl) {
-        return null;
-      }
-      getter = (definingClass as ClassElementImpl)
-          ._internalLookUpGetter(getterName, library, false);
-    }
-    return getter;
-  }
-
-  MethodElement _internalLookUpConcreteMethod(
-      String methodName, LibraryElement library, bool includeThisClass) {
-    MethodElement method =
-        _internalLookUpMethod(methodName, library, includeThisClass);
-    while (method != null && method.isAbstract) {
-      ClassElement definingClass = method.enclosingElement;
-      if (definingClass == null) {
-        return null;
-      }
-      method = definingClass.lookUpInheritedMethod(methodName, library);
-    }
-    return method;
-  }
-
-  PropertyAccessorElement _internalLookUpConcreteSetter(
-      String setterName, LibraryElement library, bool includeThisClass) {
-    PropertyAccessorElement setter =
-        _internalLookUpSetter(setterName, library, includeThisClass);
-    while (setter != null && setter.isAbstract) {
-      Element definingClass = setter.enclosingElement;
-      if (definingClass is! ClassElementImpl) {
-        return null;
-      }
-      setter = (definingClass as ClassElementImpl)
-          ._internalLookUpSetter(setterName, library, false);
-    }
-    return setter;
-  }
-
-  PropertyAccessorElement _internalLookUpGetter(
-      String getterName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      PropertyAccessorElement element = currentElement.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          PropertyAccessorElement element = mixinElement.getGetter(getterName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      PropertyAccessorElement element = currentElement.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  MethodElement _internalLookUpMethod(
-      String methodName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      MethodElement element = currentElement.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          MethodElement element = mixinElement.getMethod(methodName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      MethodElement element = currentElement.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  PropertyAccessorElement _internalLookUpSetter(
-      String setterName, LibraryElement library, bool includeThisClass) {
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    ClassElement currentElement = this;
-    if (includeThisClass) {
-      PropertyAccessorElement element = currentElement.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    while (currentElement != null && visitedClasses.add(currentElement)) {
-      for (InterfaceType mixin in currentElement.mixins.reversed) {
-        ClassElement mixinElement = mixin.element;
-        if (mixinElement != null) {
-          PropertyAccessorElement element = mixinElement.getSetter(setterName);
-          if (element != null && element.isAccessibleIn(library)) {
-            return element;
-          }
-        }
-      }
-      InterfaceType supertype = currentElement.supertype;
-      if (supertype == null) {
-        return null;
-      }
-      currentElement = supertype.element;
-      PropertyAccessorElement element = currentElement.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  bool _safeIsOrInheritsProxy(
-      ClassElement classElt, HashSet<ClassElement> visitedClassElts) {
-    if (visitedClassElts.contains(classElt)) {
-      return false;
-    }
-    visitedClassElts.add(classElt);
-    if (classElt.isProxy) {
-      return true;
-    } else if (classElt.supertype != null &&
-        _safeIsOrInheritsProxy(classElt.supertype.element, visitedClassElts)) {
-      return true;
-    }
-    List<InterfaceType> supertypes = classElt.interfaces;
-    for (int i = 0; i < supertypes.length; i++) {
-      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
-        return true;
-      }
-    }
-    supertypes = classElt.mixins;
-    for (int i = 0; i < supertypes.length; i++) {
-      if (_safeIsOrInheritsProxy(supertypes[i].element, visitedClassElts)) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * An element that is contained within a [ClassElement].
- */
-abstract class ClassMemberElement implements Element {
-  /**
-   * Return the type in which this member is defined.
-   */
-  @override
-  ClassElement get enclosingElement;
-
-  /**
-   * Return `true` if this element is a static element. A static element is an
-   * element that is not associated with a particular instance, but rather with
-   * an entire library or class.
-   */
-  bool get isStatic;
-}
-
-/**
- * An element representing a compilation unit.
- */
-abstract class CompilationUnitElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of compilation unit elements.
-   */
-  static const List<CompilationUnitElement> EMPTY_LIST =
-      const <CompilationUnitElement>[];
-
-  /**
-   * Return a list containing all of the top-level accessors (getters and
-   * setters) contained in this compilation unit.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return the library in which this compilation unit is defined.
-   */
-  @override
-  LibraryElement get enclosingElement;
-
-  /**
-   * Return a list containing all of the enums contained in this compilation
-   * unit.
-   */
-  List<ClassElement> get enums;
-
-  /**
-   * Return a list containing all of the top-level functions contained in this
-   * compilation unit.
-   */
-  List<FunctionElement> get functions;
-
-  /**
-   * Return a list containing all of the function type aliases contained in this
-   * compilation unit.
-   */
-  List<FunctionTypeAliasElement> get functionTypeAliases;
-
-  /**
-   * Return `true` if this compilation unit defines a top-level function named
-   * `loadLibrary`.
-   */
-  bool get hasLoadLibraryFunction;
-
-  /**
-   * Return a list containing all of the top-level variables contained in this
-   * compilation unit.
-   */
-  List<TopLevelVariableElement> get topLevelVariables;
-
-  /**
-   * Return a list containing all of the classes contained in this compilation
-   * unit.
-   */
-  List<ClassElement> get types;
-
-  /**
-   * Return the resolved [CompilationUnit] node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  CompilationUnit computeNode();
-
-  /**
-   * Return the element at the given [offset], maybe `null` if no such element.
-   */
-  Element getElementAt(int offset);
-
-  /**
-   * Return the enum defined in this compilation unit that has the given [name],
-   * or `null` if this compilation unit does not define an enum with the given
-   * name.
-   */
-  ClassElement getEnum(String name);
-
-  /**
-   * Return the class defined in this compilation unit that has the given
-   * [name], or `null` if this compilation unit does not define a class with the
-   * given name.
-   */
-  ClassElement getType(String name);
-}
-
-/**
- * A concrete implementation of a [CompilationUnitElement].
- */
-class CompilationUnitElementImpl extends UriReferencedElementImpl
-    implements CompilationUnitElement {
-  /**
-   * The source that corresponds to this compilation unit.
-   */
-  Source source;
-
-  /**
-   * The source of the library containing this compilation unit.
-   *
-   * This is the same as the source of the containing [LibraryElement],
-   * except that it does not require the containing [LibraryElement] to be
-   * computed.
-   */
-  Source librarySource;
-
-  /**
-   * A list containing all of the top-level accessors (getters and setters)
-   * contained in this compilation unit.
-   */
-  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the enums contained in this compilation unit.
-   */
-  List<ClassElement> _enums = ClassElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the top-level functions contained in this
-   * compilation unit.
-   */
-  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the function type aliases contained in this
-   * compilation unit.
-   */
-  List<FunctionTypeAliasElement> _typeAliases =
-      FunctionTypeAliasElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the types contained in this compilation unit.
-   */
-  List<ClassElement> _types = ClassElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the variables contained in this compilation unit.
-   */
-  List<TopLevelVariableElement> _variables = TopLevelVariableElement.EMPTY_LIST;
-
-  /**
-   * A map from offsets to elements of this unit at these offsets.
-   */
-  final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
-
-  /**
-   * Initialize a newly created compilation unit element to have the given
-   * [name].
-   */
-  CompilationUnitElementImpl(String name) : super(name, -1);
-
-  @override
-  List<PropertyAccessorElement> get accessors => _accessors;
-
-  /**
-   * Set the top-level accessors (getters and setters) contained in this
-   * compilation unit to the given [accessors].
-   */
-  void set accessors(List<PropertyAccessorElement> accessors) {
-    for (PropertyAccessorElement accessor in accessors) {
-      (accessor as PropertyAccessorElementImpl).enclosingElement = this;
-    }
-    this._accessors = accessors;
-  }
-
-  @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement as LibraryElement;
-
-  @override
-  List<ClassElement> get enums => _enums;
-
-  /**
-   * Set the enums contained in this compilation unit to the given [enums].
-   */
-  void set enums(List<ClassElement> enums) {
-    for (ClassElement enumDeclaration in enums) {
-      (enumDeclaration as ClassElementImpl).enclosingElement = this;
-    }
-    this._enums = enums;
-  }
-
-  @override
-  List<FunctionElement> get functions => _functions;
-
-  /**
-   * Set the top-level functions contained in this compilation unit to the given
-   * [functions].
-   */
-  void set functions(List<FunctionElement> functions) {
-    for (FunctionElement function in functions) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._functions = functions;
-  }
-
-  @override
-  List<FunctionTypeAliasElement> get functionTypeAliases => _typeAliases;
-
-  @override
-  int get hashCode => source.hashCode;
-
-  @override
-  bool get hasLoadLibraryFunction {
-    for (int i = 0; i < _functions.length; i++) {
-      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String get identifier => source.encoding;
-
-  @override
-  ElementKind get kind => ElementKind.COMPILATION_UNIT;
-
-  @override
-  List<TopLevelVariableElement> get topLevelVariables => _variables;
-
-  /**
-   * Set the top-level variables contained in this compilation unit to the given
-   * [variables].
-   */
-  void set topLevelVariables(List<TopLevelVariableElement> variables) {
-    for (TopLevelVariableElement field in variables) {
-      (field as TopLevelVariableElementImpl).enclosingElement = this;
-    }
-    this._variables = variables;
-  }
-
-  /**
-   * Set the function type aliases contained in this compilation unit to the
-   * given [typeAliases].
-   */
-  void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
-    for (FunctionTypeAliasElement typeAlias in typeAliases) {
-      (typeAlias as FunctionTypeAliasElementImpl).enclosingElement = this;
-    }
-    this._typeAliases = typeAliases;
-  }
-
-  @override
-  List<ClassElement> get types => _types;
-
-  /**
-   * Set the types contained in this compilation unit to the given [types].
-   */
-  void set types(List<ClassElement> types) {
-    for (ClassElement type in types) {
-      (type as ClassElementImpl).enclosingElement = this;
-    }
-    this._types = types;
-  }
-
-  @override
-  bool operator ==(Object object) =>
-      object is CompilationUnitElementImpl && source == object.source;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitCompilationUnitElement(this);
-
-  /**
-   * This method is invoked after this unit was incrementally resolved.
-   */
-  void afterIncrementalResolution() {
-    _offsetToElementMap.clear();
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (source == null) {
-      buffer.write("{compilation unit}");
-    } else {
-      buffer.write(source.fullName);
-    }
-  }
-
-  @override
-  CompilationUnit computeNode() => unit;
-
-  @override
-  ElementImpl getChild(String identifier) {
-    //
-    // The casts in this method are safe because the set methods would have
-    // thrown a CCE if any of the elements in the arrays were not of the
-    // expected types.
-    //
-    for (PropertyAccessorElement accessor in _accessors) {
-      if ((accessor as PropertyAccessorElementImpl).identifier == identifier) {
-        return accessor as PropertyAccessorElementImpl;
-      }
-    }
-    for (VariableElement variable in _variables) {
-      if ((variable as VariableElementImpl).identifier == identifier) {
-        return variable as VariableElementImpl;
-      }
-    }
-    for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
-      }
-    }
-    for (FunctionTypeAliasElement typeAlias in _typeAliases) {
-      if ((typeAlias as FunctionTypeAliasElementImpl).identifier ==
-          identifier) {
-        return typeAlias as FunctionTypeAliasElementImpl;
-      }
-    }
-    for (ClassElement type in _types) {
-      if ((type as ClassElementImpl).identifier == identifier) {
-        return type as ClassElementImpl;
-      }
-    }
-    for (ClassElement type in _enums) {
-      if ((type as ClassElementImpl).identifier == identifier) {
-        return type as ClassElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  Element getElementAt(int offset) {
-    if (_offsetToElementMap.isEmpty) {
-      accept(new _BuildOffsetToElementMap(_offsetToElementMap));
-    }
-    return _offsetToElementMap[offset];
-  }
-
-  @override
-  ClassElement getEnum(String enumName) {
-    for (ClassElement enumDeclaration in _enums) {
-      if (enumDeclaration.name == enumName) {
-        return enumDeclaration;
-      }
-    }
-    return null;
-  }
-
-  @override
-  ClassElement getType(String className) {
-    for (ClassElement type in _types) {
-      if (type.name == className) {
-        return type;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Replace the given [from] top-level variable with [to] in this compilation unit.
-   */
-  void replaceTopLevelVariable(
-      TopLevelVariableElement from, TopLevelVariableElement to) {
-    int index = _variables.indexOf(from);
-    _variables[index] = to;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_accessors, visitor);
-    safelyVisitChildren(_enums, visitor);
-    safelyVisitChildren(_functions, visitor);
-    safelyVisitChildren(_typeAliases, visitor);
-    safelyVisitChildren(_types, visitor);
-    safelyVisitChildren(_variables, visitor);
-  }
-}
-
-/**
- * A [FieldElement] for a 'const' or 'final' field that has an initializer.
- *
- * TODO(paulberry): we should rename this class to reflect the fact that it's
- * used for both const and final fields.  However, we shouldn't do so until
- * we've created an API for reading the values of constants; until that API is
- * available, clients are likely to read constant values by casting to
- * ConstFieldElementImpl, so it would be a breaking change to rename this
- * class.
- */
-class ConstFieldElementImpl extends FieldElementImpl with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created synthetic field element to have the given
-   * [name] and [offset].
-   */
-  ConstFieldElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
-  ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * A [LocalVariableElement] for a local 'const' variable that has an
- * initializer.
- */
-class ConstLocalVariableElementImpl extends LocalVariableElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created local variable element to have the given [name]
-   * and [offset].
-   */
-  ConstLocalVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created local variable element to have the given [name].
-   */
-  ConstLocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * An element representing a constructor or a factory method defined within a
- * class.
- */
-abstract class ConstructorElement
-    implements ClassMemberElement, ExecutableElement, ConstantEvaluationTarget {
-  /**
-   * An empty list of constructor elements.
-   */
-  static const List<ConstructorElement> EMPTY_LIST =
-      const <ConstructorElement>[];
-
-  /**
-   * Return `true` if this constructor is a const constructor.
-   */
-  bool get isConst;
-
-  /**
-   * Return `true` if this constructor can be used as a default constructor -
-   * unnamed and has no required parameters.
-   */
-  bool get isDefaultConstructor;
-
-  /**
-   * Return `true` if this constructor represents a factory constructor.
-   */
-  bool get isFactory;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this constructor's name, or `null` if not named.
-   */
-  int get nameEnd;
-
-  /**
-   * Return the offset of the `.` before this constructor name, or `null` if
-   * not named.
-   */
-  int get periodOffset;
-
-  /**
-   * Return the constructor to which this constructor is redirecting, or `null`
-   * if this constructor does not redirect to another constructor or if the
-   * library containing this constructor has not yet been resolved.
-   */
-  ConstructorElement get redirectedConstructor;
-
-  /**
-   * Return the resolved [ConstructorDeclaration] node that declares this
-   * [ConstructorElement] .
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  ConstructorDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [ConstructorElement].
- */
-class ConstructorElementImpl extends ExecutableElementImpl
-    implements ConstructorElement {
-  /**
-   * The constructor to which this constructor is redirecting.
-   */
-  ConstructorElement redirectedConstructor;
-
-  /**
-   * The initializers for this constructor (used for evaluating constant
-   * instance creation expressions).
-   */
-  List<ConstructorInitializer> constantInitializers;
-
-  /**
-   * The offset of the `.` before this constructor name or `null` if not named.
-   */
-  int periodOffset;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this constructor's name, or `null` if not named.
-   */
-  int nameEnd;
-
-  /**
-   * True if this constructor has been found by constant evaluation to be free
-   * of redirect cycles, and is thus safe to evaluate.
-   */
-  bool isCycleFree = false;
-
-  /**
-   * Initialize a newly created constructor element to have the given [name] and
-   * [offset].
-   */
-  ConstructorElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created constructor element to have the given [name].
-   */
-  ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this constructor represents a 'const' constructor.
-   */
-  void set const2(bool isConst) {
-    setModifier(Modifier.CONST, isConst);
-  }
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  /**
-   * Set whether this constructor represents a factory method.
-   */
-  void set factory(bool isFactory) {
-    setModifier(Modifier.FACTORY, isFactory);
-  }
-
-  @override
-  bool get isConst => hasModifier(Modifier.CONST);
-
-  @override
-  bool get isDefaultConstructor {
-    // unnamed
-    String name = this.name;
-    if (name != null && name.length != 0) {
-      return false;
-    }
-    // no required parameters
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.REQUIRED) {
-        return false;
-      }
-    }
-    // OK, can be used as default constructor
-    return true;
-  }
-
-  @override
-  bool get isFactory => hasModifier(Modifier.FACTORY);
-
-  @override
-  bool get isStatic => false;
-
-  @override
-  ElementKind get kind => ElementKind.CONSTRUCTOR;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (enclosingElement == null) {
-      String message;
-      String name = displayName;
-      if (name != null && !name.isEmpty) {
-        message =
-            'Found constructor element named $name with no enclosing element';
-      } else {
-        message = 'Found unnamed constructor element with no enclosing element';
-      }
-      AnalysisEngine.instance.logger.logError(message);
-      buffer.write('<unknown class>');
-    } else {
-      buffer.write(enclosingElement.displayName);
-    }
-    String name = displayName;
-    if (name != null && !name.isEmpty) {
-      buffer.write(".");
-      buffer.write(name);
-    }
-    super.appendTo(buffer);
-  }
-
-  @override
-  ConstructorDeclaration computeNode() =>
-      getNodeMatching((node) => node is ConstructorDeclaration);
-}
-
-/**
- * A constructor element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class ConstructorMember extends ExecutableMember implements ConstructorElement {
-  /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType]. If [type] is passed, it
-   * represents the full type of the member, and will take precedence over
-   * the [definingType].
-   */
-  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
-      [FunctionType type])
-      : super(baseElement, definingType, type);
-
-  @override
-  ConstructorElement get baseElement => super.baseElement as ConstructorElement;
-
-  @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isConst => baseElement.isConst;
-
-  @override
-  bool get isDefaultConstructor => baseElement.isDefaultConstructor;
-
-  @override
-  bool get isFactory => baseElement.isFactory;
-
-  @override
-  int get nameEnd => baseElement.nameEnd;
-
-  @override
-  int get periodOffset => baseElement.periodOffset;
-
-  @override
-  ConstructorElement get redirectedConstructor =>
-      from(baseElement.redirectedConstructor, definingType);
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitConstructorElement(this);
-
-  @override
-  ConstructorDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() {
-    ConstructorElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(baseElement.enclosingElement.displayName);
-    String name = displayName;
-    if (name != null && !name.isEmpty) {
-      buffer.write(".");
-      buffer.write(name);
-    }
-    buffer.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(parameters[i]);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * If the given [constructor]'s type is different when any type parameters
-   * from the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create a constructor member representing
-   * the given constructor. Return the member that was created, or the original
-   * constructor if no member was created.
-   */
-  static ConstructorElement from(
-      ConstructorElement constructor, InterfaceType definingType) {
-    if (constructor == null || definingType.typeArguments.length == 0) {
-      return constructor;
-    }
-    FunctionType baseType = constructor.type;
-    if (baseType == null) {
-      // TODO(brianwilkerson) We need to understand when this can happen.
-      return constructor;
-    }
-    List<DartType> argumentTypes = definingType.typeArguments;
-    List<DartType> parameterTypes = definingType.element.type.typeArguments;
-    FunctionType substitutedType =
-        baseType.substitute2(argumentTypes, parameterTypes);
-    if (baseType == substitutedType) {
-      return constructor;
-    }
-    return new ConstructorMember(constructor, definingType, substitutedType);
-  }
-}
-
-/**
- * A [TopLevelVariableElement] for a top-level 'const' variable that has an
- * initializer.
- */
-class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created top-level variable element to have the given
-   * [name].
-   */
-  ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * Mixin used by elements that represent constant variables and have
- * initializers.
- *
- * Note that in correct Dart code, all constant variables must have
- * initializers.  However, analyzer also needs to handle incorrect Dart code,
- * in which case there might be some constant variables that lack initializers.
- * This interface is only used for constant variables that have initializers.
- *
- * This class is not intended to be part of the public API for analyzer.
- */
-abstract class ConstVariableElement {
-  /**
-   * If this element represents a constant variable, and it has an initializer,
-   * a copy of the initializer for the constant.  Otherwise `null`.
-   *
-   * Note that in correct Dart code, all constant variables must have
-   * initializers.  However, analyzer also needs to handle incorrect Dart code,
-   * in which case there might be some constant variables that lack
-   * initializers.
-   */
-  Expression constantInitializer;
-}
-
-/**
- * The type associated with elements in the element model.
- */
-abstract class DartType {
-  /**
-   * An empty list of types.
-   */
-  static const List<DartType> EMPTY_LIST = const <DartType>[];
-
-  /**
-   * Return the name of this type as it should appear when presented to users in
-   * contexts such as error messages.
-   */
-  String get displayName;
-
-  /**
-   * Return the element representing the declaration of this type, or `null` if
-   * the type has not, or cannot, be associated with an element. The former case
-   * will occur if the element model is not yet complete; the latter case will
-   * occur if this object represents an undefined type.
-   */
-  Element get element;
-
-  /**
-   * Return `true` if this type represents the bottom type.
-   */
-  bool get isBottom;
-
-  /**
-   * Return `true` if this type represents the type 'Function' defined in the
-   * dart:core library.
-   */
-  bool get isDartCoreFunction;
-
-  /**
-   * Return `true` if this type represents the type 'dynamic'.
-   */
-  bool get isDynamic;
-
-  /**
-   * Return `true` if this type represents the type 'Object'.
-   */
-  bool get isObject;
-
-  /**
-   * Return `true` if this type represents a typename that couldn't be resolved.
-   */
-  bool get isUndefined;
-
-  /**
-   * Return `true` if this type represents the type 'void'.
-   */
-  bool get isVoid;
-
-  /**
-   * Return the name of this type, or `null` if the type does not have a name,
-   * such as when the type represents the type of an unnamed function.
-   */
-  String get name;
-
-  /**
-   * Return `true` if this type is assignable to the given [type]. A type
-   * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
-   * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
-   */
-  bool isAssignableTo(DartType type);
-
-  /**
-   * Return `true` if this type is more specific than the given [type].
-   */
-  bool isMoreSpecificThan(DartType type);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type].
-   */
-  bool isSubtypeOf(DartType type);
-
-  /**
-   * Return `true` if this type is a supertype of the given [type]. A type
-   * <i>S</i> is a supertype of <i>T</i>, written <i>S</i> :> <i>T</i>, iff
-   * <i>T</i> is a subtype of <i>S</i>.
-   */
-  bool isSupertypeOf(DartType type);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * the given [parameterTypes] in this type. The specification defines this
-   * operation in section 2:
-   * <blockquote>
-   * The notation <i>[x<sub>1</sub>, ..., x<sub>n</sub>/y<sub>1</sub>, ...,
-   * y<sub>n</sub>]E</i> denotes a copy of <i>E</i> in which all occurrences of
-   * <i>y<sub>i</sub>, 1 <= i <= n</i> have been replaced with
-   * <i>x<sub>i</sub></i>.
-   * </blockquote>
-   * Note that, contrary to the specification, this method will not create a
-   * copy of this type if no substitutions were required, but will return this
-   * type directly.
-   *
-   * Note too that the current implementation of this method is only guaranteed
-   * to work when the parameter types are type variables.
-   */
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-}
-
-/**
- * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
- */
-class DefaultFieldFormalParameterElementImpl
-    extends FieldFormalParameterElementImpl with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-}
-
-/**
- * A [ParameterElement] for parameters that have an initializer.
- */
-class DefaultParameterElementImpl extends ParameterElementImpl
-    with ConstVariableElement {
-  /**
-   * The result of evaluating this variable's initializer.
-   */
-  EvaluationResultImpl _result;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  DefaultParameterElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  DartObject get constantValue => _result.value;
-
-  @override
-  EvaluationResultImpl get evaluationResult => _result;
-
-  @override
-  void set evaluationResult(EvaluationResultImpl result) {
-    this._result = result;
-  }
-
-  @override
-  DefaultFormalParameter computeNode() =>
-      getNodeMatching((node) => node is DefaultFormalParameter);
-}
-
-/**
- * The synthetic element representing the declaration of the type `dynamic`.
- */
-class DynamicElementImpl extends ElementImpl implements TypeDefiningElement {
-  /**
-   * Return the unique instance of this class.
-   */
-  static DynamicElementImpl get instance =>
-      DynamicTypeImpl.instance.element as DynamicElementImpl;
-
-  @override
-  DynamicTypeImpl type;
-
-  /**
-   * Initialize a newly created instance of this class. Instances of this class
-   * should <b>not</b> be created except as part of creating the type associated
-   * with this element. The single instance of this class should be accessed
-   * through the method [getInstance].
-   */
-  DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
-    setModifier(Modifier.SYNTHETIC, true);
-  }
-
-  @override
-  ElementKind get kind => ElementKind.DYNAMIC;
-
-  @override
-  accept(ElementVisitor visitor) => null;
-}
-
-/**
- * The [Type] representing the type `dynamic`.
- */
-class DynamicTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static DynamicTypeImpl _INSTANCE = new DynamicTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static DynamicTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  DynamicTypeImpl._()
-      : super(new DynamicElementImpl(), Keyword.DYNAMIC.syntax) {
-    (element as DynamicElementImpl).type = this;
-  }
-
-  /**
-   * Constructor used by [CircularTypeImpl].
-   */
-  DynamicTypeImpl._circular()
-      : super(_INSTANCE.element, Keyword.DYNAMIC.syntax);
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool get isDynamic => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // T is S
-    if (identical(this, type)) {
-      return true;
-    }
-    // else
-    return withDynamic;
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => true;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-}
-
-/**
- * The base class for all of the elements in the element model. Generally
- * speaking, the element model is a semantic model of the program that
- * represents things that are declared with a name and hence can be referenced
- * elsewhere in the code.
- *
- * There are two exceptions to the general case. First, there are elements in
- * the element model that are created for the convenience of various kinds of
- * analysis but that do not have any corresponding declaration within the source
- * code. Such elements are marked as being <i>synthetic</i>. Examples of
- * synthetic elements include
- * * default constructors in classes that do not define any explicit
- *   constructors,
- * * getters and setters that are induced by explicit field declarations,
- * * fields that are induced by explicit declarations of getters and setters,
- *   and
- * * functions representing the initialization expression for a variable.
- *
- * Second, there are elements in the element model that do not have a name.
- * These correspond to unnamed functions and exist in order to more accurately
- * represent the semantic structure of the program.
- */
-abstract class Element implements AnalysisTarget {
-  /**
-   * An Unicode right arrow.
-   */
-  static final String RIGHT_ARROW = " \u2192 ";
-
-  /**
-   * A comparator that can be used to sort elements by their name offset.
-   * Elements with a smaller offset will be sorted to be before elements with a
-   * larger name offset.
-   */
-  static final Comparator<Element> SORT_BY_OFFSET =
-      (Element firstElement, Element secondElement) =>
-          firstElement.nameOffset - secondElement.nameOffset;
-
-  /**
-   * Return the analysis context in which this element is defined.
-   */
-  AnalysisContext get context;
-
-  /**
-   * Return the display name of this element, or `null` if this element does not
-   * have a name.
-   *
-   * In most cases the name and the display name are the same. Differences
-   * though are cases such as setters where the name of some setter `set f(x)`
-   * is `f=`, instead of `f`.
-   */
-  String get displayName;
-
-  /**
-   * Return the source range of the documentation comment for this element,
-   * or `null` if this element does not or cannot have a documentation.
-   */
-  SourceRange get docRange;
-
-  /**
-   * Return the element that either physically or logically encloses this
-   * element. This will be `null` if this element is a library because libraries
-   * are the top-level elements in the model.
-   */
-  Element get enclosingElement;
-
-  /**
-   * The unique integer identifier of this element.
-   */
-  int get id;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@deprecated'
-   * or '@Deprecated('..')'.
-   */
-  bool get isDeprecated;
-
-  /**
-   * Return `true` if this element has an annotation of the form '@override'.
-   */
-  bool get isOverride;
-
-  /**
-   * Return `true` if this element is private. Private elements are visible only
-   * within the library in which they are declared.
-   */
-  bool get isPrivate;
-
-  /**
-   * Return `true` if this element is public. Public elements are visible within
-   * any library that imports the library in which they are declared.
-   */
-  bool get isPublic;
-
-  /**
-   * Return `true` if this element is synthetic. A synthetic element is an
-   * element that is not represented in the source code explicitly, but is
-   * implied by the source code, such as the default constructor for a class
-   * that does not explicitly define any constructors.
-   */
-  bool get isSynthetic;
-
-  /**
-   * Return the kind of element that this is.
-   */
-  ElementKind get kind;
-
-  /**
-   * Return the library that contains this element. This will be the element
-   * itself if it is a library element. This will be `null` if this element is
-   * an HTML file because HTML files are not contained in libraries.
-   */
-  LibraryElement get library;
-
-  /**
-   * Return an object representing the location of this element in the element
-   * model. The object can be used to locate this element at a later time.
-   */
-  ElementLocation get location;
-
-  /**
-   * Return a list containing all of the metadata associated with this element.
-   * The array will be empty if the element does not have any metadata or if the
-   * library containing this element has not yet been resolved.
-   */
-  List<ElementAnnotation> get metadata;
-
-  /**
-   * Return the name of this element, or `null` if this element does not have a
-   * name.
-   */
-  String get name;
-
-  /**
-   * Return the length of the name of this element in the file that contains the
-   * declaration of this element, or `0` if this element does not have a name.
-   */
-  int get nameLength;
-
-  /**
-   * Return the offset of the name of this element in the file that contains the
-   * declaration of this element, or `-1` if this element is synthetic, does not
-   * have a name, or otherwise does not have an offset.
-   */
-  int get nameOffset;
-
-  /**
-   * Return the source that contains this element, or `null` if this element is
-   * not contained in a source.
-   */
-  Source get source;
-
-  /**
-   * Return the resolved [CompilationUnit] that declares this element, or `null`
-   * if this element is synthetic.
-   *
-   * This method is expensive, because resolved AST might have been already
-   * evicted from cache, so parsing and resolving will be performed.
-   */
-  CompilationUnit get unit;
-
-  /**
-   * Use the given [visitor] to visit this element. Return the value returned by
-   * the visitor as a result of visiting this element.
-   */
-  accept(ElementVisitor visitor);
-
-  /**
-   * Return the documentation comment for this element as it appears in the
-   * original source (complete with the beginning and ending delimiters), or
-   * `null` if this element does not have a documentation comment associated
-   * with it. This can be a long-running operation if the information needed to
-   * access the comment is not cached.
-   *
-   * Throws [AnalysisException] if the documentation comment could not be
-   * determined because the analysis could not be performed
-   */
-  String computeDocumentationComment();
-
-  /**
-   * Return the resolved [AstNode] node that declares this element, or `null` if
-   * this element is synthetic or isn't contained in a compilation unit, such as
-   * a [LibraryElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  AstNode computeNode();
-
-  /**
-   * Return the most immediate ancestor of this element for which the
-   * [predicate] returns `true`, or `null` if there is no such ancestor. Note
-   * that this element will never be returned.
-   */
-  Element getAncestor(Predicate<Element> predicate);
-
-  /**
-   * Return a display name for the given element that includes the path to the
-   * compilation unit in which the type is defined. If [shortName] is `null`
-   * then [getDisplayName] will be used as the name of this element. Otherwise
-   * the provided name will be used.
-   */
-  // TODO(brianwilkerson) Make the parameter optional.
-  String getExtendedDisplayName(String shortName);
-
-  /**
-   * Return `true` if this element, assuming that it is within scope, is
-   * accessible to code in the given [library]. This is defined by the Dart
-   * Language Specification in section 3.2:
-   * <blockquote>
-   * A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
-   * declared in <i>L</i> or if <i>m</i> is public.
-   * </blockquote>
-   */
-  bool isAccessibleIn(LibraryElement library);
-
-  /**
-   * Use the given [visitor] to visit all of the children of this element. There
-   * is no guarantee of the order in which the children will be visited.
-   */
-  void visitChildren(ElementVisitor visitor);
-}
-
-/**
- * A single annotation associated with an element.
- */
-abstract class ElementAnnotation {
-  /**
-   * An empty list of annotations.
-   */
-  static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
-
-  /**
-   * Return a representation of the value of this annotation.
-   *
-   * Return `null` if the value of this annotation could not be computed because
-   * of errors.
-   */
-  DartObject get constantValue;
-
-  /**
-   * Return the element representing the field, variable, or const constructor
-   * being used as an annotation.
-   */
-  Element get element;
-
-  /**
-   * Return `true` if this annotation marks the associated element as being
-   * deprecated.
-   */
-  bool get isDeprecated;
-
-  /**
-   * Return `true` if this annotation marks the associated method as being
-   * expected to override an inherited method.
-   */
-  bool get isOverride;
-
-  /**
-   * Return `true` if this annotation marks the associated class as implementing
-   * a proxy object.
-   */
-  bool get isProxy;
-}
-
-/**
- * A concrete implementation of an [ElementAnnotation].
- */
-class ElementAnnotationImpl implements ElementAnnotation {
-  /**
-   * The name of the class used to mark an element as being deprecated.
-   */
-  static String _DEPRECATED_CLASS_NAME = "Deprecated";
-
-  /**
-   * The name of the top-level variable used to mark an element as being
-   * deprecated.
-   */
-  static String _DEPRECATED_VARIABLE_NAME = "deprecated";
-
-  /**
-   * The name of the top-level variable used to mark a method as being expected
-   * to override an inherited method.
-   */
-  static String _OVERRIDE_VARIABLE_NAME = "override";
-
-  /**
-   * The name of the top-level variable used to mark a class as implementing a
-   * proxy object.
-   */
-  static String PROXY_VARIABLE_NAME = "proxy";
-
-  /**
-   * The element representing the field, variable, or constructor being used as
-   * an annotation.
-   */
-  final Element element;
-
-  /**
-   * The result of evaluating this annotation as a compile-time constant
-   * expression, or `null` if the compilation unit containing the variable has
-   * not been resolved.
-   */
-  EvaluationResultImpl evaluationResult;
-
-  /**
-   * Initialize a newly created annotation. The given [element] is the element
-   * representing the field, variable, or constructor being used as an
-   * annotation.
-   */
-  ElementAnnotationImpl(this.element);
-
-  @override
-  DartObject get constantValue => evaluationResult.value;
-
-  @override
-  bool get isDeprecated {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is ConstructorElement) {
-          ConstructorElement constructorElement = element as ConstructorElement;
-          if (constructorElement.enclosingElement.name ==
-              _DEPRECATED_CLASS_NAME) {
-            return true;
-          }
-        } else if (element is PropertyAccessorElement &&
-            element.name == _DEPRECATED_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isOverride {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is PropertyAccessorElement &&
-            element.name == _OVERRIDE_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isProxy {
-    if (element != null) {
-      LibraryElement library = element.library;
-      if (library != null && library.isDartCore) {
-        if (element is PropertyAccessorElement &&
-            element.name == PROXY_VARIABLE_NAME) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  String toString() => '@$element';
-}
-
-/**
- * A base class for concrete implementations of an [Element].
- */
-abstract class ElementImpl implements Element {
-  static int _NEXT_ID = 0;
-
-  final int id = _NEXT_ID++;
-
-  /**
-   * The enclosing element of this element, or `null` if this element is at the
-   * root of the element structure.
-   */
-  ElementImpl _enclosingElement;
-
-  /**
-   * The name of this element.
-   */
-  String _name;
-
-  /**
-   * The offset of the name of this element in the file that contains the
-   * declaration of this element.
-   */
-  int _nameOffset = 0;
-
-  /**
-   * A bit-encoded form of the modifiers associated with this element.
-   */
-  int _modifiers = 0;
-
-  /**
-   * A list containing all of the metadata associated with this element.
-   */
-  List<ElementAnnotation> metadata = ElementAnnotation.EMPTY_LIST;
-
-  /**
-   * A cached copy of the calculated hashCode for this element.
-   */
-  int _cachedHashCode;
-
-  /**
-   * A cached copy of the calculated location for this element.
-   */
-  ElementLocation _cachedLocation;
-
-  /**
-   * The offset to the beginning of the documentation comment,
-   * or `null` if this element does not have a documentation comment.
-   */
-  int _docRangeOffset;
-
-  /**
-   * The length of the documentation comment range for this element.
-   */
-  int _docRangeLength;
-
-  /**
-   * Initialize a newly created element to have the given [name] at the given
-   * [_nameOffset].
-   */
-  ElementImpl(String name, this._nameOffset) {
-    this._name = StringUtilities.intern(name);
-  }
-
-  /**
-   * Initialize a newly created element to have the given [name].
-   */
-  ElementImpl.forNode(Identifier name)
-      : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
-
-  @override
-  AnalysisContext get context {
-    if (_enclosingElement == null) {
-      return null;
-    }
-    return _enclosingElement.context;
-  }
-
-  @override
-  String get displayName => _name;
-
-  @override
-  SourceRange get docRange {
-    if (_docRangeOffset != null && _docRangeLength != null) {
-      return new SourceRange(_docRangeOffset, _docRangeLength);
-    }
-    return null;
-  }
-
-  @override
-  Element get enclosingElement => _enclosingElement;
-
-  /**
-   * Set the enclosing element of this element to the given [element].
-   */
-  void set enclosingElement(Element element) {
-    _enclosingElement = element as ElementImpl;
-    _cachedLocation = null;
-    _cachedHashCode = null;
-  }
-
-  @override
-  int get hashCode {
-    // TODO: We might want to re-visit this optimization in the future.
-    // We cache the hash code value as this is a very frequently called method.
-    if (_cachedHashCode == null) {
-      int hashIdentifier = identifier.hashCode;
-      Element enclosing = enclosingElement;
-      if (enclosing != null) {
-        _cachedHashCode = hashIdentifier + enclosing.hashCode;
-      } else {
-        _cachedHashCode = hashIdentifier;
-      }
-    }
-    return _cachedHashCode;
-  }
-
-  /**
-   * Return an identifier that uniquely identifies this element among the
-   * children of this element's parent.
-   */
-  String get identifier => name;
-
-  @override
-  bool get isDeprecated {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isDeprecated) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isOverride {
-    for (ElementAnnotation annotation in metadata) {
-      if (annotation.isOverride) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isPrivate {
-    String name = displayName;
-    if (name == null) {
-      return true;
-    }
-    return Identifier.isPrivateName(name);
-  }
-
-  @override
-  bool get isPublic => !isPrivate;
-
-  @override
-  bool get isSynthetic => hasModifier(Modifier.SYNTHETIC);
-
-  @override
-  LibraryElement get library =>
-      getAncestor((element) => element is LibraryElement);
-
-  @override
-  ElementLocation get location {
-    if (_cachedLocation == null) {
-      _cachedLocation = new ElementLocationImpl.con1(this);
-    }
-    return _cachedLocation;
-  }
-
-  @override
-  String get name => _name;
-
-  void set name(String name) {
-    this._name = name;
-    _cachedLocation = null;
-    _cachedHashCode = null;
-  }
-
-  @override
-  int get nameLength => displayName != null ? displayName.length : 0;
-
-  @override
-  int get nameOffset => _nameOffset;
-
-  /**
-   * Sets the offset of the name of this element in the file that contains the
-   * declaration of this element.
-   */
-  void set nameOffset(int offset) {
-    _nameOffset = offset;
-    _cachedHashCode = null;
-    _cachedLocation = null;
-  }
-
-  @override
-  Source get source {
-    if (_enclosingElement == null) {
-      return null;
-    }
-    return _enclosingElement.source;
-  }
-
-  /**
-   * Set whether this element is synthetic.
-   */
-  void set synthetic(bool isSynthetic) {
-    setModifier(Modifier.SYNTHETIC, isSynthetic);
-  }
-
-  @override
-  CompilationUnit get unit => context.resolveCompilationUnit(source, library);
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(this, object)) {
-      return true;
-    }
-    if (object == null || hashCode != object.hashCode) {
-      return false;
-    }
-    return object.runtimeType == runtimeType &&
-        (object as Element).location == location;
-  }
-
-  /**
-   * Append a textual representation of this element to the given [buffer].
-   */
-  void appendTo(StringBuffer buffer) {
-    if (_name == null) {
-      buffer.write("<unnamed ");
-      buffer.write(runtimeType.toString());
-      buffer.write(">");
-    } else {
-      buffer.write(_name);
-    }
-  }
-
-  @override
-  String computeDocumentationComment() {
-    AnalysisContext context = this.context;
-    if (context == null) {
-      return null;
-    }
-    return context.computeDocumentationComment(this);
-  }
-
-  @override
-  AstNode computeNode() => getNodeMatching((node) => node is AstNode);
-
-  /**
-   * Set this element as the enclosing element for given [element].
-   */
-  void encloseElement(ElementImpl element) {
-    element.enclosingElement = this;
-  }
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) {
-    Element ancestor = _enclosingElement;
-    while (ancestor != null && !predicate(ancestor)) {
-      ancestor = ancestor.enclosingElement;
-    }
-    return ancestor;
-  }
-
-  /**
-   * Return the child of this element that is uniquely identified by the given
-   * [identifier], or `null` if there is no such child.
-   */
-  ElementImpl getChild(String identifier) => null;
-
-  @override
-  String getExtendedDisplayName(String shortName) {
-    if (shortName == null) {
-      shortName = displayName;
-    }
-    Source source = this.source;
-    if (source != null) {
-      return "$shortName (${source.fullName})";
-    }
-    return shortName;
-  }
-
-  /**
-   * Return the resolved [AstNode] of the given type enclosing [getNameOffset].
-   */
-  AstNode getNodeMatching(Predicate<AstNode> predicate) {
-    CompilationUnit unit = this.unit;
-    if (unit == null) {
-      return null;
-    }
-    int offset = nameOffset;
-    AstNode node = new NodeLocator(offset).searchWithin(unit);
-    if (node == null) {
-      return null;
-    }
-    return node.getAncestor(predicate);
-  }
-
-  /**
-   * Return `true` if this element has the given [modifier] associated with it.
-   */
-  bool hasModifier(Modifier modifier) =>
-      BooleanArray.getEnum(_modifiers, modifier);
-
-  @override
-  bool isAccessibleIn(LibraryElement library) {
-    if (Identifier.isPrivateName(_name)) {
-      return library == this.library;
-    }
-    return true;
-  }
-
-  /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  void safelyVisitChild(Element child, ElementVisitor visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
-   * Use the given [visitor] to visit all of the [children] in the given array.
-   */
-  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
-    if (children != null) {
-      for (Element child in children) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Set the documentation comment source range for this element.
-   */
-  void setDocRange(int offset, int length) {
-    _docRangeOffset = offset;
-    _docRangeLength = length;
-  }
-
-  /**
-   * Set whether the given [modifier] is associated with this element to
-   * correspond to the given [value].
-   */
-  void setModifier(Modifier modifier, bool value) {
-    _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    appendTo(buffer);
-    return buffer.toString();
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-}
-
-/**
- * The enumeration `ElementKind` defines the various kinds of elements in the
- * element model.
- */
-class ElementKind extends Enum<ElementKind> {
-  static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
-
-  static const ElementKind COMPILATION_UNIT =
-      const ElementKind('COMPILATION_UNIT', 1, "compilation unit");
-
-  static const ElementKind CONSTRUCTOR =
-      const ElementKind('CONSTRUCTOR', 2, "constructor");
-
-  static const ElementKind DYNAMIC =
-      const ElementKind('DYNAMIC', 3, "<dynamic>");
-
-  static const ElementKind EMBEDDED_HTML_SCRIPT =
-      const ElementKind('EMBEDDED_HTML_SCRIPT', 4, "embedded html script");
-
-  static const ElementKind ERROR = const ElementKind('ERROR', 5, "<error>");
-
-  static const ElementKind EXPORT =
-      const ElementKind('EXPORT', 6, "export directive");
-
-  static const ElementKind EXTERNAL_HTML_SCRIPT =
-      const ElementKind('EXTERNAL_HTML_SCRIPT', 7, "external html script");
-
-  static const ElementKind FIELD = const ElementKind('FIELD', 8, "field");
-
-  static const ElementKind FUNCTION =
-      const ElementKind('FUNCTION', 9, "function");
-
-  static const ElementKind GETTER = const ElementKind('GETTER', 10, "getter");
-
-  static const ElementKind HTML = const ElementKind('HTML', 11, "html");
-
-  static const ElementKind IMPORT =
-      const ElementKind('IMPORT', 12, "import directive");
-
-  static const ElementKind LABEL = const ElementKind('LABEL', 13, "label");
-
-  static const ElementKind LIBRARY =
-      const ElementKind('LIBRARY', 14, "library");
-
-  static const ElementKind LOCAL_VARIABLE =
-      const ElementKind('LOCAL_VARIABLE', 15, "local variable");
-
-  static const ElementKind METHOD = const ElementKind('METHOD', 16, "method");
-
-  static const ElementKind NAME = const ElementKind('NAME', 17, "<name>");
-
-  static const ElementKind PARAMETER =
-      const ElementKind('PARAMETER', 18, "parameter");
-
-  static const ElementKind PREFIX =
-      const ElementKind('PREFIX', 19, "import prefix");
-
-  static const ElementKind SETTER = const ElementKind('SETTER', 20, "setter");
-
-  static const ElementKind TOP_LEVEL_VARIABLE =
-      const ElementKind('TOP_LEVEL_VARIABLE', 21, "top level variable");
-
-  static const ElementKind FUNCTION_TYPE_ALIAS =
-      const ElementKind('FUNCTION_TYPE_ALIAS', 22, "function type alias");
-
-  static const ElementKind TYPE_PARAMETER =
-      const ElementKind('TYPE_PARAMETER', 23, "type parameter");
-
-  static const ElementKind UNIVERSE =
-      const ElementKind('UNIVERSE', 24, "<universe>");
-
-  static const List<ElementKind> values = const [
-    CLASS,
-    COMPILATION_UNIT,
-    CONSTRUCTOR,
-    DYNAMIC,
-    EMBEDDED_HTML_SCRIPT,
-    ERROR,
-    EXPORT,
-    EXTERNAL_HTML_SCRIPT,
-    FIELD,
-    FUNCTION,
-    GETTER,
-    HTML,
-    IMPORT,
-    LABEL,
-    LIBRARY,
-    LOCAL_VARIABLE,
-    METHOD,
-    NAME,
-    PARAMETER,
-    PREFIX,
-    SETTER,
-    TOP_LEVEL_VARIABLE,
-    FUNCTION_TYPE_ALIAS,
-    TYPE_PARAMETER,
-    UNIVERSE
-  ];
-
-  /**
-   * The name displayed in the UI for this kind of element.
-   */
-  final String displayName;
-
-  /**
-   * Initialize a newly created element kind to have the given [displayName].
-   */
-  const ElementKind(String name, int ordinal, this.displayName)
-      : super(name, ordinal);
-
-  /**
-   * Return the kind of the given [element], or [ERROR] if the element is
-   * `null`. This is a utility method that can reduce the need for null checks
-   * in other places.
-   */
-  static ElementKind of(Element element) {
-    if (element == null) {
-      return ERROR;
-    }
-    return element.kind;
-  }
-}
-
-/**
- * The location of an element within the element model.
- */
-abstract class ElementLocation {
-  /**
-   * Return the path to the element whose location is represented by this
-   * object. Clients must not modify the returned array.
-   */
-  List<String> get components;
-
-  /**
-   * Return an encoded representation of this location that can be used to
-   * create a location that is equal to this location.
-   */
-  String get encoding;
-}
-
-/**
- * A concrete implementation of an [ElementLocation].
- */
-class ElementLocationImpl implements ElementLocation {
-  /**
-   * The character used to separate components in the encoded form.
-   */
-  static int _SEPARATOR_CHAR = 0x3B;
-
-  /**
-   * The path to the element whose location is represented by this object.
-   */
-  List<String> _components;
-
-  /**
-   * The object managing [indexKeyId] and [indexLocationId].
-   */
-  Object indexOwner;
-
-  /**
-   * A cached id of this location in index.
-   */
-  int indexKeyId;
-
-  /**
-   * A cached id of this location in index.
-   */
-  int indexLocationId;
-
-  /**
-   * Initialize a newly created location to represent the given [element].
-   */
-  ElementLocationImpl.con1(Element element) {
-    List<String> components = new List<String>();
-    Element ancestor = element;
-    while (ancestor != null) {
-      components.insert(0, (ancestor as ElementImpl).identifier);
-      ancestor = ancestor.enclosingElement;
-    }
-    this._components = components;
-  }
-
-  /**
-   * Initialize a newly created location from the given [encoding].
-   */
-  ElementLocationImpl.con2(String encoding) {
-    this._components = _decode(encoding);
-  }
-
-  /**
-   * Initialize a newly created location from the given [components].
-   */
-  ElementLocationImpl.con3(List<String> components) {
-    this._components = components;
-  }
-
-  @override
-  List<String> get components => _components;
-
-  @override
-  String get encoding {
-    StringBuffer buffer = new StringBuffer();
-    int length = _components.length;
-    for (int i = 0; i < length; i++) {
-      if (i > 0) {
-        buffer.writeCharCode(_SEPARATOR_CHAR);
-      }
-      _encode(buffer, _components[i]);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  int get hashCode {
-    int result = 1;
-    for (int i = 0; i < _components.length; i++) {
-      String component = _components[i];
-      result = 31 * result + component.hashCode;
-    }
-    return result;
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(this, object)) {
-      return true;
-    }
-    if (object is! ElementLocationImpl) {
-      return false;
-    }
-    ElementLocationImpl location = object as ElementLocationImpl;
-    List<String> otherComponents = location._components;
-    int length = _components.length;
-    if (otherComponents.length != length) {
-      return false;
-    }
-    for (int i = 0; i < length; i++) {
-      if (_components[i] != otherComponents[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
-  String toString() => encoding;
-
-  /**
-   * Decode the [encoding] of a location into a list of components and return
-   * the components.
-   */
-  List<String> _decode(String encoding) {
-    List<String> components = new List<String>();
-    StringBuffer buffer = new StringBuffer();
-    int index = 0;
-    int length = encoding.length;
-    while (index < length) {
-      int currentChar = encoding.codeUnitAt(index);
-      if (currentChar == _SEPARATOR_CHAR) {
-        if (index + 1 < length &&
-            encoding.codeUnitAt(index + 1) == _SEPARATOR_CHAR) {
-          buffer.writeCharCode(_SEPARATOR_CHAR);
-          index += 2;
-        } else {
-          components.add(buffer.toString());
-          buffer = new StringBuffer();
-          index++;
-        }
-      } else {
-        buffer.writeCharCode(currentChar);
-        index++;
-      }
-    }
-    components.add(buffer.toString());
-    return components;
-  }
-
-  /**
-   * Append an encoded form of the given [component] to the given [buffer].
-   */
-  void _encode(StringBuffer buffer, String component) {
-    int length = component.length;
-    for (int i = 0; i < length; i++) {
-      int currentChar = component.codeUnitAt(i);
-      if (currentChar == _SEPARATOR_CHAR) {
-        buffer.writeCharCode(_SEPARATOR_CHAR);
-      }
-      buffer.writeCharCode(currentChar);
-    }
-  }
-}
-
-/**
- * An object that can be used to visit an element structure.
- */
-abstract class ElementVisitor<R> {
-  R visitClassElement(ClassElement element);
-
-  R visitCompilationUnitElement(CompilationUnitElement element);
-
-  R visitConstructorElement(ConstructorElement element);
-
-  R visitExportElement(ExportElement element);
-
-  R visitFieldElement(FieldElement element);
-
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element);
-
-  R visitFunctionElement(FunctionElement element);
-
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
-
-  R visitImportElement(ImportElement element);
-
-  R visitLabelElement(LabelElement element);
-
-  R visitLibraryElement(LibraryElement element);
-
-  R visitLocalVariableElement(LocalVariableElement element);
-
-  R visitMethodElement(MethodElement element);
-
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element);
-
-  R visitParameterElement(ParameterElement element);
-
-  R visitPrefixElement(PrefixElement element);
-
-  R visitPropertyAccessorElement(PropertyAccessorElement element);
-
-  R visitTopLevelVariableElement(TopLevelVariableElement element);
-
-  R visitTypeParameterElement(TypeParameterElement element);
-}
-
-/**
- * An element representing an executable object, including functions, methods,
- * constructors, getters, and setters.
- */
-abstract class ExecutableElement implements FunctionTypedElement {
-  /**
-   * An empty list of executable elements.
-   */
-  static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
-
-  /**
-   * Return a list containing all of the functions defined within this
-   * executable element.
-   */
-  List<FunctionElement> get functions;
-
-  /**
-   * Return `true` if this executable element did not have an explicit return
-   * type specified for it in the original source. Note that if there was no
-   * explicit return type, and if the element model is fully populated, then
-   * the [returnType] will not be `null`.
-   */
-  bool get hasImplicitReturnType;
-
-  /**
-   * Return `true` if this executable element is abstract. Executable elements
-   * are abstract if they are not external and have no body.
-   */
-  bool get isAbstract;
-
-  /**
-   * Return `true` if this executable element has body marked as being
-   * asynchronous.
-   */
-  bool get isAsynchronous;
-
-  /**
-   * Return `true` if this executable element is external. Executable elements
-   * are external if they are explicitly marked as such using the 'external'
-   * keyword.
-   */
-  bool get isExternal;
-
-  /**
-   * Return `true` if this executable element has a body marked as being a
-   * generator.
-   */
-  bool get isGenerator;
-
-  /**
-   * Return `true` if this executable element is an operator. The test may be
-   * based on the name of the executable element, in which case the result will
-   * be correct when the name is legal.
-   */
-  bool get isOperator;
-
-  /**
-   * Return `true` if this element is a static element. A static element is an
-   * element that is not associated with a particular instance, but rather with
-   * an entire library or class.
-   */
-  bool get isStatic;
-
-  /**
-   * Return `true` if this executable element has a body marked as being
-   * synchronous.
-   */
-  bool get isSynchronous;
-
-  /**
-   * Return a list containing all of the labels defined within this executable
-   * element.
-   */
-  List<LabelElement> get labels;
-
-  /**
-   * Return a list containing all of the local variables defined within this
-   * executable element.
-   */
-  List<LocalVariableElement> get localVariables;
-}
-
-/**
- * A base class for concrete implementations of an [ExecutableElement].
- */
-abstract class ExecutableElementImpl extends ElementImpl
-    implements ExecutableElement {
-  /**
-   * A list containing all of the functions defined within this executable
-   * element.
-   */
-  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the labels defined within this executable element.
-   */
-  List<LabelElement> _labels = LabelElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the local variables defined within this executable
-   * element.
-   */
-  List<LocalVariableElement> _localVariables = LocalVariableElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the parameters defined by this executable element.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the type parameters defined for this executable
-   * element.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The return type defined by this executable element.
-   */
-  DartType returnType;
-
-  /**
-   * The type of function defined by this executable element.
-   */
-  FunctionType type;
-
-  /**
-   * Initialize a newly created executable element to have the given [name] and
-   * [offset].
-   */
-  ExecutableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created executable element to have the given [name].
-   */
-  ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this executable element's body is asynchronous.
-   */
-  void set asynchronous(bool isAsynchronous) {
-    setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
-  }
-
-  /**
-   * Set whether this executable element is external.
-   */
-  void set external(bool isExternal) {
-    setModifier(Modifier.EXTERNAL, isExternal);
-  }
-
-  @override
-  List<FunctionElement> get functions => _functions;
-
-  /**
-   * Set the functions defined within this executable element to the given
-   * [functions].
-   */
-  void set functions(List<FunctionElement> functions) {
-    for (FunctionElement function in functions) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._functions = functions;
-  }
-
-  /**
-   * Set whether this method's body is a generator.
-   */
-  void set generator(bool isGenerator) {
-    setModifier(Modifier.GENERATOR, isGenerator);
-  }
-
-  @override
-  bool get hasImplicitReturnType => hasModifier(Modifier.IMPLICIT_TYPE);
-
-  /**
-   * Set whether this executable element has an implicit return type.
-   */
-  void set hasImplicitReturnType(bool hasImplicitReturnType) {
-    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitReturnType);
-  }
-
-  @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
-  bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
-
-  @override
-  bool get isExternal => hasModifier(Modifier.EXTERNAL);
-
-  @override
-  bool get isGenerator => hasModifier(Modifier.GENERATOR);
-
-  @override
-  bool get isOperator => false;
-
-  @override
-  bool get isSynchronous => !hasModifier(Modifier.ASYNCHRONOUS);
-
-  @override
-  List<LabelElement> get labels => _labels;
-
-  /**
-   * Set the labels defined within this executable element to the given
-   * [labels].
-   */
-  void set labels(List<LabelElement> labels) {
-    for (LabelElement label in labels) {
-      (label as LabelElementImpl).enclosingElement = this;
-    }
-    this._labels = labels;
-  }
-
-  @override
-  List<LocalVariableElement> get localVariables => _localVariables;
-
-  /**
-   * Set the local variables defined within this executable element to the given
-   * [variables].
-   */
-  void set localVariables(List<LocalVariableElement> variables) {
-    for (LocalVariableElement variable in variables) {
-      (variable as LocalVariableElementImpl).enclosingElement = this;
-    }
-    this._localVariables = variables;
-  }
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this executable element to the given
-   * [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement = this;
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined by this executable element to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement parameter in typeParameters) {
-      (parameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (this.kind != ElementKind.GETTER) {
-      int typeParameterCount = _typeParameters.length;
-      if (typeParameterCount > 0) {
-        buffer.write('<');
-        for (int i = 0; i < typeParameterCount; i++) {
-          if (i > 0) {
-            buffer.write(", ");
-          }
-          (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-        }
-        buffer.write('>');
-      }
-      buffer.write("(");
-      String closing = null;
-      ParameterKind kind = ParameterKind.REQUIRED;
-      int parameterCount = _parameters.length;
-      for (int i = 0; i < parameterCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        ParameterElementImpl parameter = _parameters[i] as ParameterElementImpl;
-        ParameterKind parameterKind = parameter.parameterKind;
-        if (parameterKind != kind) {
-          if (closing != null) {
-            buffer.write(closing);
-          }
-          if (parameterKind == ParameterKind.POSITIONAL) {
-            buffer.write("[");
-            closing = "]";
-          } else if (parameterKind == ParameterKind.NAMED) {
-            buffer.write("{");
-            closing = "}";
-          } else {
-            closing = null;
-          }
-        }
-        kind = parameterKind;
-        parameter.appendToWithoutDelimiters(buffer);
-      }
-      if (closing != null) {
-        buffer.write(closing);
-      }
-      buffer.write(")");
-    }
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (ExecutableElement function in _functions) {
-      if ((function as ExecutableElementImpl).identifier == identifier) {
-        return function as ExecutableElementImpl;
-      }
-    }
-    for (LabelElement label in _labels) {
-      if ((label as LabelElementImpl).identifier == identifier) {
-        return label as LabelElementImpl;
-      }
-    }
-    for (VariableElement variable in _localVariables) {
-      if ((variable as VariableElementImpl).identifier == identifier) {
-        return variable as VariableElementImpl;
-      }
-    }
-    for (ParameterElement parameter in _parameters) {
-      if ((parameter as ParameterElementImpl).identifier == identifier) {
-        return parameter as ParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_functions, visitor);
-    safelyVisitChildren(_labels, visitor);
-    safelyVisitChildren(_localVariables, visitor);
-    safelyVisitChildren(_parameters, visitor);
-  }
-}
-
-/**
- * An executable element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-abstract class ExecutableMember extends Member implements ExecutableElement {
-  @override
-  final FunctionType type;
-
-  /**
-   * Initialize a newly created element to represent a callable element (like a
-   * method or function or property), based on the [baseElement], defined by the
-   * [definingType]. If [type] is passed, it represents the full type of the
-   * member, and will take precedence over the [definingType].
-   */
-  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
-      [FunctionType type])
-      : type = type ??
-            baseElement.type.substitute2(definingType.typeArguments,
-                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
-        super(baseElement, definingType);
-
-  @override
-  ExecutableElement get baseElement => super.baseElement as ExecutableElement;
-
-  @override
-  List<FunctionElement> get functions {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-//    return getBaseElement().getFunctions();
-  }
-
-  @override
-  bool get hasImplicitReturnType => baseElement.hasImplicitReturnType;
-
-  @override
-  bool get isAbstract => baseElement.isAbstract;
-
-  @override
-  bool get isAsynchronous => baseElement.isAsynchronous;
-
-  @override
-  bool get isExternal => baseElement.isExternal;
-
-  @override
-  bool get isGenerator => baseElement.isGenerator;
-
-  @override
-  bool get isOperator => baseElement.isOperator;
-
-  @override
-  bool get isStatic => baseElement.isStatic;
-
-  @override
-  bool get isSynchronous => baseElement.isSynchronous;
-
-  @override
-  List<LabelElement> get labels => baseElement.labels;
-
-  @override
-  List<LocalVariableElement> get localVariables {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-//    return getBaseElement().getLocalVariables();
-  }
-
-  @override
-  List<ParameterElement> get parameters => type.parameters;
-
-  @override
-  DartType get returnType => type.returnType;
-
-  @override
-  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // TODO(brianwilkerson) We need to finish implementing the accessors used
-    // below so that we can safely invoke them.
-    super.visitChildren(visitor);
-    safelyVisitChildren(baseElement.functions, visitor);
-    safelyVisitChildren(labels, visitor);
-    safelyVisitChildren(baseElement.localVariables, visitor);
-    safelyVisitChildren(parameters, visitor);
-  }
-}
-
-/**
- * An export directive within a library.
- */
-abstract class ExportElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of export elements.
-   */
-  static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
-
-  /**
-   * Return a list containing the combinators that were specified as part of the
-   * export directive in the order in which they were specified.
-   */
-  List<NamespaceCombinator> get combinators;
-
-  /**
-   * Return the library that is exported from this library by this export
-   * directive.
-   */
-  LibraryElement get exportedLibrary;
-}
-
-/**
- * A concrete implementation of an [ExportElement].
- */
-class ExportElementImpl extends UriReferencedElementImpl
-    implements ExportElement {
-  /**
-   * The library that is exported from this library by this export directive.
-   */
-  LibraryElement exportedLibrary;
-
-  /**
-   * The combinators that were specified as part of the export directive in the
-   * order in which they were specified.
-   */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created export element at the given [offset].
-   */
-  ExportElementImpl(int offset) : super(null, offset);
-
-  @override
-  String get identifier => exportedLibrary.name;
-
-  @override
-  ElementKind get kind => ElementKind.EXPORT;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitExportElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("export ");
-    (exportedLibrary as LibraryElementImpl).appendTo(buffer);
-  }
-}
-
-/**
- * A field defined within a type.
- */
-abstract class FieldElement
-    implements ClassMemberElement, PropertyInducingElement {
-  /**
-   * An empty list of field elements.
-   */
-  static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
-
-  /**
-   * Return {@code true} if this element is an enum constant.
-   */
-  bool get isEnumConstant;
-
-  /**
-   * Return the resolved [VariableDeclaration] or [EnumConstantDeclaration]
-   * node that declares this [FieldElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  AstNode computeNode();
-}
-
-/**
- * A concrete implementation of a [FieldElement].
- */
-class FieldElementImpl extends PropertyInducingElementImpl
-    implements FieldElement {
-  /**
-   * Initialize a newly created synthetic field element to have the given [name]
-   * at the given [offset].
-   */
-  FieldElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
-  FieldElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  @override
-  bool get isEnumConstant =>
-      enclosingElement != null ? enclosingElement.isEnum : false;
-
-  @override
-  ElementKind get kind => ElementKind.FIELD;
-
-  /**
-   * Set whether this field is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
-
-  @override
-  AstNode computeNode() {
-    if (isEnumConstant) {
-      return getNodeMatching((node) => node is EnumConstantDeclaration);
-    } else {
-      return getNodeMatching((node) => node is VariableDeclaration);
-    }
-  }
-}
-
-/**
- * A field formal parameter defined within a constructor element.
- */
-abstract class FieldFormalParameterElement implements ParameterElement {
-  /**
-   * Return the field element associated with this field formal parameter, or
-   * `null` if the parameter references a field that doesn't exist.
-   */
-  FieldElement get field;
-}
-
-/**
- * A [ParameterElementImpl] that has the additional information of the
- * [FieldElement] associated with the parameter.
- */
-class FieldFormalParameterElementImpl extends ParameterElementImpl
-    implements FieldFormalParameterElement {
-  /**
-   * The field associated with this field formal parameter.
-   */
-  FieldElement field;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
-
-  @override
-  bool get isInitializingFormal => true;
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitFieldFormalParameterElement(this);
-}
-
-/**
- * A parameter element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class FieldFormalParameterMember extends ParameterMember
-    implements FieldFormalParameterElement {
-  /**
-   * Initialize a newly created element to represent a field formal parameter,
-   * based on the [baseElement], defined by the [definingType]. If [type]
-   * is passed it will be used as the substituted type for this member.
-   */
-  FieldFormalParameterMember(
-      FieldFormalParameterElement baseElement, ParameterizedType definingType,
-      [DartType type])
-      : super(baseElement, definingType, type);
-
-  @override
-  FieldElement get field {
-    FieldElement field = (baseElement as FieldFormalParameterElement).field;
-    if (field is FieldElement) {
-      return FieldMember.from(
-          field, substituteFor(field.enclosingElement.type));
-    }
-    return field;
-  }
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitFieldFormalParameterElement(this);
-}
-
-/**
- * A field element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-class FieldMember extends VariableMember implements FieldElement {
-  /**
-   * Initialize a newly created element to represent a field, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  FieldMember(FieldElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  FieldElement get baseElement => super.baseElement as FieldElement;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  PropertyAccessorElement get getter =>
-      PropertyAccessorMember.from(baseElement.getter, definingType);
-
-  @override
-  bool get isEnumConstant => baseElement.isEnumConstant;
-
-  @override
-  DartType get propagatedType => substituteFor(baseElement.propagatedType);
-
-  @override
-  PropertyAccessorElement get setter =>
-      PropertyAccessorMember.from(baseElement.setter, definingType);
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
-
-  @override
-  VariableDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() => '$type $displayName';
-
-  /**
-   * If the given [field]'s type is different when any type parameters from the
-   * defining type's declaration are replaced with the actual type arguments
-   * from the [definingType], create a field member representing the given
-   * field. Return the member that was created, or the base field if no member
-   * was created.
-   */
-  static FieldElement from(FieldElement field, ParameterizedType definingType) {
-    if (!_isChangedByTypeSubstitution(field, definingType)) {
-      return field;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new FieldMember(field, definingType);
-  }
-
-  /**
-   * Determine whether the given [field]'s type is changed when type parameters
-   * from the [definingType]'s declaration are replaced with the actual type
-   * arguments from the defining type.
-   */
-  static bool _isChangedByTypeSubstitution(
-      FieldElement field, ParameterizedType definingType) {
-    List<DartType> argumentTypes = definingType.typeArguments;
-    if (field != null && argumentTypes.length != 0) {
-      DartType baseType = field.type;
-      List<DartType> parameterTypes =
-          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
-      if (baseType != null) {
-        DartType substitutedType =
-            baseType.substitute2(argumentTypes, parameterTypes);
-        if (baseType != substitutedType) {
-          return true;
-        }
-      }
-      // If the field has a propagated type, then we need to check whether the
-      // propagated type needs substitution.
-      DartType basePropagatedType = field.propagatedType;
-      if (basePropagatedType != null) {
-        DartType substitutedPropagatedType =
-            basePropagatedType.substitute2(argumentTypes, parameterTypes);
-        if (basePropagatedType != substitutedPropagatedType) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * A (non-method) function. This can be either a top-level function, a local
- * function, a closure, or the initialization expression for a field or
- * variable.
- */
-abstract class FunctionElement implements ExecutableElement, LocalElement {
-  /**
-   * An empty list of function elements.
-   */
-  static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
-
-  /**
-   * The name of the method that can be implemented by a class to allow its
-   * instances to be invoked as if they were a function.
-   */
-  static final String CALL_METHOD_NAME = "call";
-
-  /**
-   * The name of the synthetic function defined for libraries that are deferred.
-   */
-  static final String LOAD_LIBRARY_NAME = "loadLibrary";
-
-  /**
-   * The name of the function used as an entry point.
-   */
-  static const String MAIN_FUNCTION_NAME = "main";
-
-  /**
-   * The name of the method that will be invoked if an attempt is made to invoke
-   * an undefined method on an object.
-   */
-  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
-
-  /**
-   * Return `true` if the function is an entry point, i.e. a top-level function
-   * and has the name `main`.
-   */
-  bool get isEntryPoint;
-
-  /**
-   * Return the resolved function declaration node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  FunctionDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [FunctionElement].
- */
-class FunctionElementImpl extends ExecutableElementImpl
-    implements FunctionElement {
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created function element to have the given [name] and
-   * [offset].
-   */
-  FunctionElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created function element to have the given [name].
-   */
-  FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created function element to have no name and the given
-   * [offset]. This is used for function expressions, that have no name.
-   */
-  FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
-
-  @override
-  String get identifier {
-    String identifier = super.identifier;
-    if (!isStatic) {
-      identifier += "@$nameOffset";
-    }
-    return identifier;
-  }
-
-  @override
-  bool get isEntryPoint {
-    return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
-  }
-
-  @override
-  bool get isStatic => enclosingElement is CompilationUnitElement;
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION;
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String name = displayName;
-    if (name != null) {
-      buffer.write(name);
-    }
-    super.appendTo(buffer);
-  }
-
-  @override
-  FunctionDeclaration computeNode() =>
-      getNodeMatching((node) => node is FunctionDeclaration);
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-
-  /**
-   * Set the parameters defined by this type alias to the given [parameters]
-   * without becoming the parent of the parameters. This should only be used by
-   * the [TypeResolverVisitor] when creating a synthetic type alias.
-   */
-  void shareParameters(List<ParameterElement> parameters) {
-    this._parameters = parameters;
-  }
-}
-
-/**
- * An element of a generic function, where the type parameters are known.
- */
-// TODO(jmesserly): the term "function member" is a bit weird, but it allows
-// a certain consistency.
-class FunctionMember extends ExecutableMember implements FunctionElement {
-  /**
-   * Initialize a newly created element to represent a function, based on the
-   * [baseElement], with the corresponding function [type].
-   */
-  FunctionMember(FunctionElement baseElement, [DartType type])
-      : super(baseElement, null, type);
-
-  @override
-  FunctionElement get baseElement => super.baseElement as FunctionElement;
-
-  @override
-  Element get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isEntryPoint => baseElement.isEntryPoint;
-
-  @override
-  SourceRange get visibleRange => baseElement.visibleRange;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
-
-  @override
-  FunctionDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(baseElement.displayName);
-    (type as FunctionTypeImpl).appendTo(buffer);
-    return buffer.toString();
-  }
-
-  /**
-   * If the given [method]'s type is different when any type parameters from the
-   * defining type's declaration are replaced with the actual type arguments
-   * from the [definingType], create a method member representing the given
-   * method. Return the member that was created, or the base method if no member
-   * was created.
-   */
-  static MethodElement from(
-      MethodElement method, ParameterizedType definingType) {
-    if (method == null || definingType.typeArguments.length == 0) {
-      return method;
-    }
-    FunctionType baseType = method.type;
-    List<DartType> argumentTypes = definingType.typeArguments;
-    List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(definingType.typeParameters);
-    FunctionType substitutedType =
-        baseType.substitute2(argumentTypes, parameterTypes);
-    if (baseType == substitutedType) {
-      return method;
-    }
-    return new MethodMember(method, definingType, substitutedType);
-  }
-}
-
-/**
- * The type of a function, method, constructor, getter, or setter. Function
- * types come in three variations:
- *
- * * The types of functions that only have required parameters. These have the
- *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
- * * The types of functions with optional positional parameters. These have the
- *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
- *   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
- * * The types of functions with named parameters. These have the general form
- *   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
- *   T<sub>xk</sub> xk}) &rarr; T</i>.
- */
-abstract class FunctionType implements ParameterizedType {
-  /**
-   * The type parameters of this generic function. For example `<T> T -> T`.
-   *
-   * These are distinct from the [typeParameters] list, which contains type
-   * parameters from surrounding contexts, and thus are free type variables from
-   * the perspective of this function type.
-   */
-  List<TypeParameterElement> get boundTypeParameters;
-
-  /**
-   * Return a map from the names of named parameters to the types of the named
-   * parameters of this type of function. The entries in the map will be
-   * iterated in the same order as the order in which the named parameters were
-   * defined. If there were no named parameters declared then the map will be
-   * empty.
-   */
-  Map<String, DartType> get namedParameterTypes;
-
-  /**
-   * Return a list containing the types of the normal parameters of this type of
-   * function. The parameter types are in the same order as they appear in the
-   * declaration of the function.
-   */
-  List<DartType> get normalParameterTypes;
-
-  /**
-   * 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
-   * optional parameters were defined. If there were no optional parameters
-   * declared then the map will be empty.
-   */
-  List<DartType> get optionalParameterTypes;
-
-  /**
-   * 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.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the type of object returned by this type of function.
-   */
-  DartType get returnType;
-
-  /**
-   * Return the type resulting from instantiating (replacing) the given
-   * [argumentTypes] for this function's bound type parameters.
-   */
-  FunctionType instantiate(List<DartType> argumentTypes);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type].
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
-   * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
-   * &rarr; S</i>, if all of the following conditions are met:
-   *
-   * * Either
-   *   * <i>S</i> is void, or
-   *   * <i>T &hArr; S</i>.
-   *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
-   *   S<sub>i</sub></i>.
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
-   * [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr; T</i> is a subtype of
-   * the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
-   * [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
-   * following conditions are met:
-   *
-   * * Either
-   *   * <i>S</i> is void, or
-   *   * <i>T &hArr; S</i>.
-   *
-   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>,
-   *   <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
-   *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
-   * {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i> is a subtype
-   * of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
-   * {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of
-   * the following conditions are met:
-   * * Either
-   *   * <i>S</i> is void,
-   *   * or <i>T &hArr; S</i>.
-   *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
-   *   S<sub>i</sub></i>.
-   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>,
-   *   &hellip;, x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
-   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;,
-   *   y<sub>m</sub>}</i>, <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
-   *
-   * In addition, the following subtype rules apply:
-   *
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>, {}) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
-   * &hellip;, T<sub>n</sub>, []) &rarr; T.</i>
-   *
-   * All functions implement the class `Function`. However not all function
-   * types are a subtype of `Function`. If an interface type <i>I</i> includes a
-   * method named `call()`, and the type of `call()` is the function type
-   * <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
-   */
-  @override
-  bool isSubtypeOf(DartType type);
-
-  @override
-  FunctionType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * this type's parameters. This is fully equivalent to
-   * `substitute(argumentTypes, getTypeArguments())`.
-   */
-  @deprecated // use instantiate
-  FunctionType substitute3(List<DartType> argumentTypes);
-}
-
-/**
- * A function type alias (`typedef`).
- */
-abstract class FunctionTypeAliasElement
-    implements TypeDefiningElement, FunctionTypedElement {
-  /**
-   * An empty array of type alias elements.
-   */
-  static List<FunctionTypeAliasElement> EMPTY_LIST =
-      new List<FunctionTypeAliasElement>(0);
-
-  /**
-   * Return the compilation unit in which this type alias is defined.
-   */
-  @override
-  CompilationUnitElement get enclosingElement;
-
-  /**
-   * Return the resolved function type alias node that declares this element.
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  FunctionTypeAlias computeNode();
-}
-
-/**
- * A concrete implementation of a [FunctionTypeAliasElement].
- */
-class FunctionTypeAliasElementImpl extends ElementImpl
-    implements FunctionTypeAliasElement {
-  /**
-   * A list containing all of the parameters defined by this type alias.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * The return type defined by this type alias.
-   */
-  DartType returnType;
-
-  /**
-   * The type of function defined by this type alias.
-   */
-  FunctionType type;
-
-  /**
-   * A list containing all of the type parameters defined for this type.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created type alias element to have the given name.
-   *
-   * [name] the name of this element
-   * [nameOffset] the offset of the name of this element in the file that
-   *    contains the declaration of this element
-   */
-  FunctionTypeAliasElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created type alias element to have the given [name].
-   */
-  FunctionTypeAliasElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  CompilationUnitElement get enclosingElement =>
-      super.enclosingElement as CompilationUnitElement;
-
-  @override
-  ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this type alias to the given [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    if (parameters != null) {
-      for (ParameterElement parameter in parameters) {
-        (parameter as ParameterElementImpl).enclosingElement = this;
-      }
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined for this type to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement typeParameter in typeParameters) {
-      (typeParameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitFunctionTypeAliasElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("typedef ");
-    buffer.write(displayName);
-    int typeParameterCount = _typeParameters.length;
-    if (typeParameterCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < typeParameterCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (_typeParameters[i] as TypeParameterElementImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-    buffer.write("(");
-    int parameterCount = _parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      (_parameters[i] as ParameterElementImpl).appendTo(buffer);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    } else if (returnType != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(returnType);
-    }
-  }
-
-  @override
-  FunctionTypeAlias computeNode() =>
-      getNodeMatching((node) => node is FunctionTypeAlias);
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (VariableElement parameter in _parameters) {
-      if ((parameter as VariableElementImpl).identifier == identifier) {
-        return parameter as VariableElementImpl;
-      }
-    }
-    for (TypeParameterElement typeParameter in _typeParameters) {
-      if ((typeParameter as TypeParameterElementImpl).identifier ==
-          identifier) {
-        return typeParameter as TypeParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_parameters, visitor);
-    safelyVisitChildren(_typeParameters, visitor);
-  }
-}
-
-/**
- * An element that has a [FunctionType] as its [type].
- *
- * This also provides convenient access to the parameters and return type.
- */
-abstract class FunctionTypedElement implements TypeParameterizedElement {
-  /**
-   * Return a list containing all of the parameters defined by this executable
-   * element.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the return type defined by this element. If the element model is
-   * fully populated, then the [returnType] will not be `null`, even
-   * if no return type was explicitly specified.
-   */
-  DartType get returnType;
-
-  /**
-   * Return the type of function defined by this element.
-   */
-  FunctionType get type;
-}
-
-/**
- * The type of a function, method, constructor, getter, or setter.
- */
-class FunctionTypeImpl extends TypeImpl implements FunctionType {
-  /**
-   * The list of [typeArguments].
-   */
-  List<DartType> _typeArguments;
-
-  /**
-   * The list of [typeParameters].
-   */
-  List<TypeParameterElement> _typeParameters;
-
-  /**
-   * The list of [boundTypeParameters].
-   */
-  List<TypeParameterElement> _boundTypeParameters;
-
-  /**
-   * The set of typedefs which should not be expanded when exploring this type,
-   * to avoid creating infinite types in response to self-referential typedefs.
-   */
-  final List<FunctionTypeAliasElement> prunedTypedefs;
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element], and also initialize [typeArguments] to match the
-   * [typeParameters], which permits later substitution.
-   */
-  FunctionTypeImpl(ExecutableElement element,
-      [List<FunctionTypeAliasElement> prunedTypedefs])
-      : this._(element, null, prunedTypedefs, null, null, null);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
-      [List<FunctionTypeAliasElement> prunedTypedefs])
-      : this._(element, element?.name, prunedTypedefs, null, null, null);
-
-  /**
-   * Private constructor.
-   */
-  FunctionTypeImpl._(
-      TypeParameterizedElement element,
-      String name,
-      this.prunedTypedefs,
-      List<DartType> typeArguments,
-      List<TypeParameterElement> typeParameters,
-      List<TypeParameterElement> boundTypeParameters)
-      : super(element, name) {
-    _boundTypeParameters = boundTypeParameters ??
-        element?.typeParameters ??
-        TypeParameterElement.EMPTY_LIST;
-
-    if (typeParameters == null) {
-      // Combine the generic type variables from all enclosing contexts, except
-      // for this generic function's type variables. Those variables are
-      // tracked in [boundTypeParameters].
-      typeParameters = <TypeParameterElement>[];
-      Element e = element?.enclosingElement;
-      while (e != null) {
-        if (e is TypeParameterizedElement) {
-          typeParameters.addAll((e as TypeParameterizedElement).typeParameters);
-        }
-        e = e.enclosingElement;
-      }
-    }
-    _typeParameters = typeParameters;
-
-    if (typeArguments == null) {
-      // TODO(jmesserly): reuse TypeParameterTypeImpl.getTypes once we can
-      // make it generic, which will allow it to return List<DartType> instead
-      // of List<TypeParameterType>.
-      if (typeParameters.isEmpty) {
-        typeArguments = DartType.EMPTY_LIST;
-      } else {
-        typeArguments = new List<DartType>.from(
-            typeParameters.map((t) => t.type),
-            growable: false);
-      }
-    }
-    _typeArguments = typeArguments;
-  }
-
-  /**
-   * Return the base parameter elements of this function element.
-   */
-  List<ParameterElement> get baseParameters => element.parameters;
-
-  /**
-   * Return the return type defined by this function's element.
-   */
-  DartType get baseReturnType => element.returnType;
-
-  @override
-  List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters;
-
-  @override
-  String get displayName {
-    String name = this.name;
-    if (name == null || name.length == 0) {
-      // Function types have an empty name when they are defined implicitly by
-      // either a closure or as part of a parameter declaration.
-      List<DartType> normalParameterTypes = this.normalParameterTypes;
-      List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-      Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
-      DartType returnType = this.returnType;
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("(");
-      bool needsComma = false;
-      if (normalParameterTypes.length > 0) {
-        for (DartType type in normalParameterTypes) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(type.displayName);
-        }
-      }
-      if (optionalParameterTypes.length > 0) {
-        if (needsComma) {
-          buffer.write(", ");
-          needsComma = false;
-        }
-        buffer.write("[");
-        for (DartType type in optionalParameterTypes) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(type.displayName);
-        }
-        buffer.write("]");
-        needsComma = true;
-      }
-      if (namedParameterTypes.length > 0) {
-        if (needsComma) {
-          buffer.write(", ");
-          needsComma = false;
-        }
-        buffer.write("{");
-        namedParameterTypes.forEach((String name, DartType type) {
-          if (needsComma) {
-            buffer.write(", ");
-          } else {
-            needsComma = true;
-          }
-          buffer.write(name);
-          buffer.write(": ");
-          buffer.write(type.displayName);
-        });
-        buffer.write("}");
-        needsComma = true;
-      }
-      buffer.write(")");
-      buffer.write(Element.RIGHT_ARROW);
-      if (returnType == null) {
-        buffer.write("null");
-      } else {
-        buffer.write(returnType.displayName);
-      }
-      name = buffer.toString();
-    }
-    return name;
-  }
-
-  @override
-  FunctionTypedElement get element => super.element;
-
-  @override
-  int get hashCode {
-    if (element == null) {
-      return 0;
-    }
-    // Reference the arrays of parameters
-    List<DartType> normalParameterTypes = this.normalParameterTypes;
-    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-    Iterable<DartType> namedParameterTypes = this.namedParameterTypes.values;
-    // Generate the hashCode
-    int code = (returnType as TypeImpl).hashCode;
-    for (int i = 0; i < normalParameterTypes.length; i++) {
-      code = (code << 1) + (normalParameterTypes[i] as TypeImpl).hashCode;
-    }
-    for (int i = 0; i < optionalParameterTypes.length; i++) {
-      code = (code << 1) + (optionalParameterTypes[i] as TypeImpl).hashCode;
-    }
-    for (DartType type in namedParameterTypes) {
-      code = (code << 1) + (type as TypeImpl).hashCode;
-    }
-    return code;
-  }
-
-  /**
-   * The type arguments that were used to instantiate this function type, if
-   * any, otherwise this will return an empty list.
-   *
-   * Given a function type `f`:
-   *
-   *     f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
-   *
-   * Will always hold.
-   */
-  List<DartType> get instantiatedTypeArguments {
-    int typeParameterCount = element.type.boundTypeParameters.length;
-    if (typeParameterCount == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    // The substituted types at the end should be our bound type parameters.
-    int skipCount = typeArguments.length - typeParameterCount;
-    return new List<DartType>.from(typeArguments.skip(skipCount));
-  }
-
-  @override
-  Map<String, DartType> get namedParameterTypes {
-    LinkedHashMap<String, DartType> namedParameterTypes =
-        new LinkedHashMap<String, DartType>();
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return namedParameterTypes;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.NAMED) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        namedParameterTypes[parameter.name] = type;
-      }
-    }
-    return namedParameterTypes;
-  }
-
-  /**
-   * Determine the new set of typedefs which should be pruned when expanding
-   * this function type.
-   */
-  List<FunctionTypeAliasElement> get newPrune {
-    Element element = this.element;
-    if (element is FunctionTypeAliasElement && !element.isSynthetic) {
-      // This typedef should be pruned, along with anything that was previously
-      // pruned.
-      if (prunedTypedefs == null) {
-        return <FunctionTypeAliasElement>[element];
-      } else {
-        return new List<FunctionTypeAliasElement>.from(prunedTypedefs)
-          ..add(element);
-      }
-    } else {
-      // This is not a typedef, so nothing additional needs to be pruned.
-      return prunedTypedefs;
-    }
-  }
-
-  @override
-  List<DartType> get normalParameterTypes {
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    List<DartType> types = new List<DartType>();
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.REQUIRED) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        types.add(type);
-      }
-    }
-    return types;
-  }
-
-  @override
-  List<DartType> get optionalParameterTypes {
-    List<ParameterElement> parameters = baseParameters;
-    if (parameters.length == 0) {
-      return DartType.EMPTY_LIST;
-    }
-    List<DartType> typeParameters =
-        TypeParameterTypeImpl.getTypes(this.typeParameters);
-    List<DartType> types = new List<DartType>();
-    for (ParameterElement parameter in parameters) {
-      if (parameter.parameterKind == ParameterKind.POSITIONAL) {
-        DartType type = parameter.type;
-        if (typeArguments.length != 0 &&
-            typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl)
-              .substitute2(typeArguments, typeParameters, newPrune);
-        } else {
-          type = (type as TypeImpl).pruned(newPrune);
-        }
-        types.add(type);
-      }
-    }
-    return types;
-  }
-
-  /**
-   * If this is an instantiation of a generic function type, this will get
-   * the original function from which it was instantiated.
-   *
-   * Otherwise, this will return `this`.
-   */
-  FunctionTypeImpl get originalFunction {
-    if (element.type.boundTypeParameters.isEmpty) {
-      return this;
-    }
-    return (element.type as FunctionTypeImpl).substitute2(typeArguments,
-        TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
-  }
-
-  @override
-  List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = this.baseParameters;
-    // no parameters, quick return
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
-    }
-    // create specialized parameters
-    List<ParameterElement> specializedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
-    }
-    return specializedParameters;
-  }
-
-  @override
-  DartType get returnType {
-    DartType baseReturnType = this.baseReturnType;
-    if (baseReturnType == null) {
-      // TODO(brianwilkerson) This is a patch. The return type should never be
-      // null and we need to understand why it is and fix it.
-      return DynamicTypeImpl.instance;
-    }
-    // If there are no arguments to substitute, or if the arguments size doesn't
-    // match the parameter size, return the base return type.
-    if (typeArguments.length == 0 ||
-        typeArguments.length != typeParameters.length) {
-      return (baseReturnType as TypeImpl).pruned(newPrune);
-    }
-    return (baseReturnType as TypeImpl).substitute2(typeArguments,
-        TypeParameterTypeImpl.getTypes(typeParameters), newPrune);
-  }
-
-  /**
-   * A list containing the actual types of the type arguments.
-   */
-  List<DartType> get typeArguments => _typeArguments;
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  @override
-  bool operator ==(Object object) {
-    if (object is! FunctionTypeImpl) {
-      return false;
-    }
-    FunctionTypeImpl otherType = object as FunctionTypeImpl;
-    if (boundTypeParameters.length != otherType.boundTypeParameters.length) {
-      return false;
-    }
-    // `<T>T -> T` should be equal to `<U>U -> U`
-    // To test this, we instantiate both types with the same (unique) type
-    // variables, and see if the result is equal.
-    if (boundTypeParameters.isNotEmpty) {
-      List<DartType> instantiateTypeArgs = new List<DartType>();
-      List<DartType> variablesThis = new List<DartType>();
-      List<DartType> variablesOther = new List<DartType>();
-      for (int i = 0; i < boundTypeParameters.length; i++) {
-        TypeParameterElement pThis = boundTypeParameters[i];
-        TypeParameterElement pOther = otherType.boundTypeParameters[i];
-        TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
-            new TypeParameterElementImpl(pThis.name, -1));
-        instantiateTypeArgs.add(pFresh);
-        variablesThis.add(pThis.type);
-        variablesOther.add(pOther.type);
-        // Check that the bounds are equal after equating the previous
-        // bound variables.
-        if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
-            pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
-          return false;
-        }
-      }
-      // After instantiation, they will no longer have boundTypeParameters,
-      // so we will continue below.
-      return this.instantiate(instantiateTypeArgs) ==
-          otherType.instantiate(instantiateTypeArgs);
-    }
-
-    return returnType == otherType.returnType &&
-        TypeImpl.equalArrays(
-            normalParameterTypes, otherType.normalParameterTypes) &&
-        TypeImpl.equalArrays(
-            optionalParameterTypes, otherType.optionalParameterTypes) &&
-        _equals(namedParameterTypes, otherType.namedParameterTypes);
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (boundTypeParameters.isNotEmpty) {
-      // To print a type with type variables, first make sure we have unique
-      // variable names to print.
-      Set<TypeParameterType> freeVariables = new HashSet<TypeParameterType>();
-      _freeVariablesInFunctionType(this, freeVariables);
-
-      Set<String> namesToAvoid = new HashSet<String>();
-      for (DartType arg in freeVariables) {
-        if (arg is TypeParameterType) {
-          namesToAvoid.add(arg.displayName);
-        }
-      }
-
-      List<DartType> instantiateTypeArgs = new List<DartType>();
-      List<DartType> variables = new List<DartType>();
-      buffer.write("<");
-      for (TypeParameterElement e in boundTypeParameters) {
-        if (e != boundTypeParameters[0]) {
-          buffer.write(",");
-        }
-        String name = e.name;
-        int counter = 0;
-        while (!namesToAvoid.add(name)) {
-          // Unicode subscript-zero is U+2080, zero is U+0030. Other digits
-          // are sequential from there. Thus +0x2050 will get us the subscript.
-          String subscript = new String.fromCharCodes(
-              counter.toString().codeUnits.map((n) => n + 0x2050));
-
-          name = e.name + subscript;
-          counter++;
-        }
-        TypeParameterTypeImpl t =
-            new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
-        t.appendTo(buffer);
-        instantiateTypeArgs.add(t);
-        variables.add(e.type);
-        if (e.bound != null) {
-          buffer.write(" extends ");
-          TypeImpl renamed =
-              e.bound.substitute2(instantiateTypeArgs, variables);
-          renamed.appendTo(buffer);
-        }
-      }
-      buffer.write(">");
-
-      // Instantiate it and print the resulting type. After instantiation, it
-      // will no longer have boundTypeParameters, so we will continue below.
-      this.instantiate(instantiateTypeArgs).appendTo(buffer);
-      return;
-    }
-
-    List<DartType> normalParameterTypes = this.normalParameterTypes;
-    List<DartType> optionalParameterTypes = this.optionalParameterTypes;
-    Map<String, DartType> namedParameterTypes = this.namedParameterTypes;
-    DartType returnType = this.returnType;
-    buffer.write("(");
-    bool needsComma = false;
-    if (normalParameterTypes.isNotEmpty) {
-      for (DartType type in normalParameterTypes) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        (type as TypeImpl).appendTo(buffer);
-      }
-    }
-    if (optionalParameterTypes.isNotEmpty) {
-      if (needsComma) {
-        buffer.write(", ");
-        needsComma = false;
-      }
-      buffer.write("[");
-      for (DartType type in optionalParameterTypes) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        (type as TypeImpl).appendTo(buffer);
-      }
-      buffer.write("]");
-      needsComma = true;
-    }
-    if (namedParameterTypes.isNotEmpty) {
-      if (needsComma) {
-        buffer.write(", ");
-        needsComma = false;
-      }
-      buffer.write("{");
-      namedParameterTypes.forEach((String name, DartType type) {
-        if (needsComma) {
-          buffer.write(", ");
-        } else {
-          needsComma = true;
-        }
-        buffer.write(name);
-        buffer.write(": ");
-        (type as TypeImpl).appendTo(buffer);
-      });
-      buffer.write("}");
-      needsComma = true;
-    }
-    buffer.write(")");
-    buffer.write(Element.RIGHT_ARROW);
-    if (returnType == null) {
-      buffer.write("null");
-    } else {
-      (returnType as TypeImpl).appendTo(buffer);
-    }
-  }
-
-  @override
-  FunctionTypeImpl instantiate(List<DartType> argumentTypes) {
-    if (argumentTypes.length != boundTypeParameters.length) {
-      throw new IllegalArgumentException(
-          "argumentTypes.length (${argumentTypes.length}) != "
-          "boundTypeParameters.length (${boundTypeParameters.length})");
-    }
-    if (argumentTypes.isEmpty) {
-      return this;
-    }
-
-    // Given:
-    //     {U/T} <S> T -> S
-    // Where {U/T} represents the typeArguments (U) and typeParameters (T) list,
-    // and <S> represents the boundTypeParameters.
-    //
-    // Now instantiate([V]), and the result should be:
-    //     {U/T, V/S} T -> S.
-    List<TypeParameterElement> newTypeParams = typeParameters.toList();
-    List<DartType> newTypeArgs = typeArguments.toList();
-    newTypeParams.addAll(boundTypeParameters);
-    newTypeArgs.addAll(argumentTypes);
-
-    return new FunctionTypeImpl._(element, name, prunedTypedefs, newTypeArgs,
-        newTypeParams, TypeParameterElement.EMPTY_LIST);
-  }
-
-  @override
-  bool isAssignableTo(DartType type) {
-    // A function type T may be assigned to a function type S, written T <=> S,
-    // iff T <: S.
-    return isSubtypeOf(type);
-  }
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // Note: visitedElements is only used for breaking recursion in the type
-    // hierarchy; we don't use it when recursing into the function type.
-
-    // trivial base cases
-    if (type == null) {
-      return false;
-    } else if (identical(this, type) ||
-        type.isDynamic ||
-        type.isDartCoreFunction ||
-        type.isObject) {
-      return true;
-    } else if (type is! FunctionType) {
-      return false;
-    } else if (this == type) {
-      return true;
-    }
-    FunctionType t = this;
-    FunctionType s = type as FunctionType;
-    List<DartType> tTypes = t.normalParameterTypes;
-    List<DartType> tOpTypes = t.optionalParameterTypes;
-    List<DartType> sTypes = s.normalParameterTypes;
-    List<DartType> sOpTypes = s.optionalParameterTypes;
-    // If one function has positional and the other has named parameters,
-    // return false.
-    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
-        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
-      return false;
-    }
-    // named parameters case
-    if (t.namedParameterTypes.length > 0) {
-      // check that the number of required parameters are equal, and check that
-      // every t_i is more specific than every s_i
-      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
-        return false;
-      } else if (t.normalParameterTypes.length > 0) {
-        for (int i = 0; i < tTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      }
-      Map<String, DartType> namedTypesT = t.namedParameterTypes;
-      Map<String, DartType> namedTypesS = s.namedParameterTypes;
-      // if k >= m is false, return false: the passed function type has more
-      // named parameter types than this
-      if (namedTypesT.length < namedTypesS.length) {
-        return false;
-      }
-      // Loop through each element in S verifying that T has a matching
-      // parameter name and that the corresponding type is more specific then
-      // the type in S.
-      for (String keyS in namedTypesS.keys) {
-        DartType typeT = namedTypesT[keyS];
-        if (typeT == null) {
-          return false;
-        }
-        if (!(typeT as TypeImpl)
-            .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
-          return false;
-        }
-      }
-    } else if (s.namedParameterTypes.length > 0) {
-      return false;
-    } else {
-      // positional parameter case
-      int tArgLength = tTypes.length + tOpTypes.length;
-      int sArgLength = sTypes.length + sOpTypes.length;
-      // Check that the total number of parameters in t is greater than or equal
-      // to the number of parameters in s and that the number of required
-      // parameters in s is greater than or equal to the number of required
-      // parameters in t.
-      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
-        return false;
-      }
-      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
-        // No positional arguments, don't copy contents to new array
-        for (int i = 0; i < sTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      } else {
-        // Else, we do have positional parameters, copy required and positional
-        // parameter types into arrays to do the compare (for loop below).
-        List<DartType> tAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < tTypes.length; i++) {
-          tAllTypes[i] = tTypes[i];
-        }
-        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
-          tAllTypes[i] = tOpTypes[j];
-        }
-        List<DartType> sAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < sTypes.length; i++) {
-          sAllTypes[i] = sTypes[i];
-        }
-        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
-          sAllTypes[i] = sOpTypes[j];
-        }
-        for (int i = 0; i < sAllTypes.length; i++) {
-          if (!(tAllTypes[i] as TypeImpl)
-              .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
-            return false;
-          }
-        }
-      }
-    }
-    DartType tRetType = t.returnType;
-    DartType sRetType = s.returnType;
-    return sRetType.isVoid ||
-        (tRetType as TypeImpl).isMoreSpecificThan(sRetType, withDynamic);
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) {
-    // trivial base cases
-    if (type == null) {
-      return false;
-    } else if (identical(this, type) ||
-        type.isDynamic ||
-        type.isDartCoreFunction ||
-        type.isObject) {
-      return true;
-    } else if (type is! FunctionType) {
-      return false;
-    } else if (this == type) {
-      return true;
-    }
-    FunctionType t = this;
-    FunctionType s = type as FunctionType;
-    List<DartType> tTypes = t.normalParameterTypes;
-    List<DartType> tOpTypes = t.optionalParameterTypes;
-    List<DartType> sTypes = s.normalParameterTypes;
-    List<DartType> sOpTypes = s.optionalParameterTypes;
-    // If one function has positional and the other has named parameters,
-    // return false.
-    if ((sOpTypes.length > 0 && t.namedParameterTypes.length > 0) ||
-        (tOpTypes.length > 0 && s.namedParameterTypes.length > 0)) {
-      return false;
-    }
-    // named parameters case
-    if (t.namedParameterTypes.length > 0) {
-      // check that the number of required parameters are equal,
-      // and check that every t_i is assignable to every s_i
-      if (t.normalParameterTypes.length != s.normalParameterTypes.length) {
-        return false;
-      } else if (t.normalParameterTypes.length > 0) {
-        for (int i = 0; i < tTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
-            return false;
-          }
-        }
-      }
-      Map<String, DartType> namedTypesT = t.namedParameterTypes;
-      Map<String, DartType> namedTypesS = s.namedParameterTypes;
-      // if k >= m is false, return false: the passed function type has more
-      // named parameter types than this
-      if (namedTypesT.length < namedTypesS.length) {
-        return false;
-      }
-      // Loop through each element in S verifying that T has a matching
-      // parameter name and that the corresponding type is assignable to the
-      // type in S.
-      for (String keyS in namedTypesS.keys) {
-        DartType typeT = namedTypesT[keyS];
-        if (typeT == null) {
-          return false;
-        }
-        if (!(typeT as TypeImpl).isAssignableTo(namedTypesS[keyS])) {
-          return false;
-        }
-      }
-    } else if (s.namedParameterTypes.length > 0) {
-      return false;
-    } else {
-      // positional parameter case
-      int tArgLength = tTypes.length + tOpTypes.length;
-      int sArgLength = sTypes.length + sOpTypes.length;
-      // Check that the total number of parameters in t is greater than or
-      // equal to the number of parameters in s and that the number of
-      // required parameters in s is greater than or equal to the number of
-      // required parameters in t.
-      if (tArgLength < sArgLength || sTypes.length < tTypes.length) {
-        return false;
-      }
-      if (tOpTypes.length == 0 && sOpTypes.length == 0) {
-        // No positional arguments, don't copy contents to new array
-        for (int i = 0; i < sTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isAssignableTo(sTypes[i])) {
-            return false;
-          }
-        }
-      } else {
-        // Else, we do have positional parameters, copy required and
-        // positional parameter types into arrays to do the compare (for loop
-        // below).
-        List<DartType> tAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < tTypes.length; i++) {
-          tAllTypes[i] = tTypes[i];
-        }
-        for (int i = tTypes.length, j = 0; i < sArgLength; i++, j++) {
-          tAllTypes[i] = tOpTypes[j];
-        }
-        List<DartType> sAllTypes = new List<DartType>(sArgLength);
-        for (int i = 0; i < sTypes.length; i++) {
-          sAllTypes[i] = sTypes[i];
-        }
-        for (int i = sTypes.length, j = 0; i < sArgLength; i++, j++) {
-          sAllTypes[i] = sOpTypes[j];
-        }
-        for (int i = 0; i < sAllTypes.length; i++) {
-          if (!(tAllTypes[i] as TypeImpl).isAssignableTo(sAllTypes[i])) {
-            return false;
-          }
-        }
-      }
-    }
-    DartType tRetType = t.returnType;
-    DartType sRetType = s.returnType;
-    return sRetType.isVoid || (tRetType as TypeImpl).isAssignableTo(sRetType);
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) {
-    if (prune == null) {
-      return this;
-    } else if (prune.contains(element)) {
-      // Circularity found.  Prune the type declaration.
-      return new CircularTypeImpl();
-    } else {
-      // There should never be a reason to prune a type that has already been
-      // pruned, since pruning is only done when expanding a function type
-      // alias, and function type aliases are always expanded by starting with
-      // base types.
-      assert(this.prunedTypedefs == null);
-      List<DartType> typeArgs = typeArguments
-          .map((TypeImpl t) => t.pruned(prune))
-          .toList(growable: false);
-      return new FunctionTypeImpl._(element, name, prune, typeArgs,
-          _typeParameters, _boundTypeParameters);
-    }
-  }
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    // Pruned types should only ever result from performing type variable
-    // substitution, and it doesn't make sense to substitute again after
-    // substituting once.
-    assert(this.prunedTypedefs == null);
-    if (argumentTypes.length != parameterTypes.length) {
-      throw new IllegalArgumentException(
-          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
-    }
-    Element element = this.element;
-    if (prune != null && prune.contains(element)) {
-      // Circularity found.  Prune the type declaration.
-      return new CircularTypeImpl();
-    }
-    if (argumentTypes.length == 0) {
-      return this.pruned(prune);
-    }
-    List<DartType> typeArgs =
-        TypeImpl.substitute(typeArguments, argumentTypes, parameterTypes);
-    return new FunctionTypeImpl._(
-        element, name, prune, typeArgs, _typeParameters, _boundTypeParameters);
-  }
-
-  @override
-  FunctionTypeImpl substitute3(List<DartType> argumentTypes) =>
-      substitute2(argumentTypes, typeArguments);
-
-  void _freeVariablesInFunctionType(
-      FunctionType type, Set<TypeParameterType> free) {
-    // Make some fresh variables to avoid capture.
-    List<DartType> typeArgs = DartType.EMPTY_LIST;
-    if (type.boundTypeParameters.isNotEmpty) {
-      typeArgs = new List<DartType>.from(type.boundTypeParameters.map((e) =>
-          new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
-
-      type = type.instantiate(typeArgs);
-    }
-
-    for (ParameterElement p in type.parameters) {
-      _freeVariablesInType(p.type, free);
-    }
-    _freeVariablesInType(type.returnType, free);
-
-    // Remove all of our bound variables.
-    free.removeAll(typeArgs);
-  }
-
-  void _freeVariablesInInterfaceType(
-      InterfaceType type, Set<TypeParameterType> free) {
-    for (DartType typeArg in type.typeArguments) {
-      _freeVariablesInType(typeArg, free);
-    }
-  }
-
-  void _freeVariablesInType(DartType type, Set<TypeParameterType> free) {
-    if (type is TypeParameterType) {
-      free.add(type);
-    } else if (type is FunctionType) {
-      _freeVariablesInFunctionType(type, free);
-    } else if (type is InterfaceType) {
-      _freeVariablesInInterfaceType(type, free);
-    }
-  }
-
-  /**
-   * 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
-   * same order in which those entries were added to the map.
-   */
-  static bool _equals(
-      Map<String, DartType> firstTypes, Map<String, DartType> secondTypes) {
-    if (secondTypes.length != firstTypes.length) {
-      return false;
-    }
-    Iterator<String> firstKeys = firstTypes.keys.iterator;
-    Iterator<String> secondKeys = secondTypes.keys.iterator;
-    while (firstKeys.moveNext() && secondKeys.moveNext()) {
-      String firstKey = firstKeys.current;
-      String secondKey = secondKeys.current;
-      TypeImpl firstType = firstTypes[firstKey];
-      TypeImpl secondType = secondTypes[secondKey];
-      if (firstKey != secondKey || firstType != secondType) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
-
-/**
- * An element visitor that will recursively visit all of the elements in an
- * element model (like instances of the class [RecursiveElementVisitor]). In
- * addition, when an element of a specific type is visited not only will the
- * visit method for that specific type of element be invoked, but additional
- * methods for the supertypes of that element will also be invoked. For example,
- * using an instance of this class to visit a [MethodElement] will cause the
- * method [visitMethodElement] to be invoked but will also cause the methods
- * [visitExecutableElement] and [visitElement] to be subsequently invoked. This
- * allows visitors to be written that visit all executable elements without
- * needing to override the visit method for each of the specific subclasses of
- * [ExecutableElement].
- *
- * Note, however, that unlike many visitors, element visitors visit objects
- * based on the interfaces implemented by those elements. Because interfaces
- * form a graph structure rather than a tree structure the way classes do, and
- * because it is generally undesirable for an object to be visited more than
- * once, this class flattens the interface graph into a pseudo-tree. In
- * particular, this class treats elements as if the element types were
- * structured in the following way:
- *
- * <pre>
- * Element
- *   ClassElement
- *   CompilationUnitElement
- *   ExecutableElement
- *       ConstructorElement
- *       LocalElement
- *           FunctionElement
- *       MethodElement
- *       PropertyAccessorElement
- *   ExportElement
- *   HtmlElement
- *   ImportElement
- *   LabelElement
- *   LibraryElement
- *   MultiplyDefinedElement
- *   PrefixElement
- *   TypeAliasElement
- *   TypeParameterElement
- *   UndefinedElement
- *   VariableElement
- *       PropertyInducingElement
- *           FieldElement
- *           TopLevelVariableElement
- *       LocalElement
- *           LocalVariableElement
- *           ParameterElement
- *               FieldFormalParameterElement
- * </pre>
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or explicitly invoke the more general visit method. Failure to
- * do so will cause the visit methods for superclasses of the element to not be
- * invoked and will cause the children of the visited node to not be visited.
- */
-class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) => visitElement(element);
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) =>
-      visitElement(element);
-
-  @override
-  R visitConstructorElement(ConstructorElement element) =>
-      visitExecutableElement(element);
-
-  R visitElement(Element element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  R visitExecutableElement(ExecutableElement element) => visitElement(element);
-
-  @override
-  R visitExportElement(ExportElement element) => visitElement(element);
-
-  @override
-  R visitFieldElement(FieldElement element) =>
-      visitPropertyInducingElement(element);
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
-      visitParameterElement(element);
-
-  @override
-  R visitFunctionElement(FunctionElement element) => visitLocalElement(element);
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
-      visitElement(element);
-
-  @override
-  R visitImportElement(ImportElement element) => visitElement(element);
-
-  @override
-  R visitLabelElement(LabelElement element) => visitElement(element);
-
-  @override
-  R visitLibraryElement(LibraryElement element) => visitElement(element);
-
-  R visitLocalElement(LocalElement element) {
-    if (element is LocalVariableElement) {
-      return visitVariableElement(element);
-    } else if (element is ParameterElement) {
-      return visitVariableElement(element);
-    } else if (element is FunctionElement) {
-      return visitExecutableElement(element);
-    }
-    return null;
-  }
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) =>
-      visitLocalElement(element);
-
-  @override
-  R visitMethodElement(MethodElement element) =>
-      visitExecutableElement(element);
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) =>
-      visitElement(element);
-
-  @override
-  R visitParameterElement(ParameterElement element) =>
-      visitLocalElement(element);
-
-  @override
-  R visitPrefixElement(PrefixElement element) => visitElement(element);
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) =>
-      visitExecutableElement(element);
-
-  R visitPropertyInducingElement(PropertyInducingElement element) =>
-      visitVariableElement(element);
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) =>
-      visitPropertyInducingElement(element);
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) =>
-      visitElement(element);
-
-  R visitVariableElement(VariableElement element) => visitElement(element);
-}
-
-/**
- * A combinator that causes some of the names in a namespace to be hidden when
- * being imported.
- */
-abstract class HideElementCombinator implements NamespaceCombinator {
-  /**
-   * Return a list containing the names that are not to be made visible in the
-   * importing library even if they are defined in the imported library.
-   */
-  List<String> get hiddenNames;
-}
-
-/**
- * A concrete implementation of a [HideElementCombinator].
- */
-class HideElementCombinatorImpl implements HideElementCombinator {
-  /**
-   * The names that are not to be made visible in the importing library even if
-   * they are defined in the imported library.
-   */
-  List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("show ");
-    int count = hiddenNames.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(hiddenNames[i]);
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * A single import directive within a library.
- */
-abstract class ImportElement implements Element, UriReferencedElement {
-  /**
-   * An empty list of import elements.
-   */
-  static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
-
-  /**
-   * Return a list containing the combinators that were specified as part of the
-   * import directive in the order in which they were specified.
-   */
-  List<NamespaceCombinator> get combinators;
-
-  /**
-   * Return the library that is imported into this library by this import
-   * directive.
-   */
-  LibraryElement get importedLibrary;
-
-  /**
-   * Return `true` if this import is for a deferred library.
-   */
-  bool get isDeferred;
-
-  /**
-   * Return the prefix that was specified as part of the import directive, or
-   * `null` if there was no prefix specified.
-   */
-  PrefixElement get prefix;
-
-  /**
-   * Return the offset of the prefix of this import in the file that contains
-   * this import directive, or `-1` if this import is synthetic, does not have a
-   * prefix, or otherwise does not have an offset.
-   */
-  int get prefixOffset;
-}
-
-/**
- * A concrete implementation of an [ImportElement].
- */
-class ImportElementImpl extends UriReferencedElementImpl
-    implements ImportElement {
-  /**
-   * The offset of the prefix of this import in the file that contains the this
-   * import directive, or `-1` if this import is synthetic.
-   */
-  int prefixOffset = 0;
-
-  /**
-   * The library that is imported into this library by this import directive.
-   */
-  LibraryElement importedLibrary;
-
-  /**
-   * The combinators that were specified as part of the import directive in the
-   * order in which they were specified.
-   */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
-
-  /**
-   * The prefix that was specified as part of the import directive, or `null` if
-   * there was no prefix specified.
-   */
-  PrefixElement prefix;
-
-  /**
-   * Initialize a newly created import element at the given [offset].
-   * The offset may be `-1` if the import is synthetic.
-   */
-  ImportElementImpl(int offset) : super(null, offset);
-
-  /**
-   * Set whether this import is for a deferred library.
-   */
-  void set deferred(bool isDeferred) {
-    setModifier(Modifier.DEFERRED, isDeferred);
-  }
-
-  @override
-  String get identifier =>
-      "${(importedLibrary as LibraryElementImpl).identifier}@$nameOffset";
-
-  @override
-  bool get isDeferred => hasModifier(Modifier.DEFERRED);
-
-  @override
-  ElementKind get kind => ElementKind.IMPORT;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitImportElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("import ");
-    (importedLibrary as LibraryElementImpl).appendTo(buffer);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(prefix, visitor);
-  }
-}
-
-/**
- * The type introduced by either a class or an interface, or a reference to such
- * a type.
- */
-abstract class InterfaceType implements ParameterizedType {
-  /**
-   * An empty list of types.
-   */
-  static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
-
-  /**
-   * Return a list containing all of the accessors (getters and setters)
-   * declared in this type.
-   */
-  List<PropertyAccessorElement> get accessors;
-
-  /**
-   * Return a list containing all of the constructors declared in this type.
-   */
-  List<ConstructorElement> get constructors;
-
-  @override
-  ClassElement get element;
-
-  /**
-   * Return a list containing all of the interfaces that are implemented by this
-   * interface. Note that this is <b>not</b>, in general, equivalent to getting
-   * the interfaces from this type's element because the types returned by this
-   * method will have had their type parameters replaced.
-   */
-  List<InterfaceType> get interfaces;
-
-  /**
-   * Return a list containing all of the methods declared in this type.
-   */
-  List<MethodElement> get methods;
-
-  /**
-   * Return a list containing all of the mixins that are applied to the class
-   * being extended in order to derive the superclass of this class. Note that
-   * this is <b>not</b>, in general, equivalent to getting the mixins from this
-   * type's element because the types returned by this method will have had
-   * their type parameters replaced.
-   */
-  List<InterfaceType> get mixins;
-
-  /**
-   * Return the type representing the superclass of this type, or null if this
-   * type represents the class 'Object'. Note that this is <b>not</b>, in
-   * general, equivalent to getting the superclass from this type's element
-   * because the type returned by this method will have had it's type parameters
-   * replaced.
-   */
-  InterfaceType get superclass;
-
-  /**
-   * Return the element representing the getter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a getter
-   * with the given name.
-   */
-  PropertyAccessorElement getGetter(String name);
-
-  /**
-   * Return the element representing the method with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a method
-   * with the given name.
-   */
-  MethodElement getMethod(String name);
-
-  /**
-   * Return the element representing the setter with the given [name] that is
-   * declared in this class, or `null` if this class does not declare a setter
-   * with the given name.
-   */
-  PropertyAccessorElement getSetter(String name);
-
-  /**
-   * Return `true` if this type is a direct supertype of the given [type]. The
-   * implicit interface of class <i>I</i> is a direct supertype of the implicit
-   * interface of class <i>J</i> iff:
-   *
-   * * <i>I</i> is Object, and <i>J</i> has no extends clause.
-   * * <i>I</i> is listed in the extends clause of <i>J</i>.
-   * * <i>I</i> is listed in the implements clause of <i>J</i>.
-   * * <i>I</i> is listed in the with clause of <i>J</i>.
-   * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
-   */
-  bool isDirectSupertypeOf(InterfaceType type);
-
-  /**
-   * Return `true` if this type is more specific than the given [type]. An
-   * interface type <i>T</i> is more specific than an interface type <i>S</i>,
-   * written <i>T &laquo; S</i>, if one of the following conditions is met:
-   *
-   * * Reflexivity: <i>T</i> is <i>S</i>.
-   * * <i>T</i> is bottom.
-   * * <i>S</i> is dynamic.
-   * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
-   * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
-   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
-   *   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
-   *   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
-   *   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
-   * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
-   */
-  @override
-  bool isMoreSpecificThan(DartType type);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type]. An interface
-   * type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
-   * <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
-   * more specific than <i>S</i>). If an interface type <i>I</i> includes a
-   * method named <i>call()</i>, and the type of <i>call()</i> is the function
-   * type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
-   */
-  @override
-  bool isSubtypeOf(DartType type);
-
-  /**
-   * Return the element representing the constructor that results from looking
-   * up the constructor with the given [name] in this class with respect to the
-   * given [library], or `null` if the look up fails. The behavior of this
-   * method is defined by the Dart Language Specification in section 12.11.1:
-   * <blockquote>
-   * If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be the
-   * constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>.
-   * Otherwise, if <i>q</i> is not defined or not accessible, a
-   * NoSuchMethodException is thrown.
-   * </blockquote>
-   */
-  ConstructorElement lookUpConstructor(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * getter with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetter(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the
-   * getter with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 12.15.1:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpGetterInSuperclass(
-      String name, LibraryElement library);
-
-  /**
-   * Look up the member with the given [name] in this type and all extended
-   * and mixed in classes, and by default including [thisType]. If the search
-   * fails, this will then search interfaces.
-   *
-   * Return the element representing the member that was found, or `null` if
-   * there is no getter with the given name.
-   *
-   * The [library] determines if a private member name is visible, and does not
-   * need to be supplied for public names.
-   */
-  PropertyAccessorElement lookUpInheritedGetter(String name,
-      {LibraryElement library, bool thisType: true});
-
-  /**
-   * Look up the member with the given [name] in this type and all extended
-   * and mixed in classes, starting from this type. If the search fails,
-   * search interfaces.
-   *
-   * Return the element representing the member that was found, or `null` if
-   * there is no getter with the given name.
-   *
-   * The [library] determines if a private member name is visible, and does not
-   * need to be supplied for public names.
-   */
-  ExecutableElement lookUpInheritedGetterOrMethod(String name,
-      {LibraryElement library});
-
-  /**
-   * Look up the member with the given [name] in this type and all extended
-   * and mixed in classes, and by default including [thisType]. If the search
-   * fails, this will then search interfaces.
-   *
-   * Return the element representing the member that was found, or `null` if
-   * there is no getter with the given name.
-   *
-   * The [library] determines if a private member name is visible, and does not
-   * need to be supplied for public names.
-   */
-  MethodElement lookUpInheritedMethod(String name,
-      {LibraryElement library, bool thisType: true});
-
-  /**
-   * Look up the member with the given [name] in this type and all extended
-   * and mixed in classes, and by default including [thisType]. If the search
-   * fails, this will then search interfaces.
-   *
-   * Return the element representing the member that was found, or `null` if
-   * there is no getter with the given name.
-   *
-   * The [library] determines if a private member name is visible, and does not
-   * need to be supplied for public names.
-   */
-  PropertyAccessorElement lookUpInheritedSetter(String name,
-      {LibraryElement library, bool thisType: true});
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * method with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
-   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
-   *   <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
-   *   result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>
-   *   Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethod(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the method that results from looking up the
-   * method with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section
-   * 12.15.1:
-   * <blockquote>
-   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
-   * library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
-   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
-   * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
-   * result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  MethodElement lookUpMethodInSuperclass(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * setter with the given [name] in this class with respect to the given
-   * [library], or `null` if the look up fails. The behavior of this method is
-   * defined by the Dart Language Specification in section 12.16:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetter(String name, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the
-   * setter with the given [name] in the superclass of this class with respect
-   * to the given [library], or `null` if the look up fails. The behavior of
-   * this method is defined by the Dart Language Specification in section 12.16:
-   * <blockquote>
-   * The result of looking up getter (respectively setter) <i>m</i> in class
-   * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named
-   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
-   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
-   *   superclass <i>S</i>, then the result of the lookup is the result of
-   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
-   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   */
-  PropertyAccessorElement lookUpSetterInSuperclass(
-      String name, LibraryElement library);
-
-  @override
-  InterfaceType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-
-  // TODO(jmesserly): introduce a new "instantiate" and deprecate this.
-  // The new "instantiate" should work similar to FunctionType.instantiate,
-  // which uses [boundTypeParameters] to model type parameters that haven't been
-  // filled in yet. Those are kept separate from already-substituted type
-  // parameters or free variables from the enclosing scopes, which allows nested
-  // generics to work, such as a generic method in a generic class.
-  /**
-   * Return the type resulting from substituting the given arguments for this
-   * type's parameters. This is fully equivalent to `substitute2(argumentTypes,
-   * getTypeArguments())`.
-   */
-  InterfaceType substitute4(List<DartType> argumentTypes);
-
-  /**
-   * Returns a "smart" version of the "least upper bound" of the given types.
-   *
-   * If these types have the same element and differ only in terms of the type
-   * arguments, attempts to find a compatible set of type arguments.
-   *
-   * Otherwise, calls [DartType.getLeastUpperBound].
-   */
-  static InterfaceType getSmartLeastUpperBound(
-      InterfaceType first, InterfaceType second) {
-    // TODO(paulberry): this needs to be deprecated and replaced with a method
-    // in [TypeSystem], since it relies on the deprecated functionality of
-    // [DartType.getLeastUpperBound].
-    if (first.element == second.element) {
-      return _leastUpperBound(first, second);
-    }
-    AnalysisContext context = first.element.context;
-    return context.typeSystem
-        .getLeastUpperBound(context.typeProvider, first, second);
-  }
-
-  /**
-   * Return the "least upper bound" of the given types under the assumption that
-   * the types have the same element and differ only in terms of the type
-   * arguments.
-   *
-   * The resulting type is composed by comparing the corresponding type
-   * arguments, keeping those that are the same, and using 'dynamic' for those
-   * that are different.
-   */
-  static InterfaceType _leastUpperBound(
-      InterfaceType firstType, InterfaceType secondType) {
-    ClassElement firstElement = firstType.element;
-    ClassElement secondElement = secondType.element;
-    if (firstElement != secondElement) {
-      throw new IllegalArgumentException('The same elements expected, but '
-          '$firstElement and $secondElement are given.');
-    }
-    if (firstType == secondType) {
-      return firstType;
-    }
-    List<DartType> firstArguments = firstType.typeArguments;
-    List<DartType> secondArguments = secondType.typeArguments;
-    int argumentCount = firstArguments.length;
-    if (argumentCount == 0) {
-      return firstType;
-    }
-    List<DartType> lubArguments = new List<DartType>(argumentCount);
-    for (int i = 0; i < argumentCount; i++) {
-      //
-      // Ideally we would take the least upper bound of the two argument types,
-      // but this can cause an infinite recursion (such as when finding the
-      // least upper bound of String and num).
-      //
-      if (firstArguments[i] == secondArguments[i]) {
-        lubArguments[i] = firstArguments[i];
-      }
-      if (lubArguments[i] == null) {
-        lubArguments[i] = DynamicTypeImpl.instance;
-      }
-    }
-    InterfaceTypeImpl lub = new InterfaceTypeImpl(firstElement);
-    lub.typeArguments = lubArguments;
-    return lub;
-  }
-}
-
-/**
- * A concrete implementation of an [InterfaceType].
- */
-class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
-  /**
-   * A list containing the actual types of the type arguments.
-   */
-  List<DartType> typeArguments = DartType.EMPTY_LIST;
-
-  /**
-   * The set of typedefs which should not be expanded when exploring this type,
-   * to avoid creating infinite types in response to self-referential typedefs.
-   */
-  final List<FunctionTypeAliasElement> prunedTypedefs;
-
-  /**
-   * Initialize a newly created type to be declared by the given [element].
-   */
-  InterfaceTypeImpl(ClassElement element, [this.prunedTypedefs])
-      : super(element, element.displayName);
-
-  /**
-   * Initialize a newly created type to have the given [name]. This constructor
-   * should only be used in cases where there is no declaration of the type.
-   */
-  InterfaceTypeImpl.named(String name)
-      : prunedTypedefs = null,
-        super(null, name);
-
-  /**
-   * Private constructor.
-   */
-  InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
-      : super(element, name);
-
-  @override
-  List<PropertyAccessorElement> get accessors {
-    List<PropertyAccessorElement> accessors = element.accessors;
-    List<PropertyAccessorElement> members =
-        new List<PropertyAccessorElement>(accessors.length);
-    for (int i = 0; i < accessors.length; i++) {
-      members[i] = PropertyAccessorMember.from(accessors[i], this);
-    }
-    return members;
-  }
-
-  @override
-  List<ConstructorElement> get constructors {
-    List<ConstructorElement> constructors = element.constructors;
-    List<ConstructorElement> members =
-        new List<ConstructorElement>(constructors.length);
-    for (int i = 0; i < constructors.length; i++) {
-      members[i] = ConstructorMember.from(constructors[i], this);
-    }
-    return members;
-  }
-
-  @override
-  String get displayName {
-    String name = this.name;
-    List<DartType> typeArguments = this.typeArguments;
-    bool allDynamic = true;
-    for (DartType type in typeArguments) {
-      if (type != null && !type.isDynamic) {
-        allDynamic = false;
-        break;
-      }
-    }
-    // If there is at least one non-dynamic type, then list them out
-    if (!allDynamic) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write(name);
-      buffer.write("<");
-      for (int i = 0; i < typeArguments.length; i++) {
-        if (i != 0) {
-          buffer.write(", ");
-        }
-        DartType typeArg = typeArguments[i];
-        buffer.write(typeArg.displayName);
-      }
-      buffer.write(">");
-      name = buffer.toString();
-    }
-    return name;
-  }
-
-  @override
-  ClassElement get element => super.element as ClassElement;
-
-  @override
-  int get hashCode {
-    ClassElement element = this.element;
-    if (element == null) {
-      return 0;
-    }
-    return element.hashCode;
-  }
-
-  @override
-  List<InterfaceType> get interfaces {
-    ClassElement classElement = element;
-    List<InterfaceType> interfaces = classElement.interfaces;
-    List<TypeParameterElement> typeParameters = classElement.typeParameters;
-    List<DartType> parameterTypes = classElement.type.typeArguments;
-    if (typeParameters.length == 0) {
-      return interfaces;
-    }
-    int count = interfaces.length;
-    List<InterfaceType> typedInterfaces = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      typedInterfaces[i] =
-          interfaces[i].substitute2(typeArguments, parameterTypes);
-    }
-    return typedInterfaces;
-  }
-
-  @override
-  bool get isDartCoreFunction {
-    ClassElement element = this.element;
-    if (element == null) {
-      return false;
-    }
-    return element.name == "Function" && element.library.isDartCore;
-  }
-
-  @override
-  bool get isObject => element.supertype == null;
-
-  @override
-  List<MethodElement> get methods {
-    List<MethodElement> methods = element.methods;
-    List<MethodElement> members = new List<MethodElement>(methods.length);
-    for (int i = 0; i < methods.length; i++) {
-      members[i] = MethodMember.from(methods[i], this);
-    }
-    return members;
-  }
-
-  @override
-  List<InterfaceType> get mixins {
-    ClassElement classElement = element;
-    List<InterfaceType> mixins = classElement.mixins;
-    List<TypeParameterElement> typeParameters = classElement.typeParameters;
-    List<DartType> parameterTypes = classElement.type.typeArguments;
-    if (typeParameters.length == 0) {
-      return mixins;
-    }
-    int count = mixins.length;
-    List<InterfaceType> typedMixins = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      typedMixins[i] = mixins[i].substitute2(typeArguments, parameterTypes);
-    }
-    return typedMixins;
-  }
-
-  @override
-  InterfaceType get superclass {
-    ClassElement classElement = element;
-    InterfaceType supertype = classElement.supertype;
-    if (supertype == null) {
-      return null;
-    }
-    List<DartType> typeParameters = classElement.type.typeArguments;
-    if (typeArguments.length == 0 ||
-        typeArguments.length != typeParameters.length) {
-      return supertype;
-    }
-    return supertype.substitute2(typeArguments, typeParameters);
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => element.typeParameters;
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(object, this)) {
-      return true;
-    }
-    if (object is! InterfaceTypeImpl) {
-      return false;
-    }
-    InterfaceTypeImpl otherType = object as InterfaceTypeImpl;
-    return (element == otherType.element) &&
-        TypeImpl.equalArrays(typeArguments, otherType.typeArguments);
-  }
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(name);
-    int argumentCount = typeArguments.length;
-    if (argumentCount > 0) {
-      buffer.write("<");
-      for (int i = 0; i < argumentCount; i++) {
-        if (i > 0) {
-          buffer.write(", ");
-        }
-        (typeArguments[i] as TypeImpl).appendTo(buffer);
-      }
-      buffer.write(">");
-    }
-  }
-
-  @override
-  PropertyAccessorElement getGetter(String getterName) => PropertyAccessorMember
-      .from((element as ClassElementImpl).getGetter(getterName), this);
-
-  @override
-  MethodElement getMethod(String methodName) => MethodMember.from(
-      (element as ClassElementImpl).getMethod(methodName), this);
-
-  @override
-  PropertyAccessorElement getSetter(String setterName) => PropertyAccessorMember
-      .from((element as ClassElementImpl).getSetter(setterName), this);
-
-  @override
-  bool isDirectSupertypeOf(InterfaceType type) {
-    InterfaceType i = this;
-    InterfaceType j = type;
-    ClassElement jElement = j.element;
-    InterfaceType supertype = jElement.supertype;
-    //
-    // If J has no direct supertype then it is Object, and Object has no direct
-    // supertypes.
-    //
-    if (supertype == null) {
-      return false;
-    }
-    //
-    // I is listed in the extends clause of J.
-    //
-    List<DartType> jArgs = j.typeArguments;
-    List<DartType> jVars = jElement.type.typeArguments;
-    supertype = supertype.substitute2(jArgs, jVars);
-    if (supertype == i) {
-      return true;
-    }
-    //
-    // I is listed in the implements clause of J.
-    //
-    for (InterfaceType interfaceType in jElement.interfaces) {
-      interfaceType = interfaceType.substitute2(jArgs, jVars);
-      if (interfaceType == i) {
-        return true;
-      }
-    }
-    //
-    // I is listed in the with clause of J.
-    //
-    for (InterfaceType mixinType in jElement.mixins) {
-      mixinType = mixinType.substitute2(jArgs, jVars);
-      if (mixinType == i) {
-        return true;
-      }
-    }
-    //
-    // J is a mixin application of the mixin of I.
-    //
-    // TODO(brianwilkerson) Determine whether this needs to be implemented or
-    // whether it is covered by the case above.
-    return false;
-  }
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    //
-    // S is dynamic.
-    // The test to determine whether S is dynamic is done here because dynamic
-    // is not an instance of InterfaceType.
-    //
-    if (type.isDynamic) {
-      return true;
-    }
-    //
-    // A type T is more specific than a type S, written T << S,
-    // if one of the following conditions is met:
-    //
-    // Reflexivity: T is S.
-    //
-    if (this == type) {
-      return true;
-    }
-    if (type is InterfaceType) {
-      //
-      // T is bottom. (This case is handled by the class BottomTypeImpl.)
-      //
-      // Direct supertype: S is a direct supertype of T.
-      //
-      if (type.isDirectSupertypeOf(this)) {
-        return true;
-      }
-      //
-      // Covariance: T is of the form I<T1, ..., Tn> and S is of the form
-      // I<S1, ..., Sn> and Ti << Si, 1 <= i <= n.
-      //
-      ClassElement tElement = this.element;
-      ClassElement sElement = type.element;
-      if (tElement == sElement) {
-        List<DartType> tArguments = typeArguments;
-        List<DartType> sArguments = type.typeArguments;
-        if (tArguments.length != sArguments.length) {
-          return false;
-        }
-        for (int i = 0; i < tArguments.length; i++) {
-          if (!(tArguments[i] as TypeImpl)
-              .isMoreSpecificThan(sArguments[i], withDynamic)) {
-            return false;
-          }
-        }
-        return true;
-      }
-    }
-    //
-    // Transitivity: T << U and U << S.
-    //
-    // First check for infinite loops
-    if (element == null) {
-      return false;
-    }
-    if (visitedElements == null) {
-      visitedElements = new HashSet<ClassElement>();
-    } else if (visitedElements.contains(element)) {
-      return false;
-    }
-    visitedElements.add(element);
-    try {
-      // Iterate over all of the types U that are more specific than T because
-      // they are direct supertypes of T and return true if any of them are more
-      // specific than S.
-      InterfaceTypeImpl supertype = superclass;
-      if (supertype != null &&
-          supertype.isMoreSpecificThan(type, withDynamic, visitedElements)) {
-        return true;
-      }
-      for (InterfaceType interfaceType in interfaces) {
-        if ((interfaceType as InterfaceTypeImpl)
-            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      for (InterfaceType mixinType in mixins) {
-        if ((mixinType as InterfaceTypeImpl)
-            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      // If a type I includes an instance method named `call`, and the type of
-      // `call` is the function type F, then I is considered to be more specific
-      // than F.
-      MethodElement callMethod = getMethod('call');
-      if (callMethod != null && !callMethod.isStatic) {
-        FunctionTypeImpl callType = callMethod.type;
-        if (callType.isMoreSpecificThan(type, withDynamic, visitedElements)) {
-          return true;
-        }
-      }
-      return false;
-    } finally {
-      visitedElements.remove(element);
-    }
-  }
-
-  @override
-  ConstructorElement lookUpConstructor(
-      String constructorName, LibraryElement library) {
-    // prepare base ConstructorElement
-    ConstructorElement constructorElement;
-    if (constructorName == null) {
-      constructorElement = element.unnamedConstructor;
-    } else {
-      constructorElement = element.getNamedConstructor(constructorName);
-    }
-    // not found or not accessible
-    if (constructorElement == null ||
-        !constructorElement.isAccessibleIn(library)) {
-      return null;
-    }
-    // return member
-    return ConstructorMember.from(constructorElement, this);
-  }
-
-  @override
-  PropertyAccessorElement lookUpGetter(
-      String getterName, LibraryElement library) {
-    PropertyAccessorElement element = getGetter(getterName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpGetterInSuperclass(getterName, library);
-  }
-
-  @override
-  PropertyAccessorElement lookUpGetterInSuperclass(
-      String getterName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      PropertyAccessorElement element = mixin.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      PropertyAccessorElement element = supertype.getGetter(getterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getGetter(getterName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement lookUpInheritedGetter(String name,
-      {LibraryElement library, bool thisType: true}) {
-    PropertyAccessorElement result;
-    if (thisType) {
-      result = lookUpGetter(name, library);
-    } else {
-      result = lookUpGetterInSuperclass(name, library);
-    }
-    if (result != null) {
-      return result;
-    }
-    return _lookUpMemberInInterfaces(this, false, library,
-        new HashSet<ClassElement>(), (InterfaceType t) => t.getGetter(name));
-  }
-
-  @override
-  ExecutableElement lookUpInheritedGetterOrMethod(String name,
-      {LibraryElement library}) {
-    ExecutableElement result =
-        lookUpGetter(name, library) ?? lookUpMethod(name, library);
-
-    if (result != null) {
-      return result;
-    }
-    return _lookUpMemberInInterfaces(
-        this,
-        false,
-        library,
-        new HashSet<ClassElement>(),
-        (InterfaceType t) => t.getGetter(name) ?? t.getMethod(name));
-  }
-
-  @override
-  MethodElement lookUpInheritedMethod(String name,
-      {LibraryElement library, bool thisType: true}) {
-    MethodElement result;
-    if (thisType) {
-      result = lookUpMethod(name, library);
-    } else {
-      result = lookUpMethodInSuperclass(name, library);
-    }
-    if (result != null) {
-      return result;
-    }
-    return _lookUpMemberInInterfaces(this, false, library,
-        new HashSet<ClassElement>(), (InterfaceType t) => t.getMethod(name));
-  }
-
-  @override
-  PropertyAccessorElement lookUpInheritedSetter(String name,
-      {LibraryElement library, bool thisType: true}) {
-    PropertyAccessorElement result;
-    if (thisType) {
-      result = lookUpSetter(name, library);
-    } else {
-      result = lookUpSetterInSuperclass(name, library);
-    }
-    if (result != null) {
-      return result;
-    }
-    return _lookUpMemberInInterfaces(this, false, library,
-        new HashSet<ClassElement>(), (t) => t.getSetter(name));
-  }
-
-  @override
-  MethodElement lookUpMethod(String methodName, LibraryElement library) {
-    MethodElement element = getMethod(methodName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpMethodInSuperclass(methodName, library);
-  }
-
-  @override
-  MethodElement lookUpMethodInSuperclass(
-      String methodName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      MethodElement element = mixin.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      MethodElement element = supertype.getMethod(methodName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getMethod(methodName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  PropertyAccessorElement lookUpSetter(
-      String setterName, LibraryElement library) {
-    PropertyAccessorElement element = getSetter(setterName);
-    if (element != null && element.isAccessibleIn(library)) {
-      return element;
-    }
-    return lookUpSetterInSuperclass(setterName, library);
-  }
-
-  @override
-  PropertyAccessorElement lookUpSetterInSuperclass(
-      String setterName, LibraryElement library) {
-    for (InterfaceType mixin in mixins.reversed) {
-      PropertyAccessorElement element = mixin.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-    }
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    InterfaceType supertype = superclass;
-    ClassElement supertypeElement =
-        supertype == null ? null : supertype.element;
-    while (supertype != null && !visitedClasses.contains(supertypeElement)) {
-      visitedClasses.add(supertypeElement);
-      PropertyAccessorElement element = supertype.getSetter(setterName);
-      if (element != null && element.isAccessibleIn(library)) {
-        return element;
-      }
-      for (InterfaceType mixin in supertype.mixins.reversed) {
-        element = mixin.getSetter(setterName);
-        if (element != null && element.isAccessibleIn(library)) {
-          return element;
-        }
-      }
-      supertype = supertype.superclass;
-      supertypeElement = supertype == null ? null : supertype.element;
-    }
-    return null;
-  }
-
-  @override
-  InterfaceTypeImpl pruned(List<FunctionTypeAliasElement> prune) {
-    if (prune == null) {
-      return this;
-    } else {
-      // There should never be a reason to prune a type that has already been
-      // pruned, since pruning is only done when expanding a function type
-      // alias, and function type aliases are always expanded by starting with
-      // base types.
-      assert(this.prunedTypedefs == null);
-      InterfaceTypeImpl result = new InterfaceTypeImpl._(element, name, prune);
-      result.typeArguments =
-          typeArguments.map((TypeImpl t) => t.pruned(prune)).toList();
-      return result;
-    }
-  }
-
-  @override
-  InterfaceTypeImpl substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    if (argumentTypes.length != parameterTypes.length) {
-      throw new IllegalArgumentException(
-          "argumentTypes.length (${argumentTypes.length}) != parameterTypes.length (${parameterTypes.length})");
-    }
-    if (argumentTypes.length == 0 || typeArguments.length == 0) {
-      return this.pruned(prune);
-    }
-    List<DartType> newTypeArguments = TypeImpl.substitute(
-        typeArguments, argumentTypes, parameterTypes, prune);
-    if (JavaArrays.equals(newTypeArguments, typeArguments)) {
-      return this;
-    }
-    InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
-    newType.typeArguments = newTypeArguments;
-    return newType;
-  }
-
-  @override
-  InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
-      substitute2(argumentTypes, typeArguments);
-
-  /**
-   * Compute the least upper bound of types [i] and [j], both of which are
-   * known to be interface types.
-   *
-   * In the event that the algorithm fails (which might occur due to a bug in
-   * the analyzer), `null` is returned.
-   */
-  static InterfaceType computeLeastUpperBound(
-      InterfaceType i, InterfaceType j) {
-    // compute set of supertypes
-    Set<InterfaceType> si = computeSuperinterfaceSet(i);
-    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
-    // union si with i and sj with j
-    si.add(i);
-    sj.add(j);
-    // compute intersection, reference as set 's'
-    List<InterfaceType> s = _intersection(si, sj);
-    // for each element in Set s, compute the largest inheritance path to Object
-    List<int> depths = new List<int>.filled(s.length, 0);
-    int maxDepth = 0;
-    for (int n = 0; n < s.length; n++) {
-      depths[n] = computeLongestInheritancePathToObject(s[n]);
-      if (depths[n] > maxDepth) {
-        maxDepth = depths[n];
-      }
-    }
-    // ensure that the currently computed maxDepth is unique,
-    // otherwise, decrement and test for uniqueness again
-    for (; maxDepth >= 0; maxDepth--) {
-      int indexOfLeastUpperBound = -1;
-      int numberOfTypesAtMaxDepth = 0;
-      for (int m = 0; m < depths.length; m++) {
-        if (depths[m] == maxDepth) {
-          numberOfTypesAtMaxDepth++;
-          indexOfLeastUpperBound = m;
-        }
-      }
-      if (numberOfTypesAtMaxDepth == 1) {
-        return s[indexOfLeastUpperBound];
-      }
-    }
-    // Should be impossible--there should always be exactly one type with the
-    // maximum depth.
-    assert(false);
-    return null;
-  }
-
-  /**
-   * Return the length of the longest inheritance path from the given [type] to
-   * Object.
-   *
-   * See [computeLeastUpperBound].
-   */
-  static int computeLongestInheritancePathToObject(InterfaceType type) =>
-      _computeLongestInheritancePathToObject(
-          type, 0, new HashSet<ClassElement>());
-
-  /**
-   * Returns the set of all superinterfaces of the given [type].
-   *
-   * See [computeLeastUpperBound].
-   */
-  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
-      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
-
-  /**
-   * Return the length of the longest inheritance path from a subtype of the
-   * given [type] to Object, where the given [depth] is the length of the
-   * longest path from the subtype to this type. The set of [visitedTypes] is
-   * used to prevent infinite recursion in the case of a cyclic type structure.
-   *
-   * See [computeLongestInheritancePathToObject], and [computeLeastUpperBound].
-   */
-  static int _computeLongestInheritancePathToObject(
-      InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
-    ClassElement classElement = type.element;
-    // Object case
-    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
-      return depth;
-    }
-    int longestPath = 1;
-    try {
-      visitedTypes.add(classElement);
-      List<InterfaceType> superinterfaces = classElement.interfaces;
-      int pathLength;
-      if (superinterfaces.length > 0) {
-        // loop through each of the superinterfaces recursively calling this
-        // method and keeping track of the longest path to return
-        for (InterfaceType superinterface in superinterfaces) {
-          pathLength = _computeLongestInheritancePathToObject(
-              superinterface, depth + 1, visitedTypes);
-          if (pathLength > longestPath) {
-            longestPath = pathLength;
-          }
-        }
-      }
-      // finally, perform this same check on the super type
-      // TODO(brianwilkerson) Does this also need to add in the number of mixin
-      // classes?
-      InterfaceType supertype = classElement.supertype;
-      pathLength = _computeLongestInheritancePathToObject(
-          supertype, depth + 1, visitedTypes);
-      if (pathLength > longestPath) {
-        longestPath = pathLength;
-      }
-    } finally {
-      visitedTypes.remove(classElement);
-    }
-    return longestPath;
-  }
-
-  /**
-   * Add all of the superinterfaces of the given [type] to the given [set].
-   * Return the [set] as a convenience.
-   *
-   * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
-   */
-  static Set<InterfaceType> _computeSuperinterfaceSet(
-      InterfaceType type, HashSet<InterfaceType> set) {
-    Element element = type.element;
-    if (element != null) {
-      List<InterfaceType> superinterfaces = type.interfaces;
-      for (InterfaceType superinterface in superinterfaces) {
-        if (set.add(superinterface)) {
-          _computeSuperinterfaceSet(superinterface, set);
-        }
-      }
-      InterfaceType supertype = type.superclass;
-      if (supertype != null) {
-        if (set.add(supertype)) {
-          _computeSuperinterfaceSet(supertype, set);
-        }
-      }
-    }
-    return set;
-  }
-
-  /**
-   * Return the intersection of the [first] and [second] sets of types, where
-   * intersection is based on the equality of the types themselves.
-   */
-  static List<InterfaceType> _intersection(
-      Set<InterfaceType> first, Set<InterfaceType> second) {
-    Set<InterfaceType> result = new HashSet<InterfaceType>.from(first);
-    result.retainAll(second);
-    return new List.from(result);
-  }
-
-  /**
-   * Look up the getter with the given [name] in the interfaces
-   * implemented by the given [targetType], either directly or indirectly.
-   * Return the element representing the getter that was found, or `null` if
-   * there is no getter with the given name. The flag [includeTargetType] should
-   * be `true` if the search should include the target type. The
-   * [visitedInterfaces] is a set containing all of the interfaces that have
-   * been examined, used to prevent infinite recursion and to optimize the
-   * search.
-   */
-  static ExecutableElement _lookUpMemberInInterfaces(
-      InterfaceType targetType,
-      bool includeTargetType,
-      LibraryElement library,
-      HashSet<ClassElement> visitedInterfaces,
-      ExecutableElement getMember(InterfaceType type)) {
-    // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
-    // specification (titled "Inheritance and Overriding" under "Interfaces")
-    // describes a much more complex scheme for finding the inherited member.
-    // We need to follow that scheme. The code below should cover the 80% case.
-    ClassElement targetClass = targetType.element;
-    if (!visitedInterfaces.add(targetClass)) {
-      return null;
-    }
-    if (includeTargetType) {
-      ExecutableElement member = getMember(targetType);
-      if (member != null && member.isAccessibleIn(library)) {
-        return member;
-      }
-    }
-    for (InterfaceType interfaceType in targetType.interfaces) {
-      ExecutableElement member = _lookUpMemberInInterfaces(
-          interfaceType, true, library, visitedInterfaces, getMember);
-      if (member != null) {
-        return member;
-      }
-    }
-    for (InterfaceType mixinType in targetType.mixins.reversed) {
-      ExecutableElement member = _lookUpMemberInInterfaces(
-          mixinType, true, library, visitedInterfaces, getMember);
-      if (member != null) {
-        return member;
-      }
-    }
-    InterfaceType superclass = targetType.superclass;
-    if (superclass == null) {
-      return null;
-    }
-    return _lookUpMemberInInterfaces(
-        superclass, true, library, visitedInterfaces, getMember);
-  }
-}
-
-/**
- * A label associated with a statement.
- */
-abstract class LabelElement implements Element {
-  /**
-   * An empty list of label elements.
-   */
-  static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
-
-  /**
-   * Return the executable element in which this label is defined.
-   */
-  @override
-  ExecutableElement get enclosingElement;
-}
-
-/**
- * A concrete implementation of a [LabelElement].
- */
-class LabelElementImpl extends ElementImpl implements LabelElement {
-  /**
-   * A flag indicating whether this label is associated with a `switch`
-   * statement.
-   */
-  // TODO(brianwilkerson) Make this a modifier.
-  final bool _onSwitchStatement;
-
-  /**
-   * A flag indicating whether this label is associated with a `switch` member
-   * (`case` or `default`).
-   */
-  // TODO(brianwilkerson) Make this a modifier.
-  final bool _onSwitchMember;
-
-  /**
-   * Initialize a newly created label element to have the given [name].
-   * [onSwitchStatement] should be `true` if this label is associated with a
-   * `switch` statement and [onSwitchMember] should be `true` if this label is
-   * associated with a `switch` member.
-   */
-  LabelElementImpl(
-      Identifier name, this._onSwitchStatement, this._onSwitchMember)
-      : super.forNode(name);
-
-  @override
-  ExecutableElement get enclosingElement =>
-      super.enclosingElement as ExecutableElement;
-
-  /**
-   * Return `true` if this label is associated with a `switch` member (`case` or
-   * `default`).
-   */
-  bool get isOnSwitchMember => _onSwitchMember;
-
-  /**
-   * Return `true` if this label is associated with a `switch` statement.
-   */
-  bool get isOnSwitchStatement => _onSwitchStatement;
-
-  @override
-  ElementKind get kind => ElementKind.LABEL;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLabelElement(this);
-}
-
-/**
- * A library.
- */
-abstract class LibraryElement implements Element {
-  /**
-   * An empty list of library elements.
-   */
-  static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
-
-  /**
-   * Return the compilation unit that defines this library.
-   */
-  CompilationUnitElement get definingCompilationUnit;
-
-  /**
-   * Return the entry point for this library, or `null` if this library does not
-   * have an entry point. The entry point is defined to be a zero argument
-   * top-level function whose name is `main`.
-   */
-  FunctionElement get entryPoint;
-
-  /**
-   * Return a list containing all of the libraries that are exported from this
-   * library.
-   */
-  List<LibraryElement> get exportedLibraries;
-
-  /**
-   * The export [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  Namespace get exportNamespace;
-
-  /**
-   * Return a list containing all of the exports defined in this library.
-   */
-  List<ExportElement> get exports;
-
-  /**
-   * Return `true` if the defining compilation unit of this library contains at
-   * least one import directive whose URI uses the "dart-ext" scheme.
-   */
-  bool get hasExtUri;
-
-  /**
-   * Return `true` if this library defines a top-level function named
-   * `loadLibrary`.
-   */
-  bool get hasLoadLibraryFunction;
-
-  /**
-   * Return a list containing all of the libraries that are imported into this
-   * library. This includes all of the libraries that are imported using a
-   * prefix (also available through the prefixes returned by [getPrefixes]) and
-   * those that are imported without a prefix.
-   */
-  List<LibraryElement> get importedLibraries;
-
-  /**
-   * Return a list containing all of the imports defined in this library.
-   */
-  List<ImportElement> get imports;
-
-  /**
-   * Return `true` if this library is an application that can be run in the
-   * browser.
-   */
-  bool get isBrowserApplication;
-
-  /**
-   * Return `true` if this library is the dart:core library.
-   */
-  bool get isDartCore;
-
-  /**
-   * Return `true` if this library is part of the SDK.
-   */
-  bool get isInSdk;
-
-  /**
-   * Return the element representing the synthetic function `loadLibrary` that
-   * is implicitly defined for this library if the library is imported using a
-   * deferred import.
-   */
-  FunctionElement get loadLibraryFunction;
-
-  /**
-   * Return a list containing all of the compilation units that are included in
-   * this library using a `part` directive. This does not include the defining
-   * compilation unit that contains the `part` directives.
-   */
-  List<CompilationUnitElement> get parts;
-
-  /**
-   * Return a list containing elements for each of the prefixes used to `import`
-   * libraries into this library. Each prefix can be used in more than one
-   * `import` directive.
-   */
-  List<PrefixElement> get prefixes;
-
-  /**
-   * The public [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  Namespace get publicNamespace;
-
-  /**
-   * Return a list containing all of the compilation units this library consists
-   * of. This includes the defining compilation unit and units included using
-   * the `part` directive.
-   */
-  List<CompilationUnitElement> get units;
-
-  /**
-   * Return a list containing all directly and indirectly imported libraries.
-   */
-  List<LibraryElement> get visibleLibraries;
-
-  /**
-   * Return a list containing all of the imports that share the given [prefix],
-   * or an empty array if there are no such imports.
-   */
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
-
-  /**
-   * Return the class defined in this library that has the given [name], or
-   * `null` if this library does not define a class with the given name.
-   */
-  ClassElement getType(String className);
-
-  /**
-   * Return `true` if this library is up to date with respect to the given
-   * [timeStamp]. If any transitively referenced Source is newer than the time
-   * stamp, this method returns false.
-   */
-  bool isUpToDate(int timeStamp);
-}
-
-/**
- * A concrete implementation of a [LibraryElement].
- */
-class LibraryElementImpl extends ElementImpl implements LibraryElement {
-  /**
-   * The analysis context in which this library is defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The compilation unit that defines this library.
-   */
-  CompilationUnitElement _definingCompilationUnit;
-
-  /**
-   * The entry point for this library, or `null` if this library does not have
-   * an entry point.
-   */
-  FunctionElement entryPoint;
-
-  /**
-   * A list containing specifications of all of the imports defined in this
-   * library.
-   */
-  List<ImportElement> _imports = ImportElement.EMPTY_LIST;
-
-  /**
-   * A list containing specifications of all of the exports defined in this
-   * library.
-   */
-  List<ExportElement> _exports = ExportElement.EMPTY_LIST;
-
-  /**
-   * A list containing the strongly connected component in the import/export
-   * graph in which the current library resides.  Computed on demand, null
-   * if not present.  If _libraryCycle is set, then the _libraryCycle field
-   * for all libraries reachable from this library in the import/export graph
-   * is also set.
-   */
-  List<LibraryElement> _libraryCycle = null;
-
-  /**
-   * A list containing all of the compilation units that are included in this
-   * library using a `part` directive.
-   */
-  List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
-
-  /**
-   * The element representing the synthetic function `loadLibrary` that is
-   * defined for this library, or `null` if the element has not yet been created.
-   */
-  FunctionElement _loadLibraryFunction;
-
-  @override
-  final int nameLength;
-
-  /**
-   * The export [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  @override
-  Namespace exportNamespace;
-
-  /**
-   * The public [Namespace] of this library, `null` if it has not been
-   * computed yet.
-   */
-  @override
-  Namespace publicNamespace;
-
-  /**
-   * Initialize a newly created library element in the given [context] to have
-   * the given [name] and [offset].
-   */
-  LibraryElementImpl(this.context, String name, int offset, this.nameLength)
-      : super(name, offset);
-
-  /**
-   * Initialize a newly created library element in the given [context] to have
-   * the given [name].
-   */
-  LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
-      : super.forNode(name),
-        nameLength = name != null ? name.length : 0;
-
-  @override
-  CompilationUnitElement get definingCompilationUnit =>
-      _definingCompilationUnit;
-
-  /**
-   * Set the compilation unit that defines this library to the given compilation
-   * [unit].
-   */
-  void set definingCompilationUnit(CompilationUnitElement unit) {
-    assert((unit as CompilationUnitElementImpl).librarySource == unit.source);
-    (unit as CompilationUnitElementImpl).enclosingElement = this;
-    this._definingCompilationUnit = unit;
-  }
-
-  @override
-  List<LibraryElement> get exportedLibraries {
-    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ExportElement element in _exports) {
-      LibraryElement library = element.exportedLibrary;
-      if (library != null) {
-        libraries.add(library);
-      }
-    }
-    return new List.from(libraries);
-  }
-
-  @override
-  List<ExportElement> get exports => _exports;
-
-  /**
-   * Set the specifications of all of the exports defined in this library to the
-   * given list of [exports].
-   */
-  void set exports(List<ExportElement> exports) {
-    for (ExportElement exportElement in exports) {
-      (exportElement as ExportElementImpl).enclosingElement = this;
-    }
-    this._exports = exports;
-  }
-
-  @override
-  bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
-
-  /**
-   * Set whether this library has an import of a "dart-ext" URI.
-   */
-  void set hasExtUri(bool hasExtUri) {
-    setModifier(Modifier.HAS_EXT_URI, hasExtUri);
-  }
-
-  @override
-  int get hashCode => _definingCompilationUnit.hashCode;
-
-  @override
-  bool get hasLoadLibraryFunction {
-    if (_definingCompilationUnit.hasLoadLibraryFunction) {
-      return true;
-    }
-    for (int i = 0; i < _parts.length; i++) {
-      if (_parts[i].hasLoadLibraryFunction) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String get identifier => _definingCompilationUnit.source.encoding;
-
-  @override
-  List<LibraryElement> get importedLibraries {
-    HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ImportElement element in _imports) {
-      LibraryElement library = element.importedLibrary;
-      if (library != null) {
-        libraries.add(library);
-      }
-    }
-    return new List.from(libraries);
-  }
-
-  @override
-  List<ImportElement> get imports => _imports;
-
-  /**
-   * Set the specifications of all of the imports defined in this library to the
-   * given list of [imports].
-   */
-  void set imports(List<ImportElement> imports) {
-    for (ImportElement importElement in imports) {
-      (importElement as ImportElementImpl).enclosingElement = this;
-      PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
-      if (prefix != null) {
-        prefix.enclosingElement = this;
-      }
-    }
-    this._imports = imports;
-  }
-
-  @override
-  bool get isBrowserApplication =>
-      entryPoint != null && isOrImportsBrowserLibrary;
-
-  @override
-  bool get isDartCore => name == "dart.core";
-
-  @override
-  bool get isInSdk =>
-      StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
-
-  /**
-   * Return `true` if the receiver directly or indirectly imports the
-   * 'dart:html' libraries.
-   */
-  bool get isOrImportsBrowserLibrary {
-    List<LibraryElement> visited = new List<LibraryElement>();
-    Source htmlLibSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
-    visited.add(this);
-    for (int index = 0; index < visited.length; index++) {
-      LibraryElement library = visited[index];
-      Source source = library.definingCompilationUnit.source;
-      if (source == htmlLibSource) {
-        return true;
-      }
-      for (LibraryElement importedLibrary in library.importedLibraries) {
-        if (!visited.contains(importedLibrary)) {
-          visited.add(importedLibrary);
-        }
-      }
-      for (LibraryElement exportedLibrary in library.exportedLibraries) {
-        if (!visited.contains(exportedLibrary)) {
-          visited.add(exportedLibrary);
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.LIBRARY;
-
-  @override
-  LibraryElement get library => this;
-
-  List<LibraryElement> get libraryCycle {
-    if (_libraryCycle != null) {
-      return _libraryCycle;
-    }
-
-    // Global counter for this run of the algorithm
-    int counter = 0;
-    // The discovery times of each library
-    Map<LibraryElementImpl, int> indices = {};
-    // The set of scc candidates
-    Set<LibraryElementImpl> active = new Set();
-    // The stack of discovered elements
-    List<LibraryElementImpl> stack = [];
-    // For a given library that has not yet been processed by this run of the
-    // algorithm, compute the strongly connected components.
-    int scc(LibraryElementImpl library) {
-      int index = counter++;
-      int root = index;
-      indices[library] = index;
-      active.add(library);
-      stack.add(library);
-      void recurse(LibraryElementImpl child) {
-        if (!indices.containsKey(child)) {
-          // We haven't visited this child yet, so recurse on the child,
-          // returning the lowest numbered node reachable from the child.  If
-          // the child can reach a root which is lower numbered than anything
-          // we've reached so far, update the root.
-          root = min(root, scc(child));
-        } else if (active.contains(child)) {
-          // The child has been visited, but has not yet been placed into a
-          // component.  If the child is higher than anything we've seen so far
-          // update the root appropriately.
-          root = min(root, indices[child]);
-        }
-      }
-      // Recurse on all of the children in the import/export graph, filtering
-      // out those for which library cycles have already been computed.
-      library.exportedLibraries
-          .where((l) => l._libraryCycle == null)
-          .forEach(recurse);
-      library.importedLibraries
-          .where((l) => l._libraryCycle == null)
-          .forEach(recurse);
-
-      if (root == index) {
-        // This is the root of a strongly connected component.
-        // Pop the elements, and share the component across all
-        // of the elements.
-        List<LibraryElement> component = <LibraryElement>[];
-        LibraryElementImpl cur = null;
-        do {
-          cur = stack.removeLast();
-          active.remove(cur);
-          component.add(cur);
-          cur._libraryCycle = component;
-        } while (cur != library);
-      }
-      return root;
-    }
-    scc(library);
-    return _libraryCycle;
-  }
-
-  @override
-  FunctionElement get loadLibraryFunction {
-    assert(_loadLibraryFunction != null);
-    return _loadLibraryFunction;
-  }
-
-  @override
-  List<CompilationUnitElement> get parts => _parts;
-
-  /**
-   * Set the compilation units that are included in this library using a `part`
-   * directive to the given list of [parts].
-   */
-  void set parts(List<CompilationUnitElement> parts) {
-    for (CompilationUnitElement compilationUnit in parts) {
-      assert((compilationUnit as CompilationUnitElementImpl).librarySource ==
-          source);
-      (compilationUnit as CompilationUnitElementImpl).enclosingElement = this;
-    }
-    this._parts = parts;
-  }
-
-  @override
-  List<PrefixElement> get prefixes {
-    HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
-    for (ImportElement element in _imports) {
-      PrefixElement prefix = element.prefix;
-      if (prefix != null) {
-        prefixes.add(prefix);
-      }
-    }
-    return new List.from(prefixes);
-  }
-
-  @override
-  Source get source {
-    if (_definingCompilationUnit == null) {
-      return null;
-    }
-    return _definingCompilationUnit.source;
-  }
-
-  @override
-  List<CompilationUnitElement> get units {
-    List<CompilationUnitElement> units = new List<CompilationUnitElement>();
-    units.add(_definingCompilationUnit);
-    units.addAll(_parts);
-    return units;
-  }
-
-  @override
-  List<LibraryElement> get visibleLibraries {
-    Set<LibraryElement> visibleLibraries = new Set();
-    _addVisibleLibraries(visibleLibraries, false);
-    return new List.from(visibleLibraries);
-  }
-
-  @override
-  bool operator ==(Object object) =>
-      object is LibraryElementImpl &&
-      _definingCompilationUnit == object.definingCompilationUnit;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLibraryElement(this);
-
-  /**
-   * Create the [FunctionElement] to be returned by [loadLibraryFunction],
-   * using types provided by [typeProvider].
-   */
-  void createLoadLibraryFunction(TypeProvider typeProvider) {
-    FunctionElementImpl function =
-        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
-    function.synthetic = true;
-    function.enclosingElement = this;
-    function.returnType = typeProvider.futureDynamicType;
-    function.type = new FunctionTypeImpl(function);
-    _loadLibraryFunction = function;
-  }
-
-  @override
-  ElementImpl getChild(String identifier) {
-    if ((_definingCompilationUnit as CompilationUnitElementImpl).identifier ==
-        identifier) {
-      return _definingCompilationUnit as CompilationUnitElementImpl;
-    }
-    for (CompilationUnitElement part in _parts) {
-      if ((part as CompilationUnitElementImpl).identifier == identifier) {
-        return part as CompilationUnitElementImpl;
-      }
-    }
-    for (ImportElement importElement in _imports) {
-      if ((importElement as ImportElementImpl).identifier == identifier) {
-        return importElement as ImportElementImpl;
-      }
-    }
-    for (ExportElement exportElement in _exports) {
-      if ((exportElement as ExportElementImpl).identifier == identifier) {
-        return exportElement as ExportElementImpl;
-      }
-    }
-    return null;
-  }
-
-  @override
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
-    int count = _imports.length;
-    List<ImportElement> importList = new List<ImportElement>();
-    for (int i = 0; i < count; i++) {
-      if (identical(_imports[i].prefix, prefixElement)) {
-        importList.add(_imports[i]);
-      }
-    }
-    return importList;
-  }
-
-  @override
-  ClassElement getType(String className) {
-    ClassElement type = _definingCompilationUnit.getType(className);
-    if (type != null) {
-      return type;
-    }
-    for (CompilationUnitElement part in _parts) {
-      type = part.getType(className);
-      if (type != null) {
-        return type;
-      }
-    }
-    return null;
-  }
-
-  /** Given an update to this library which may have added or deleted edges
-   * in the import/export graph originating from this node only, remove any
-   * cached library cycles in the element model which may have been invalidated.
-   */
-  void invalidateLibraryCycles() {
-    if (_libraryCycle == null) {
-      // We have already invalidated this node, or we have never computed
-      // library cycle information for it.  In the former case, we're done. In
-      // the latter case, this node cannot be reachable from any node for which
-      // we have computed library cycle information.  Therefore, any edges added
-      // or deleted in the update causing this invalidation can only be edges to
-      // nodes which either have no library cycle information (and hence do not
-      // need invalidation), or which do not reach this node by any path.
-      // In either case, no further invalidation is needed.
-      return;
-    }
-    // If we have pre-computed library cycle information, then we must
-    // invalidate the information both on this element, and on certain
-    // other elements.  Edges originating at this node may have been
-    // added or deleted.  A deleted edge that points outside of this cycle
-    // cannot change the cycle information for anything outside of this cycle,
-    // and so it is sufficient to delete the cached library information on this
-    // cycle.  An added edge which points to another node within the cycle
-    // only invalidates the cycle.  An added edge which points to a node earlier
-    // in the topological sort of cycles induces no invalidation (since there
-    // are by definition no back edges from earlier cycles in the topological
-    // order, and hence no possible cycle can have been introduced.  The only
-    // remaining case is that we have added an edge to a node which is later
-    // in the topological sort of cycles.  This can induce cycles, since it
-    // represents a new back edge.  It would be sufficient to invalidate the
-    // cycle information for all nodes that are between the target and the
-    // node in the topological order.  For simplicity, we simply invalidate
-    // all nodes which are reachable from the the source node.
-    // Note that in the invalidation phase, we do not cut off when we encounter
-    // a node with no library cycle information, since we do not know whether
-    // we are in the case where invalidation has already been performed, or we
-    // are in the case where library cycles have simply never been computed from
-    // a newly reachable node.
-    Set<LibraryElementImpl> active = new HashSet();
-    void invalidate(LibraryElementImpl library) {
-      if (!active.add(library)) return;
-      if (library._libraryCycle != null) {
-        library._libraryCycle.forEach(invalidate);
-        library._libraryCycle = null;
-      }
-      library.exportedLibraries.forEach(invalidate);
-      library.importedLibraries.forEach(invalidate);
-    }
-    invalidate(this);
-  }
-
-  @override
-  bool isUpToDate(int timeStamp) {
-    Set<LibraryElement> visitedLibraries = new Set();
-    return _safeIsUpToDate(this, timeStamp, visitedLibraries);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(_definingCompilationUnit, visitor);
-    safelyVisitChildren(_exports, visitor);
-    safelyVisitChildren(_imports, visitor);
-    safelyVisitChildren(_parts, visitor);
-  }
-
-  /**
-   * Recursively fills set of visible libraries for
-   * [getVisibleElementsLibraries].
-   */
-  void _addVisibleLibraries(
-      Set<LibraryElement> visibleLibraries, bool includeExports) {
-    // maybe already processed
-    if (!visibleLibraries.add(this)) {
-      return;
-    }
-    // add imported libraries
-    for (ImportElement importElement in _imports) {
-      LibraryElement importedLibrary = importElement.importedLibrary;
-      if (importedLibrary != null) {
-        (importedLibrary as LibraryElementImpl)
-            ._addVisibleLibraries(visibleLibraries, true);
-      }
-    }
-    // add exported libraries
-    if (includeExports) {
-      for (ExportElement exportElement in _exports) {
-        LibraryElement exportedLibrary = exportElement.exportedLibrary;
-        if (exportedLibrary != null) {
-          (exportedLibrary as LibraryElementImpl)
-              ._addVisibleLibraries(visibleLibraries, true);
-        }
-      }
-    }
-  }
-
-  /**
-   * Return `true` if the given [library] is up to date with respect to the
-   * given [timeStamp]. The set of [visitedLibraries] is used to prevent
-   * infinite recusion in the case of mutually dependent libraries.
-   */
-  static bool _safeIsUpToDate(LibraryElement library, int timeStamp,
-      Set<LibraryElement> visitedLibraries) {
-    if (!visitedLibraries.contains(library)) {
-      visitedLibraries.add(library);
-      AnalysisContext context = library.context;
-      // Check the defining compilation unit.
-      if (timeStamp <
-          context
-              .getModificationStamp(library.definingCompilationUnit.source)) {
-        return false;
-      }
-      // Check the parted compilation units.
-      for (CompilationUnitElement element in library.parts) {
-        if (timeStamp < context.getModificationStamp(element.source)) {
-          return false;
-        }
-      }
-      // Check the imported libraries.
-      for (LibraryElement importedLibrary in library.importedLibraries) {
-        if (!_safeIsUpToDate(importedLibrary, timeStamp, visitedLibraries)) {
-          return false;
-        }
-      }
-      // Check the exported libraries.
-      for (LibraryElement exportedLibrary in library.exportedLibraries) {
-        if (!_safeIsUpToDate(exportedLibrary, timeStamp, visitedLibraries)) {
-          return false;
-        }
-      }
-    }
-    return true;
-  }
-}
-
-/**
- * An element that can be (but are not required to be) defined within a method
- * or function (an [ExecutableElement]).
- */
-abstract class LocalElement implements Element {
-  /**
-   * Return a source range that covers the approximate portion of the source in
-   * which the name of this element is visible, or `null` if there is no single
-   * range of characters within which the element name is visible.
-   *
-   * * For a local variable, this includes everything from the end of the
-   *   variable's initializer to the end of the block that encloses the variable
-   *   declaration.
-   * * For a parameter, this includes the body of the method or function that
-   *   declares the parameter.
-   * * For a local function, this includes everything from the beginning of the
-   *   function's body to the end of the block that encloses the function
-   *   declaration.
-   * * For top-level functions, `null` will be returned because they are
-   *   potentially visible in multiple sources.
-   */
-  SourceRange get visibleRange;
-}
-
-/**
- * A local variable.
- */
-abstract class LocalVariableElement implements LocalElement, VariableElement {
-  /**
-   * An empty list of field elements.
-   */
-  static const List<LocalVariableElement> EMPTY_LIST =
-      const <LocalVariableElement>[];
-}
-
-/**
- * A concrete implementation of a [LocalVariableElement].
- */
-class LocalVariableElementImpl extends VariableElementImpl
-    implements LocalVariableElement {
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  LocalVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created local variable element to have the given [name].
-   */
-  LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  String get identifier {
-    int enclosingOffset =
-        enclosingElement != null ? enclosingElement.nameOffset : 0;
-    int delta = nameOffset - enclosingOffset;
-    return '${super.identifier}@$delta';
-  }
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
-
-  @override
-  ElementKind get kind => ElementKind.LOCAL_VARIABLE;
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitLocalVariableElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-  }
-
-  @override
-  VariableDeclaration computeNode() =>
-      getNodeMatching((node) => node is VariableDeclaration);
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-}
-
-/**
- * An element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-abstract class Member implements Element {
-  /**
-   * The element on which the parameterized element was created.
-   */
-  final Element _baseElement;
-
-  /**
-   * The type in which the element is defined.
-   */
-  final ParameterizedType _definingType;
-
-  /**
-   * Initialize a newly created element to represent a member, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  Member(this._baseElement, this._definingType);
-
-  /**
-   * Return the element on which the parameterized element was created.
-   */
-  Element get baseElement => _baseElement;
-
-  @override
-  AnalysisContext get context => _baseElement.context;
-
-  /**
-   * Return the type in which the element is defined.
-   */
-  ParameterizedType get definingType => _definingType;
-
-  @override
-  String get displayName => _baseElement.displayName;
-
-  @override
-  SourceRange get docRange => _baseElement.docRange;
-
-  int get id => _baseElement.id;
-
-  @override
-  bool get isDeprecated => _baseElement.isDeprecated;
-
-  @override
-  bool get isOverride => _baseElement.isOverride;
-
-  @override
-  bool get isPrivate => _baseElement.isPrivate;
-
-  @override
-  bool get isPublic => _baseElement.isPublic;
-
-  @override
-  bool get isSynthetic => _baseElement.isSynthetic;
-
-  @override
-  ElementKind get kind => _baseElement.kind;
-
-  @override
-  LibraryElement get library => _baseElement.library;
-
-  @override
-  ElementLocation get location => _baseElement.location;
-
-  @override
-  List<ElementAnnotation> get metadata => _baseElement.metadata;
-
-  @override
-  String get name => _baseElement.name;
-
-  @override
-  int get nameLength => _baseElement.nameLength;
-
-  @override
-  int get nameOffset => _baseElement.nameOffset;
-
-  @override
-  Source get source => _baseElement.source;
-
-  @override
-  CompilationUnit get unit => _baseElement.unit;
-
-  @override
-  String computeDocumentationComment() =>
-      _baseElement.computeDocumentationComment();
-
-  @override
-  AstNode computeNode() => _baseElement.computeNode();
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) =>
-      baseElement.getAncestor(predicate);
-
-  @override
-  String getExtendedDisplayName(String shortName) =>
-      _baseElement.getExtendedDisplayName(shortName);
-
-  @override
-  bool isAccessibleIn(LibraryElement library) =>
-      _baseElement.isAccessibleIn(library);
-
-  /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  void safelyVisitChild(Element child, ElementVisitor visitor) {
-    // TODO(brianwilkerson) Make this private
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
-   * Use the given [visitor] to visit all of the [children].
-   */
-  void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
-    // TODO(brianwilkerson) Make this private
-    if (children != null) {
-      for (Element child in children) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Return the type that results from replacing the type parameters in the
-   * given [type] with the type arguments associated with this member.
-   */
-  @deprecated
-  DartType substituteFor(DartType type) {
-    if (type == null) {
-      return null;
-    }
-    List<DartType> argumentTypes = _definingType.typeArguments;
-    List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(_definingType.typeParameters);
-    return type.substitute2(argumentTypes, parameterTypes);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-}
-
-/**
- * An element that represents a method defined within a type.
- */
-abstract class MethodElement implements ClassMemberElement, ExecutableElement {
-  /**
-   * An empty list of method elements.
-   */
-  static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
-
-  /**
-   * Return the resolved [MethodDeclaration] node that declares this
-   * [MethodElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  MethodDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [MethodElement].
- */
-class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
-  /**
-   * Initialize a newly created method element to have the given [name] at the
-   * given [offset].
-   */
-  MethodElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created method element to have the given [name].
-   */
-  MethodElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this method is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  String get displayName {
-    String displayName = super.displayName;
-    if ("unary-" == displayName) {
-      return "-";
-    }
-    return displayName;
-  }
-
-  @override
-  ClassElement get enclosingElement => super.enclosingElement as ClassElement;
-
-  @override
-  bool get isOperator {
-    String name = displayName;
-    if (name.isEmpty) {
-      return false;
-    }
-    int first = name.codeUnitAt(0);
-    return !((0x61 <= first && first <= 0x7A) ||
-        (0x41 <= first && first <= 0x5A) ||
-        first == 0x5F ||
-        first == 0x24);
-  }
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  ElementKind get kind => ElementKind.METHOD;
-
-  @override
-  String get name {
-    String name = super.name;
-    if (isOperator && name == "-") {
-      if (parameters.length == 0) {
-        return "unary-";
-      }
-    }
-    return super.name;
-  }
-
-  /**
-   * Set whether this method is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(displayName);
-    super.appendTo(buffer);
-  }
-
-  @override
-  MethodDeclaration computeNode() =>
-      getNodeMatching((node) => node is MethodDeclaration);
-}
-
-/**
- * A method element defined in a parameterized type where the values of the type
- * parameters are known.
- */
-class MethodMember extends ExecutableMember implements MethodElement {
-  /**
-   * Initialize a newly created element to represent a method, based on the
-   * [baseElement], defined by the [definingType]. If [type] is passed, it
-   * represents the full type of the member, and will take precedence over
-   * the [definingType].
-   */
-  MethodMember(MethodElement baseElement, InterfaceType definingType,
-      [DartType type])
-      : super(baseElement, definingType, type);
-
-  @override
-  MethodElement get baseElement => super.baseElement as MethodElement;
-
-  @override
-  ClassElement get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMethodElement(this);
-
-  @override
-  MethodDeclaration computeNode() => baseElement.computeNode();
-
-  @override
-  String toString() {
-    MethodElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(baseElement.enclosingElement.displayName);
-    buffer.write(".");
-    buffer.write(baseElement.displayName);
-    buffer.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(parameters[i]);
-    }
-    buffer.write(")");
-    if (type != null) {
-      buffer.write(Element.RIGHT_ARROW);
-      buffer.write(type.returnType);
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * If the given [method]'s type is different when any type parameters from the
-   * defining type's declaration are replaced with the actual type arguments
-   * from the [definingType], create a method member representing the given
-   * method. Return the member that was created, or the base method if no member
-   * was created.
-   */
-  static MethodElement from(MethodElement method, InterfaceType definingType) {
-    if (method == null || definingType.typeArguments.length == 0) {
-      return method;
-    }
-    FunctionType baseType = method.type;
-    List<DartType> argumentTypes = definingType.typeArguments;
-    List<DartType> parameterTypes = definingType.element.type.typeArguments;
-    FunctionType substitutedType =
-        baseType.substitute2(argumentTypes, parameterTypes);
-    if (baseType == substitutedType) {
-      return method;
-    }
-    return new MethodMember(method, definingType, substitutedType);
-  }
-}
-
-/**
- * The enumeration `Modifier` defines constants for all of the modifiers defined
- * by the Dart language and for a few additional flags that are useful.
- */
-class Modifier extends Enum<Modifier> {
-  /**
-   * Indicates that the modifier 'abstract' was applied to the element.
-   */
-  static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
-
-  /**
-   * Indicates that an executable element has a body marked as being
-   * asynchronous.
-   */
-  static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
-
-  /**
-   * Indicates that the modifier 'const' was applied to the element.
-   */
-  static const Modifier CONST = const Modifier('CONST', 2);
-
-  /**
-   * Indicates that the import element represents a deferred library.
-   */
-  static const Modifier DEFERRED = const Modifier('DEFERRED', 3);
-
-  /**
-   * Indicates that a class element was defined by an enum declaration.
-   */
-  static const Modifier ENUM = const Modifier('ENUM', 4);
-
-  /**
-   * Indicates that a class element was defined by an enum declaration.
-   */
-  static const Modifier EXTERNAL = const Modifier('EXTERNAL', 5);
-
-  /**
-   * Indicates that the modifier 'factory' was applied to the element.
-   */
-  static const Modifier FACTORY = const Modifier('FACTORY', 6);
-
-  /**
-   * Indicates that the modifier 'final' was applied to the element.
-   */
-  static const Modifier FINAL = const Modifier('FINAL', 7);
-
-  /**
-   * Indicates that an executable element has a body marked as being a
-   * generator.
-   */
-  static const Modifier GENERATOR = const Modifier('GENERATOR', 8);
-
-  /**
-   * Indicates that the pseudo-modifier 'get' was applied to the element.
-   */
-  static const Modifier GETTER = const Modifier('GETTER', 9);
-
-  /**
-   * A flag used for libraries indicating that the defining compilation unit
-   * contains at least one import directive whose URI uses the "dart-ext"
-   * scheme.
-   */
-  static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 10);
-
-  /**
-   * Indicates that the associated element did not have an explicit type
-   * associated with it. If the element is an [ExecutableElement], then the
-   * type being referred to is the return type.
-   */
-  static const Modifier IMPLICIT_TYPE = const Modifier('IMPLICIT_TYPE', 11);
-
-  /**
-   * Indicates that a class can validly be used as a mixin.
-   */
-  static const Modifier MIXIN = const Modifier('MIXIN', 12);
-
-  /**
-   * Indicates that a class is a mixin application.
-   */
-  static const Modifier MIXIN_APPLICATION =
-      const Modifier('MIXIN_APPLICATION', 13);
-
-  /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the context.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
-      const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 14);
-
-  /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the scope.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
-      const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 15);
-
-  /**
-   * Indicates that a class contains an explicit reference to 'super'.
-   */
-  static const Modifier REFERENCES_SUPER =
-      const Modifier('REFERENCES_SUPER', 16);
-
-  /**
-   * Indicates that the pseudo-modifier 'set' was applied to the element.
-   */
-  static const Modifier SETTER = const Modifier('SETTER', 17);
-
-  /**
-   * Indicates that the modifier 'static' was applied to the element.
-   */
-  static const Modifier STATIC = const Modifier('STATIC', 18);
-
-  /**
-   * Indicates that the element does not appear in the source code but was
-   * implicitly created. For example, if a class does not define any
-   * constructors, an implicit zero-argument constructor will be created and it
-   * will be marked as being synthetic.
-   */
-  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 19);
-
-  static const List<Modifier> values = const [
-    ABSTRACT,
-    ASYNCHRONOUS,
-    CONST,
-    DEFERRED,
-    ENUM,
-    EXTERNAL,
-    FACTORY,
-    FINAL,
-    GENERATOR,
-    GETTER,
-    HAS_EXT_URI,
-    IMPLICIT_TYPE,
-    MIXIN,
-    MIXIN_APPLICATION,
-    POTENTIALLY_MUTATED_IN_CONTEXT,
-    POTENTIALLY_MUTATED_IN_SCOPE,
-    REFERENCES_SUPER,
-    SETTER,
-    STATIC,
-    SYNTHETIC
-  ];
-
-  const Modifier(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
- * A pseudo-element that represents multiple elements defined within a single
- * scope that have the same name. This situation is not allowed by the language,
- * so objects implementing this interface always represent an error. As a
- * result, most of the normal operations on elements do not make sense and will
- * return useless results.
- */
-abstract class MultiplyDefinedElement implements Element {
-  /**
-   * Return a list containing all of the elements that were defined within the
-   * scope to have the same name.
-   */
-  List<Element> get conflictingElements;
-
-  /**
-   * Return the type of this element as the dynamic type.
-   */
-  DartType get type;
-}
-
-/**
- * A concrete implementation of a [MultiplyDefinedElement].
- */
-class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
-  /**
-   * The unique integer identifier of this element.
-   */
-  final int id = ElementImpl._NEXT_ID++;
-
-  /**
-   * The analysis context in which the multiply defined elements are defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The name of the conflicting elements.
-   */
-  String _name;
-
-  /**
-   * A list containing all of the elements that conflict.
-   */
-  final List<Element> conflictingElements;
-
-  /**
-   * Initialize a newly created element in the given [context] to represent a
-   * list of [conflictingElements].
-   */
-  MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
-    _name = conflictingElements[0].name;
-  }
-
-  @override
-  String get displayName => _name;
-
-  @override
-  SourceRange get docRange => null;
-
-  @override
-  Element get enclosingElement => null;
-
-  @override
-  bool get isDeprecated => false;
-
-  @override
-  bool get isOverride => false;
-
-  @override
-  bool get isPrivate {
-    String name = displayName;
-    if (name == null) {
-      return false;
-    }
-    return Identifier.isPrivateName(name);
-  }
-
-  @override
-  bool get isPublic => !isPrivate;
-
-  @override
-  bool get isSynthetic => true;
-
-  @override
-  ElementKind get kind => ElementKind.ERROR;
-
-  @override
-  LibraryElement get library => null;
-
-  @override
-  ElementLocation get location => null;
-
-  @override
-  List<ElementAnnotation> get metadata => ElementAnnotation.EMPTY_LIST;
-
-  @override
-  String get name => _name;
-
-  @override
-  int get nameLength => displayName != null ? displayName.length : 0;
-
-  @override
-  int get nameOffset => -1;
-
-  @override
-  Source get source => null;
-
-  @override
-  DartType get type => DynamicTypeImpl.instance;
-
-  @override
-  CompilationUnit get unit => null;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitMultiplyDefinedElement(this);
-
-  @override
-  String computeDocumentationComment() => null;
-
-  @override
-  AstNode computeNode() => null;
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) => null;
-
-  @override
-  String getExtendedDisplayName(String shortName) {
-    if (shortName != null) {
-      return shortName;
-    }
-    return displayName;
-  }
-
-  @override
-  bool isAccessibleIn(LibraryElement library) {
-    for (Element element in conflictingElements) {
-      if (element.isAccessibleIn(library)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("[");
-    int count = conflictingElements.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      (conflictingElements[i] as ElementImpl).appendTo(buffer);
-    }
-    buffer.write("]");
-    return buffer.toString();
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // There are no children to visit
-  }
-
-  /**
-   * Return an element in the given [context] that represents the fact that the
-   * [firstElement] and [secondElement] conflict. (If the elements are the same,
-   * then one of the two will be returned directly.)
-   */
-  static Element fromElements(
-      AnalysisContext context, Element firstElement, Element secondElement) {
-    List<Element> conflictingElements =
-        _computeConflictingElements(firstElement, secondElement);
-    int length = conflictingElements.length;
-    if (length == 0) {
-      return null;
-    } else if (length == 1) {
-      return conflictingElements[0];
-    }
-    return new MultiplyDefinedElementImpl(context, conflictingElements);
-  }
-
-  /**
-   * Add the given [element] to the list of [elements]. If the element is a
-   * multiply-defined element, add all of the conflicting elements that it
-   * represents.
-   */
-  static void _add(HashSet<Element> elements, Element element) {
-    if (element is MultiplyDefinedElementImpl) {
-      for (Element conflictingElement in element.conflictingElements) {
-        elements.add(conflictingElement);
-      }
-    } else {
-      elements.add(element);
-    }
-  }
-
-  /**
-   * Use the given elements to construct a list of conflicting elements. If
-   * either the [firstElement] or [secondElement] are multiply-defined elements
-   * then the conflicting elements they represent will be included in the array.
-   * Otherwise, the element itself will be included.
-   */
-  static List<Element> _computeConflictingElements(
-      Element firstElement, Element secondElement) {
-    HashSet<Element> elements = new HashSet<Element>();
-    _add(elements, firstElement);
-    _add(elements, secondElement);
-    return new List.from(elements);
-  }
-}
-
-/**
- * An [ExecutableElement], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
-  /**
-   * Return a list containing all of the executable elements defined within this
-   * executable element.
-   */
-  List<ExecutableElement> get inheritedElements;
-}
-
-/**
- * A [MethodElementImpl], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-class MultiplyInheritedMethodElementImpl extends MethodElementImpl
-    implements MultiplyInheritedExecutableElement {
-  /**
-   * A list the array of executable elements that were used to compose this
-   * element.
-   */
-  List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
-
-  MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
-    synthetic = true;
-  }
-
-  @override
-  List<ExecutableElement> get inheritedElements => _elements;
-
-  void set inheritedElements(List<ExecutableElement> elements) {
-    this._elements = elements;
-  }
-}
-
-/**
- * A [PropertyAccessorElementImpl], with the additional information of a list of
- * [ExecutableElement]s from which this element was composed.
- */
-class MultiplyInheritedPropertyAccessorElementImpl
-    extends PropertyAccessorElementImpl
-    implements MultiplyInheritedExecutableElement {
-  /**
-   * A list the array of executable elements that were used to compose this
-   * element.
-   */
-  List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
-
-  MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
-      : super.forNode(name) {
-    synthetic = true;
-  }
-
-  @override
-  List<ExecutableElement> get inheritedElements => _elements;
-
-  void set inheritedElements(List<ExecutableElement> elements) {
-    this._elements = elements;
-  }
-}
-
-/**
- * An object that controls how namespaces are combined.
- */
-abstract class NamespaceCombinator {
-  /**
-   * An empty list of namespace combinators.
-   */
-  static const List<NamespaceCombinator> EMPTY_LIST =
-      const <NamespaceCombinator>[];
-}
-
-/**
- * A parameter defined within an executable element.
- */
-abstract class ParameterElement
-    implements LocalElement, VariableElement, ConstantEvaluationTarget {
-  /**
-   * An empty list of parameter elements.
-   */
-  static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
-
-  /**
-   * Return the Dart code of the default value, or `null` if no default value.
-   */
-  String get defaultValueCode;
-
-  /**
-   * Return `true` if this parameter is an initializing formal parameter.
-   */
-  bool get isInitializingFormal;
-
-  /**
-   * Return the kind of this parameter.
-   */
-  ParameterKind get parameterKind;
-
-  /**
-   * Return a list containing all of the parameters defined by this parameter.
-   * A parameter will only define other parameters if it is a function typed
-   * parameter.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return a list containing all of the type parameters defined by this
-   * parameter. A parameter will only define other parameters if it is a
-   * function typed parameter.
-   */
-  List<TypeParameterElement> get typeParameters;
-
-  /**
-   * Append the type, name and possibly the default value of this parameter to
-   * the given [buffer].
-   */
-  void appendToWithoutDelimiters(StringBuffer buffer);
-
-  @override
-  FormalParameter computeNode();
-}
-
-/**
- * A concrete implementation of a [ParameterElement].
- */
-class ParameterElementImpl extends VariableElementImpl
-    with ParameterElementMixin
-    implements ParameterElement {
-  /**
-   * A list containing all of the parameters defined by this parameter element.
-   * There will only be parameters if this parameter is a function typed
-   * parameter.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the type parameters defined for this parameter
-   * element. There will only be parameters if this parameter is a function
-   * typed parameter.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
-   * The kind of this parameter.
-   */
-  ParameterKind parameterKind;
-
-  /**
-   * The Dart code of the default value.
-   */
-  String _defaultValueCode;
-
-  /**
-   * The offset to the beginning of the visible range for this element.
-   */
-  int _visibleRangeOffset = 0;
-
-  /**
-   * The length of the visible range for this element, or `-1` if this element
-   * does not have a visible range.
-   */
-  int _visibleRangeLength = -1;
-
-  /**
-   * Initialize a newly created parameter element to have the given [name] and
-   * [offset].
-   */
-  ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created parameter element to have the given [name].
-   */
-  ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  String get defaultValueCode => _defaultValueCode;
-
-  /**
-   * Set Dart code of the default value.
-   */
-  void set defaultValueCode(String defaultValueCode) {
-    this._defaultValueCode = StringUtilities.intern(defaultValueCode);
-  }
-
-  @override
-  bool get isInitializingFormal => false;
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
-
-  @override
-  ElementKind get kind => ElementKind.PARAMETER;
-
-  @override
-  List<ParameterElement> get parameters => _parameters;
-
-  /**
-   * Set the parameters defined by this executable element to the given
-   * [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement = this;
-    }
-    this._parameters = parameters;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined by this parameter element to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement parameter in typeParameters) {
-      (parameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
-  }
-
-  @override
-  SourceRange get visibleRange {
-    if (_visibleRangeLength < 0) {
-      return null;
-    }
-    return new SourceRange(_visibleRangeOffset, _visibleRangeLength);
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    String left = "";
-    String right = "";
-    while (true) {
-      if (parameterKind == ParameterKind.NAMED) {
-        left = "{";
-        right = "}";
-      } else if (parameterKind == ParameterKind.POSITIONAL) {
-        left = "[";
-        right = "]";
-      } else if (parameterKind == ParameterKind.REQUIRED) {}
-      break;
-    }
-    buffer.write(left);
-    appendToWithoutDelimiters(buffer);
-    buffer.write(right);
-  }
-
-  @override
-  FormalParameter computeNode() =>
-      getNodeMatching((node) => node is FormalParameter);
-
-  @override
-  ElementImpl getChild(String identifier) {
-    for (ParameterElement parameter in _parameters) {
-      if ((parameter as ParameterElementImpl).identifier == identifier) {
-        return parameter as ParameterElementImpl;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
-   * Set the visible range for this element to the range starting at the given
-   * [offset] with the given [length].
-   */
-  void setVisibleRange(int offset, int length) {
-    _visibleRangeOffset = offset;
-    _visibleRangeLength = length;
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_parameters, visitor);
-  }
-}
-
-/**
- * A mixin that provides a common implementation for methods defined in
- * [ParameterElement].
- */
-abstract class ParameterElementMixin implements ParameterElement {
-  @override
-  void appendToWithoutDelimiters(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-    if (defaultValueCode != null) {
-      if (parameterKind == ParameterKind.NAMED) {
-        buffer.write(": ");
-      }
-      if (parameterKind == ParameterKind.POSITIONAL) {
-        buffer.write(" = ");
-      }
-      buffer.write(defaultValueCode);
-    }
-  }
-}
-
-/**
- * A type with type parameters, such as a class or function type alias.
- */
-abstract class ParameterizedType implements DartType {
-  /**
-   * Return a list containing the actual types of the type arguments. If this
-   * type's element does not have type parameters, then the array should be
-   * empty (although it is possible for type arguments to be erroneously
-   * declared). If the element has type parameters and the actual type does not
-   * explicitly include argument values, then the type "dynamic" will be
-   * automatically provided.
-   */
-  List<DartType> get typeArguments;
-
-  /**
-   * Return a list containing all of the type parameters declared for this type.
-   */
-  List<TypeParameterElement> get typeParameters;
-}
-
-/**
- * A parameter element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-class ParameterMember extends VariableMember
-    with ParameterElementMixin
-    implements ParameterElement {
-  /**
-   * Initialize a newly created element to represent a parameter, based on the
-   * [baseElement], defined by the [definingType]. If [type] is passed it will
-   * represent the already substituted type.
-   */
-  ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
-      [DartType type])
-      : super._(baseElement, definingType, type);
-
-  @override
-  ParameterElement get baseElement => super.baseElement as ParameterElement;
-
-  @override
-  String get defaultValueCode => baseElement.defaultValueCode;
-
-  @override
-  Element get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  int get hashCode => baseElement.hashCode;
-
-  @override
-  bool get isInitializingFormal => baseElement.isInitializingFormal;
-
-  @override
-  ParameterKind get parameterKind => baseElement.parameterKind;
-
-  @override
-  List<ParameterElement> get parameters {
-    DartType type = this.type;
-    if (type is FunctionType) {
-      return type.parameters;
-    }
-    return ParameterElement.EMPTY_LIST;
-  }
-
-  @override
-  List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
-
-  @override
-  SourceRange get visibleRange => baseElement.visibleRange;
-
-  // TODO(jmesserly): this equality is broken. It should consider the defining
-  // type as well, otherwise we're dropping the substitution.
-  @override
-  bool operator ==(Object object) =>
-      object is ParameterMember && baseElement == object.baseElement;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitParameterElement(this);
-
-  @override
-  FormalParameter computeNode() => baseElement.computeNode();
-
-  @override
-  Element getAncestor(Predicate<Element> predicate) {
-    Element element = baseElement.getAncestor(predicate);
-    ParameterizedType definingType = this.definingType;
-    if (definingType is InterfaceType) {
-      InterfaceType definingInterfaceType = definingType;
-      if (element is ConstructorElement) {
-        return ConstructorMember.from(element, definingInterfaceType);
-      } else if (element is MethodElement) {
-        return MethodMember.from(element, definingInterfaceType);
-      } else if (element is PropertyAccessorElement) {
-        return PropertyAccessorMember.from(element, definingInterfaceType);
-      }
-    }
-    return element;
-  }
-
-  @override
-  String toString() {
-    ParameterElement baseElement = this.baseElement;
-    String left = "";
-    String right = "";
-    while (true) {
-      if (baseElement.parameterKind == ParameterKind.NAMED) {
-        left = "{";
-        right = "}";
-      } else if (baseElement.parameterKind == ParameterKind.POSITIONAL) {
-        left = "[";
-        right = "]";
-      } else if (baseElement.parameterKind == ParameterKind.REQUIRED) {}
-      break;
-    }
-    return '$left$type ${baseElement.displayName}$right';
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(parameters, visitor);
-  }
-
-  /**
-   * If the given [parameter]'s type is different when any type parameters from
-   * the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create a parameter member representing
-   * the given parameter. Return the member that was created, or the base
-   * parameter if no member was created.
-   */
-  static ParameterElement from(
-      ParameterElement parameter, ParameterizedType definingType) {
-    if (parameter == null || definingType.typeArguments.length == 0) {
-      return parameter;
-    }
-    // Check if parameter type depends on defining type type arguments.
-    // It is possible that we did not resolve field formal parameter yet,
-    // so skip this check for it.
-    if (parameter is FieldFormalParameterElement) {
-      return new FieldFormalParameterMember(parameter, definingType);
-    } else {
-      DartType baseType = parameter.type;
-      List<DartType> argumentTypes = definingType.typeArguments;
-      List<DartType> parameterTypes =
-          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
-      DartType substitutedType =
-          baseType.substitute2(argumentTypes, parameterTypes);
-      if (baseType == substitutedType) {
-        return parameter;
-      }
-      return new ParameterMember(parameter, definingType, substitutedType);
-    }
-  }
-}
-
-/**
- * A prefix used to import one or more libraries into another library.
- */
-abstract class PrefixElement implements Element {
-  /**
-   * An empty list of prefix elements.
-   */
-  static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
-
-  /**
-   * Return the library into which other libraries are imported using this
-   * prefix.
-   */
-  @override
-  LibraryElement get enclosingElement;
-
-  /**
-   * Return a list containing all of the libraries that are imported using this
-   * prefix.
-   */
-  List<LibraryElement> get importedLibraries;
-}
-
-/**
- * A concrete implementation of a [PrefixElement].
- */
-class PrefixElementImpl extends ElementImpl implements PrefixElement {
-  /**
-   * A list containing all of the libraries that are imported using this prefix.
-   */
-  List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
-
-  /**
-   * Initialize a newly created prefix element to have the given [name].
-   */
-  PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  LibraryElement get enclosingElement =>
-      super.enclosingElement as LibraryElement;
-
-  @override
-  String get identifier => "_${super.identifier}";
-
-  @override
-  List<LibraryElement> get importedLibraries => _importedLibraries;
-
-  /**
-   * Set the libraries that are imported using this prefix to the given
-   * [libraries].
-   */
-  void set importedLibraries(List<LibraryElement> libraries) {
-    for (LibraryElement library in libraries) {
-      (library as LibraryElementImpl).enclosingElement = this;
-    }
-    _importedLibraries = libraries;
-  }
-
-  @override
-  ElementKind get kind => ElementKind.PREFIX;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write("as ");
-    super.appendTo(buffer);
-  }
-}
-
-/**
- * A getter or a setter. Note that explicitly defined property accessors
- * implicitly define a synthetic field. Symmetrically, synthetic accessors are
- * implicitly created for explicitly defined fields. The following rules apply:
- *
- * * Every explicit field is represented by a non-synthetic [FieldElement].
- * * Every explicit field induces a getter and possibly a setter, both of which
- *   are represented by synthetic [PropertyAccessorElement]s.
- * * Every explicit getter or setter is represented by a non-synthetic
- *   [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same
- *   name) induces a field that is represented by a synthetic [FieldElement].
- */
-abstract class PropertyAccessorElement implements ExecutableElement {
-  /**
-   * An empty list of property accessor elements.
-   */
-  static const List<PropertyAccessorElement> EMPTY_LIST =
-      const <PropertyAccessorElement>[];
-
-  /**
-   * Return the accessor representing the getter that corresponds to (has the
-   * same name as) this setter, or `null` if this accessor is not a setter or if
-   * there is no corresponding getter.
-   */
-  PropertyAccessorElement get correspondingGetter;
-
-  /**
-   * Return the accessor representing the setter that corresponds to (has the
-   * same name as) this getter, or `null` if this accessor is not a getter or if
-   * there is no corresponding setter.
-   */
-  PropertyAccessorElement get correspondingSetter;
-
-  /**
-   * Return `true` if this accessor represents a getter.
-   */
-  bool get isGetter;
-
-  /**
-   * Return `true` if this accessor represents a setter.
-   */
-  bool get isSetter;
-
-  /**
-   * Return the field or top-level variable associated with this accessor. If
-   * this accessor was explicitly defined (is not synthetic) then the variable
-   * associated with it will be synthetic.
-   */
-  PropertyInducingElement get variable;
-}
-
-/**
- * A concrete implementation of a [PropertyAccessorElement].
- */
-class PropertyAccessorElementImpl extends ExecutableElementImpl
-    implements PropertyAccessorElement {
-  /**
-   * The variable associated with this accessor.
-   */
-  PropertyInducingElement variable;
-
-  /**
-   * Initialize a newly created property accessor element to have the given
-   * [name].
-   */
-  PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created synthetic property accessor element to be
-   * associated with the given [variable].
-   */
-  PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
-      : super(variable.name, variable.nameOffset) {
-    this.variable = variable;
-    static = variable.isStatic;
-    synthetic = true;
-  }
-
-  /**
-   * Set whether this accessor is abstract.
-   */
-  void set abstract(bool isAbstract) {
-    setModifier(Modifier.ABSTRACT, isAbstract);
-  }
-
-  @override
-  PropertyAccessorElement get correspondingGetter {
-    if (isGetter || variable == null) {
-      return null;
-    }
-    return variable.getter;
-  }
-
-  @override
-  PropertyAccessorElement get correspondingSetter {
-    if (isSetter || variable == null) {
-      return null;
-    }
-    return variable.setter;
-  }
-
-  /**
-   * Set whether this accessor is a getter.
-   */
-  void set getter(bool isGetter) {
-    setModifier(Modifier.GETTER, isGetter);
-  }
-
-  @override
-  int get hashCode => JenkinsSmiHash.hash2(super.hashCode, isGetter ? 1 : 2);
-
-  @override
-  String get identifier {
-    String name = displayName;
-    String suffix = isGetter ? "?" : "=";
-    return "$name$suffix";
-  }
-
-  @override
-  bool get isGetter => hasModifier(Modifier.GETTER);
-
-  @override
-  bool get isSetter => hasModifier(Modifier.SETTER);
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  ElementKind get kind {
-    if (isGetter) {
-      return ElementKind.GETTER;
-    }
-    return ElementKind.SETTER;
-  }
-
-  @override
-  String get name {
-    if (isSetter) {
-      return "${super.name}=";
-    }
-    return super.name;
-  }
-
-  /**
-   * Set whether this accessor is a setter.
-   */
-  void set setter(bool isSetter) {
-    setModifier(Modifier.SETTER, isSetter);
-  }
-
-  /**
-   * Set whether this accessor is static.
-   */
-  void set static(bool isStatic) {
-    setModifier(Modifier.STATIC, isStatic);
-  }
-
-  @override
-  bool operator ==(Object object) =>
-      super == object &&
-      isGetter == (object as PropertyAccessorElement).isGetter;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(isGetter ? "get " : "set ");
-    buffer.write(variable.displayName);
-    super.appendTo(buffer);
-  }
-
-  @override
-  AstNode computeNode() {
-    if (isSynthetic) {
-      return null;
-    }
-    if (enclosingElement is ClassElement) {
-      return getNodeMatching((node) => node is MethodDeclaration);
-    }
-    if (enclosingElement is CompilationUnitElement) {
-      return getNodeMatching((node) => node is FunctionDeclaration);
-    }
-    return null;
-  }
-}
-
-/**
- * A property accessor element defined in a parameterized type where the values
- * of the type parameters are known.
- */
-class PropertyAccessorMember extends ExecutableMember
-    implements PropertyAccessorElement {
-  /**
-   * Initialize a newly created element to represent a property, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  PropertyAccessorMember(
-      PropertyAccessorElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
-
-  @override
-  PropertyAccessorElement get baseElement =>
-      super.baseElement as PropertyAccessorElement;
-
-  @override
-  PropertyAccessorElement get correspondingGetter =>
-      from(baseElement.correspondingGetter, definingType);
-
-  @override
-  PropertyAccessorElement get correspondingSetter =>
-      from(baseElement.correspondingSetter, definingType);
-
-  @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
-  Element get enclosingElement => baseElement.enclosingElement;
-
-  @override
-  bool get isGetter => baseElement.isGetter;
-
-  @override
-  bool get isSetter => baseElement.isSetter;
-
-  @override
-  PropertyInducingElement get variable {
-    PropertyInducingElement variable = baseElement.variable;
-    if (variable is FieldElement) {
-      return FieldMember.from(variable, definingType);
-    }
-    return variable;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitPropertyAccessorElement(this);
-
-  @override
-  String toString() {
-    PropertyAccessorElement baseElement = this.baseElement;
-    List<ParameterElement> parameters = this.parameters;
-    FunctionType type = this.type;
-    StringBuffer builder = new StringBuffer();
-    if (isGetter) {
-      builder.write("get ");
-    } else {
-      builder.write("set ");
-    }
-    builder.write(baseElement.enclosingElement.displayName);
-    builder.write(".");
-    builder.write(baseElement.displayName);
-    builder.write("(");
-    int parameterCount = parameters.length;
-    for (int i = 0; i < parameterCount; i++) {
-      if (i > 0) {
-        builder.write(", ");
-      }
-      builder.write(parameters[i]);
-    }
-    builder.write(")");
-    if (type != null) {
-      builder.write(Element.RIGHT_ARROW);
-      builder.write(type.returnType);
-    }
-    return builder.toString();
-  }
-
-  /**
-   * If the given [accessor]'s type is different when any type parameters from
-   * the defining type's declaration are replaced with the actual type
-   * arguments from the [definingType], create an accessor member representing
-   * the given accessor. Return the member that was created, or the base
-   * accessor if no member was created.
-   */
-  static PropertyAccessorElement from(
-      PropertyAccessorElement accessor, InterfaceType definingType) {
-    if (!_isChangedByTypeSubstitution(accessor, definingType)) {
-      return accessor;
-    }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new PropertyAccessorMember(accessor, definingType);
-  }
-
-  /**
-   * Determine whether the given property [accessor]'s type is changed when type
-   * parameters from the defining type's declaration are replaced with the
-   * actual type arguments from the [definingType].
-   */
-  static bool _isChangedByTypeSubstitution(
-      PropertyAccessorElement accessor, InterfaceType definingType) {
-    List<DartType> argumentTypes = definingType.typeArguments;
-    if (accessor != null && argumentTypes.length != 0) {
-      FunctionType baseType = accessor.type;
-      if (baseType == null) {
-        AnalysisEngine.instance.logger.logInformation(
-            'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
-        return false;
-      }
-      List<DartType> parameterTypes = definingType.element.type.typeArguments;
-      FunctionType substitutedType =
-          baseType.substitute2(argumentTypes, parameterTypes);
-      if (baseType != substitutedType) {
-        return true;
-      }
-      // If this property accessor is based on a field, that field might have a
-      // propagated type. In which case we need to check whether the propagated
-      // type of the field needs substitution.
-      PropertyInducingElement field = accessor.variable;
-      if (!field.isSynthetic) {
-        DartType baseFieldType = field.propagatedType;
-        if (baseFieldType != null) {
-          DartType substitutedFieldType =
-              baseFieldType.substitute2(argumentTypes, parameterTypes);
-          if (baseFieldType != substitutedFieldType) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-}
-
-/**
- * A variable that has an associated getter and possibly a setter. Note that
- * explicitly defined variables implicitly define a synthetic getter and that
- * non-`final` explicitly defined variables implicitly define a synthetic
- * setter. Symmetrically, synthetic fields are implicitly created for explicitly
- * defined getters and setters. The following rules apply:
- *
- * * Every explicit variable is represented by a non-synthetic
- *   [PropertyInducingElement].
- * * Every explicit variable induces a getter and possibly a setter, both of
- *   which are represented by synthetic [PropertyAccessorElement]s.
- * * Every explicit getter or setter is represented by a non-synthetic
- *   [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same
- *   name) induces a variable that is represented by a synthetic
- *   [PropertyInducingElement].
- */
-abstract class PropertyInducingElement implements VariableElement {
-  /**
-   * An empty list of elements.
-   */
-  static const List<PropertyInducingElement> EMPTY_LIST =
-      const <PropertyInducingElement>[];
-
-  /**
-   * Return the getter associated with this variable. If this variable was
-   * explicitly defined (is not synthetic) then the getter associated with it
-   * will be synthetic.
-   */
-  PropertyAccessorElement get getter;
-
-  /**
-   * Return the propagated type of this variable, or `null` if type propagation
-   * has not been performed, for example because the variable is not final.
-   */
-  DartType get propagatedType;
-
-  /**
-   * Return the setter associated with this variable, or `null` if the variable
-   * is effectively `final` and therefore does not have a setter associated with
-   * it. (This can happen either because the variable is explicitly defined as
-   * being `final` or because the variable is induced by an explicit getter that
-   * does not have a corresponding setter.) If this variable was explicitly
-   * defined (is not synthetic) then the setter associated with it will be
-   * synthetic.
-   */
-  PropertyAccessorElement get setter;
-}
-
-/**
- * A concrete implementation of a [PropertyInducingElement].
- */
-abstract class PropertyInducingElementImpl extends VariableElementImpl
-    implements PropertyInducingElement {
-  /**
-   * The getter associated with this element.
-   */
-  PropertyAccessorElement getter;
-
-  /**
-   * The setter associated with this element, or `null` if the element is
-   * effectively `final` and therefore does not have a setter associated with
-   * it.
-   */
-  PropertyAccessorElement setter;
-
-  /**
-   * The propagated type of this variable, or `null` if type propagation has not
-   * been performed.
-   */
-  DartType propagatedType;
-
-  /**
-   * Initialize a newly created synthetic element to have the given [name] and
-   * [offset].
-   */
-  PropertyInducingElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created element to have the given [name].
-   */
-  PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
-}
-
-/**
- * A visitor that will recursively visit all of the element in an element model.
- * For example, using an instance of this class to visit a
- * [CompilationUnitElement] will also cause all of the types in the compilation
- * unit to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden
- * visit method or must explicitly ask the visited element to visit its
- * children. Failure to do so will cause the children of the visited element to
- * not be visited.
- */
-class RecursiveElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitConstructorElement(ConstructorElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitExportElement(ExportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldElement(FieldElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionElement(FunctionElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitImportElement(ImportElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLabelElement(LabelElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLibraryElement(LibraryElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMethodElement(MethodElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitParameterElement(ParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPrefixElement(PrefixElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-}
-
-/**
- * A combinator that cause some of the names in a namespace to be visible (and
- * the rest hidden) when being imported.
- */
-abstract class ShowElementCombinator implements NamespaceCombinator {
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node.
-   */
-  int get end;
-
-  /**
-   * Return the offset of the 'show' keyword of this element.
-   */
-  int get offset;
-
-  /**
-   * Return a list containing the names that are to be made visible in the
-   * importing library if they are defined in the imported library.
-   */
-  List<String> get shownNames;
-}
-
-/**
- * A concrete implementation of a [ShowElementCombinator].
- */
-class ShowElementCombinatorImpl implements ShowElementCombinator {
-  /**
-   * The names that are to be made visible in the importing library if they are
-   * defined in the imported library.
-   */
-  List<String> shownNames = StringUtilities.EMPTY_ARRAY;
-
-  /**
-   * The offset of the character immediately following the last character of
-   * this node.
-   */
-  int end = -1;
-
-  /**
-   * The offset of the 'show' keyword of this element.
-   */
-  int offset = 0;
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("show ");
-    int count = shownNames.length;
-    for (int i = 0; i < count; i++) {
-      if (i > 0) {
-        buffer.write(", ");
-      }
-      buffer.write(shownNames[i]);
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * A visitor that will do nothing when visiting an element. It is intended to be
- * a superclass for classes that use the visitor pattern primarily as a dispatch
- * mechanism (and hence don't need to recursively visit a whole structure) and
- * that only need to visit a small number of element types.
- */
-class SimpleElementVisitor<R> implements ElementVisitor<R> {
-  @override
-  R visitClassElement(ClassElement element) => null;
-
-  @override
-  R visitCompilationUnitElement(CompilationUnitElement element) => null;
-
-  @override
-  R visitConstructorElement(ConstructorElement element) => null;
-
-  @override
-  R visitExportElement(ExportElement element) => null;
-
-  @override
-  R visitFieldElement(FieldElement element) => null;
-
-  @override
-  R visitFieldFormalParameterElement(FieldFormalParameterElement element) =>
-      null;
-
-  @override
-  R visitFunctionElement(FunctionElement element) => null;
-
-  @override
-  R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
-
-  @override
-  R visitImportElement(ImportElement element) => null;
-
-  @override
-  R visitLabelElement(LabelElement element) => null;
-
-  @override
-  R visitLibraryElement(LibraryElement element) => null;
-
-  @override
-  R visitLocalVariableElement(LocalVariableElement element) => null;
-
-  @override
-  R visitMethodElement(MethodElement element) => null;
-
-  @override
-  R visitMultiplyDefinedElement(MultiplyDefinedElement element) => null;
-
-  @override
-  R visitParameterElement(ParameterElement element) => null;
-
-  @override
-  R visitPrefixElement(PrefixElement element) => null;
-
-  @override
-  R visitPropertyAccessorElement(PropertyAccessorElement element) => null;
-
-  @override
-  R visitTopLevelVariableElement(TopLevelVariableElement element) => null;
-
-  @override
-  R visitTypeParameterElement(TypeParameterElement element) => null;
-}
-
-/**
- * A top-level variable.
- */
-abstract class TopLevelVariableElement implements PropertyInducingElement {
-  /**
-   * An empty list of top-level variable elements.
-   */
-  static const List<TopLevelVariableElement> EMPTY_LIST =
-      const <TopLevelVariableElement>[];
-
-  @override
-  VariableDeclaration computeNode();
-}
-
-/**
- * A concrete implementation of a [TopLevelVariableElement].
- */
-class TopLevelVariableElementImpl extends PropertyInducingElementImpl
-    implements TopLevelVariableElement {
-  /**
-   * Initialize a newly created synthetic top-level variable element to have the
-   * given [name] and [offset].
-   */
-  TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created top-level variable element to have the given
-   * [name].
-   */
-  TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  bool get isStatic => true;
-
-  @override
-  ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitTopLevelVariableElement(this);
-
-  @override
-  VariableDeclaration computeNode() =>
-      getNodeMatching((node) => node is VariableDeclaration);
-}
-
-/**
- * An element that defines a type.
- */
-abstract class TypeDefiningElement implements Element {
-  /**
-   * Return the type defined by this element.
-   */
-  DartType get type;
-}
-
-/**
- * The abstract class `TypeImpl` implements the behavior common to objects
- * representing the declared type of elements in the element model.
- */
-abstract class TypeImpl implements DartType {
-  /**
-   * The element representing the declaration of this type, or `null` if the
-   * type has not, or cannot, be associated with an element.
-   */
-  final Element _element;
-
-  /**
-   * The name of this type, or `null` if the type does not have a name.
-   */
-  final String name;
-
-  /**
-   * Initialize a newly created type to be declared by the given [element] and
-   * to have the given [name].
-   */
-  TypeImpl(this._element, this.name);
-
-  @override
-  String get displayName => name;
-
-  @override
-  Element get element => _element;
-
-  @override
-  bool get isBottom => false;
-
-  @override
-  bool get isDartCoreFunction => false;
-
-  @override
-  bool get isDynamic => false;
-
-  @override
-  bool get isObject => false;
-
-  @override
-  bool get isUndefined => false;
-
-  @override
-  bool get isVoid => false;
-
-  /**
-   * Append a textual representation of this type to the given [buffer]. The set
-   * of [visitedTypes] is used to prevent infinite recusion.
-   */
-  void appendTo(StringBuffer buffer) {
-    if (name == null) {
-      buffer.write("<unnamed type>");
-    } else {
-      buffer.write(name);
-    }
-  }
-
-  /**
-   * Return `true` if this type is assignable to the given [type] (written in
-   * the spec as "T <=> S", where T=[this] and S=[type]).
-   *
-   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
-   * function type aliases that have been expanded so far in the process of
-   * reaching [this] and [type], respectively.  These are used to avoid
-   * infinite regress when analyzing invalid code; since the language spec
-   * forbids a typedef from referring to itself directly or indirectly, we can
-   * use these as sets of function type aliases that don't need to be expanded.
-   */
-  @override
-  bool isAssignableTo(DartType type) {
-    // An interface type T may be assigned to a type S, written T <=> S, iff
-    // either T <: S or S <: T.
-    return isSubtypeOf(type) || (type as TypeImpl).isSubtypeOf(this);
-  }
-
-  /**
-   * Return `true` if this type is more specific than the given [type] (written
-   * in the spec as "T << S", where T=[this] and S=[type]).
-   *
-   * If [withDynamic] is `true`, then "dynamic" should be considered as a
-   * subtype of any type (as though "dynamic" had been replaced with bottom).
-   *
-   * The set [visitedElements], if given, is the set of classes and type
-   * parameters that have been visited so far while examining the class
-   * hierarchy of [this].  This is used to avoid infinite regress when
-   * analyzing invalid code; since the language spec forbids loops in the class
-   * hierarchy, we can use this as a set of classes that don't need to be
-   * examined when walking the class hierarchy.
-   */
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]);
-
-  /**
-   * Return `true` if this type is a subtype of the given [type] (written in
-   * the spec as "T <: S", where T=[this] and S=[type]).
-   *
-   * The sets [thisExpansions] and [typeExpansions], if given, are the sets of
-   * function type aliases that have been expanded so far in the process of
-   * reaching [this] and [type], respectively.  These are used to avoid
-   * infinite regress when analyzing invalid code; since the language spec
-   * forbids a typedef from referring to itself directly or indirectly, we can
-   * use these as sets of function type aliases that don't need to be expanded.
-   */
-  @override
-  bool isSubtypeOf(DartType type) {
-    // For non-function types, T <: S iff [_|_/dynamic]T << S.
-    return isMoreSpecificThan(type, true);
-  }
-
-  @override
-  bool isSupertypeOf(DartType type) => type.isSubtypeOf(this);
-
-  /**
-   * Create a new [TypeImpl] that is identical to [this] except that when
-   * visiting type parameters, function parameter types, and function return
-   * types, function types listed in [prune] will not be expanded.  This is
-   * used to avoid creating infinite types in the presence of circular
-   * typedefs.
-   *
-   * If [prune] is null, then [this] is returned unchanged.
-   *
-   * Only legal to call on a [TypeImpl] that is not already subject to pruning.
-   */
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune);
-
-  /**
-   * Return the type resulting from substituting the given [argumentTypes] for
-   * the given [parameterTypes] in this type.
-   *
-   * In all classes derived from [TypeImpl], a new optional argument
-   * [prune] is added.  If specified, it is a list of function typdefs
-   * which should not be expanded.  This is used to avoid creating infinite
-   * types in response to self-referential typedefs.
-   */
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]);
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    appendTo(buffer);
-    return buffer.toString();
-  }
-
-  /**
-   * Return `true` if corresponding elements of the [first] and [second] lists
-   * of type arguments are all equal.
-   */
-  static bool equalArrays(List<DartType> first, List<DartType> second) {
-    if (first.length != second.length) {
-      return false;
-    }
-    for (int i = 0; i < first.length; i++) {
-      if (first[i] == null) {
-        AnalysisEngine.instance.logger
-            .logInformation('Found null type argument in TypeImpl.equalArrays');
-        return second[i] == null;
-      } else if (second[i] == null) {
-        AnalysisEngine.instance.logger
-            .logInformation('Found null type argument in TypeImpl.equalArrays');
-        return false;
-      }
-      if (first[i] != second[i]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return a list containing the results of using the given [argumentTypes] and
-   * [parameterTypes] to perform a substitution on all of the given [types].
-   *
-   * If [prune] is specified, it is a list of function typdefs which should not
-   * be expanded.  This is used to avoid creating infinite types in response to
-   * self-referential typedefs.
-   */
-  static List<DartType> substitute(List<DartType> types,
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = types.length;
-    if (length == 0) {
-      return types;
-    }
-    List<DartType> newTypes = new List<DartType>(length);
-    for (int i = 0; i < length; i++) {
-      newTypes[i] = (types[i] as TypeImpl)
-          .substitute2(argumentTypes, parameterTypes, prune);
-    }
-    return newTypes;
-  }
-}
-
-/**
- * A type parameter.
- */
-abstract class TypeParameterElement implements TypeDefiningElement {
-  /**
-   * An empty list of type parameter elements.
-   */
-  static const List<TypeParameterElement> EMPTY_LIST =
-      const <TypeParameterElement>[];
-
-  /**
-   * Return the type representing the bound associated with this parameter, or
-   * `null` if this parameter does not have an explicit bound.
-   */
-  DartType get bound;
-
-  /**
-   * Return the type defined by this type parameter.
-   */
-  TypeParameterType get type;
-}
-
-/**
- * A concrete implementation of a [TypeParameterElement].
- */
-class TypeParameterElementImpl extends ElementImpl
-    implements TypeParameterElement {
-  /**
-   * The type defined by this type parameter.
-   */
-  TypeParameterType type;
-
-  /**
-   * The type representing the bound associated with this parameter, or `null`
-   * if this parameter does not have an explicit bound.
-   */
-  DartType bound;
-
-  /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
-   */
-  TypeParameterElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created type parameter element to have the given [name].
-   */
-  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  @override
-  ElementKind get kind => ElementKind.TYPE_PARAMETER;
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitTypeParameterElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(displayName);
-    if (bound != null) {
-      buffer.write(" extends ");
-      buffer.write(bound);
-    }
-  }
-}
-
-/**
- * An element that has type parameters.
- *
- * For example, a class or a typedef. This also includes functions and methods
- * if support for generic methods is enabled.
- */
-abstract class TypeParameterizedElement implements Element {
-  /**
-   * Return a list containing all of the type parameters declared for this
-   * class.
-   */
-  List<TypeParameterElement> get typeParameters;
-}
-
-/**
- * The type introduced by a type parameter.
- */
-abstract class TypeParameterType implements DartType {
-  /**
-   * An empty list of type parameter types.
-   */
-  static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
-
-  @override
-  TypeParameterElement get element;
-}
-
-/**
- * A concrete implementation of a [TypeParameterType].
- */
-class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
-  /**
-   * Initialize a newly created type parameter type to be declared by the given
-   * [element] and to have the given name.
-   */
-  TypeParameterTypeImpl(TypeParameterElement element)
-      : super(element, element.name);
-
-  @override
-  TypeParameterElement get element => super.element as TypeParameterElement;
-
-  @override
-  int get hashCode => element.hashCode;
-
-  @override
-  bool operator ==(Object object) =>
-      object is TypeParameterTypeImpl && (element == object.element);
-
-  @override
-  bool isMoreSpecificThan(DartType s,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    //
-    // A type T is more specific than a type S, written T << S,
-    // if one of the following conditions is met:
-    //
-    // Reflexivity: T is S.
-    //
-    if (this == s) {
-      return true;
-    }
-    // S is dynamic.
-    //
-    if (s.isDynamic) {
-      return true;
-    }
-    //
-    // T is a type parameter and S is the upper bound of T.
-    //
-    TypeImpl bound = element.bound;
-    if (s == bound) {
-      return true;
-    }
-    //
-    // T is a type parameter and S is Object.
-    //
-    if (s.isObject) {
-      return true;
-    }
-    // We need upper bound to continue.
-    if (bound == null) {
-      return false;
-    }
-    //
-    // Transitivity: T << U and U << S.
-    //
-    // First check for infinite loops
-    if (element == null) {
-      return false;
-    }
-    if (visitedElements == null) {
-      visitedElements = new HashSet<Element>();
-    } else if (visitedElements.contains(element)) {
-      return false;
-    }
-    visitedElements.add(element);
-    try {
-      return bound.isMoreSpecificThan(s, withDynamic, visitedElements);
-    } finally {
-      visitedElements.remove(element);
-    }
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => isMoreSpecificThan(type, true);
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-
-  /**
-   * Return a list containing the type parameter types defined by the given
-   * array of type parameter elements ([typeParameters]).
-   */
-  static List<TypeParameterType> getTypes(
-      List<TypeParameterElement> typeParameters) {
-    int count = typeParameters.length;
-    if (count == 0) {
-      return TypeParameterType.EMPTY_LIST;
-    }
-    List<TypeParameterType> types = new List<TypeParameterType>(count);
-    for (int i = 0; i < count; i++) {
-      types[i] = typeParameters[i].type;
-    }
-    return types;
-  }
-}
-
-/**
- * A pseudo-elements that represents names that are undefined. This situation is
- * not allowed by the language, so objects implementing this interface always
- * represent an error. As a result, most of the normal operations on elements do
- * not make sense and will return useless results.
- */
-abstract class UndefinedElement implements Element {}
-
-/**
- * The unique instance of the class `UndefinedTypeImpl` implements the type of
- * typenames that couldn't be resolved.
- *
- * This class behaves like DynamicTypeImpl in almost every respect, to reduce
- * cascading errors.
- */
-class UndefinedTypeImpl extends TypeImpl {
-  /**
-   * The unique instance of this class.
-   */
-  static UndefinedTypeImpl _INSTANCE = new UndefinedTypeImpl._();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static UndefinedTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  UndefinedTypeImpl._()
-      : super(DynamicElementImpl.instance, Keyword.DYNAMIC.syntax);
-
-  @override
-  int get hashCode => 1;
-
-  @override
-  bool get isDynamic => true;
-
-  @override
-  bool get isUndefined => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) {
-    // T is S
-    if (identical(this, type)) {
-      return true;
-    }
-    // else
-    return withDynamic;
-  }
-
-  @override
-  bool isSubtypeOf(DartType type) => true;
-
-  @override
-  bool isSupertypeOf(DartType type) => true;
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  DartType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) {
-    int length = parameterTypes.length;
-    for (int i = 0; i < length; i++) {
-      if (parameterTypes[i] == this) {
-        return argumentTypes[i];
-      }
-    }
-    return this;
-  }
-}
-
-/**
- * An element included into a library using some URI.
- */
-abstract class UriReferencedElement implements Element {
-  /**
-   * Return the URI that is used to include this element into the enclosing
-   * library, or `null` if this is the defining compilation unit of a library.
-   */
-  String get uri;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node's URI, or `-1` for synthetic import.
-   */
-  int get uriEnd;
-
-  /**
-   * Return the offset of the URI in the file, or `-1` if this element is
-   * synthetic.
-   */
-  int get uriOffset;
-}
-
-/**
- * A concrete implementation of a [UriReferencedElement].
- */
-abstract class UriReferencedElementImpl extends ElementImpl
-    implements UriReferencedElement {
-  /**
-   * The offset of the URI in the file, may be `-1` if synthetic.
-   */
-  int uriOffset = -1;
-
-  /**
-   * The offset of the character immediately following the last character of
-   * this node's URI, may be `-1` if synthetic.
-   */
-  int uriEnd = -1;
-
-  /**
-   * The URI that is specified by this directive.
-   */
-  String uri;
-
-  /**
-   * Initialize a newly created import element to heve the given [name] and
-   * [offset]. The offset may be `-1` if the element is synthetic.
-   */
-  UriReferencedElementImpl(String name, int offset) : super(name, offset);
-}
-
-/**
- * A variable. There are concrete subclasses for different kinds of variables.
- */
-abstract class VariableElement implements Element, ConstantEvaluationTarget {
-  /**
-   * An empty list of variable elements.
-   */
-  static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
-
-  /**
-   * Return a representation of the value of this variable.
-   *
-   * Return `null` if either this variable was not declared with the 'const'
-   * modifier or if the value of this variable could not be computed because of
-   * errors.
-   */
-  DartObject get constantValue;
-
-  /**
-   * Return `true` if this variable element did not have an explicit type
-   * specified for it.
-   */
-  bool get hasImplicitType;
-
-  /**
-   * Return a synthetic function representing this variable's initializer, or
-   * `null` if this variable does not have an initializer. The function will
-   * have no parameters. The return type of the function will be the
-   * compile-time type of the initialization expression.
-   */
-  FunctionElement get initializer;
-
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
-  bool get isConst;
-
-  /**
-   * Return `true` if this variable was declared with the 'final' modifier.
-   * Variables that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
-  bool get isFinal;
-
-  /**
-   * Return `true` if this variable is potentially mutated somewhere in a
-   * closure. This information is only available for local variables (including
-   * parameters) and only after the compilation unit containing the variable has
-   * been resolved.
-   */
-  bool get isPotentiallyMutatedInClosure;
-
-  /**
-   * Return `true` if this variable is potentially mutated somewhere in its
-   * scope. This information is only available for local variables (including
-   * parameters) and only after the compilation unit containing the variable has
-   * been resolved.
-   */
-  bool get isPotentiallyMutatedInScope;
-
-  /**
-   * Return `true` if this element is a static variable, as per section 8 of the
-   * Dart Language Specification:
-   *
-   * > A static variable is a variable that is not associated with a particular
-   * > instance, but rather with an entire library or class. Static variables
-   * > include library variables and class variables. Class variables are
-   * > variables whose declaration is immediately nested inside a class
-   * > declaration and includes the modifier static. A library variable is
-   * > implicitly static.
-   */
-  bool get isStatic;
-
-  /**
-   * Return the declared type of this variable, or `null` if the variable did
-   * not have a declared type (such as if it was declared using the keyword
-   * 'var').
-   */
-  DartType get type;
-}
-
-/**
- * A concrete implementation of a [VariableElement].
- */
-abstract class VariableElementImpl extends ElementImpl
-    implements VariableElement {
-  /**
-   * The declared type of this variable.
-   */
-  DartType type;
-
-  /**
-   * A synthetic function representing this variable's initializer, or `null` if
-   * this variable does not have an initializer.
-   */
-  FunctionElement _initializer;
-
-  /**
-   * Initialize a newly created variable element to have the given [name] and
-   * [offset].
-   */
-  VariableElementImpl(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created variable element to have the given [name].
-   */
-  VariableElementImpl.forNode(Identifier name) : super.forNode(name);
-
-  /**
-   * Set whether this variable is const.
-   */
-  void set const3(bool isConst) {
-    setModifier(Modifier.CONST, isConst);
-  }
-
-  /**
-   * If this element represents a constant variable, and it has an initializer,
-   * a copy of the initializer for the constant.  Otherwise `null`.
-   *
-   * Note that in correct Dart code, all constant variables must have
-   * initializers.  However, analyzer also needs to handle incorrect Dart code,
-   * in which case there might be some constant variables that lack
-   * initializers.
-   */
-  Expression get constantInitializer => null;
-
-  @override
-  DartObject get constantValue => null;
-
-  /**
-   * Return the result of evaluating this variable's initializer as a
-   * compile-time constant expression, or `null` if this variable is not a
-   * 'const' variable, if it does not have an initializer, or if the compilation
-   * unit containing the variable has not been resolved.
-   */
-  EvaluationResultImpl get evaluationResult => null;
-
-  /**
-   * Set the result of evaluating this variable's initializer as a compile-time
-   * constant expression to the given [result].
-   */
-  void set evaluationResult(EvaluationResultImpl result) {
-    throw new IllegalStateException(
-        "Invalid attempt to set a compile-time constant result");
-  }
-
-  /**
-   * Set whether this variable is final.
-   */
-  void set final2(bool isFinal) {
-    setModifier(Modifier.FINAL, isFinal);
-  }
-
-  @override
-  bool get hasImplicitType => hasModifier(Modifier.IMPLICIT_TYPE);
-
-  /**
-   * Set whether this variable element has an implicit type.
-   */
-  void set hasImplicitType(bool hasImplicitType) {
-    setModifier(Modifier.IMPLICIT_TYPE, hasImplicitType);
-  }
-
-  @override
-  FunctionElement get initializer => _initializer;
-
-  /**
-   * Set the function representing this variable's initializer to the given
-   * [function].
-   */
-  void set initializer(FunctionElement function) {
-    if (function != null) {
-      (function as FunctionElementImpl).enclosingElement = this;
-    }
-    this._initializer = function;
-  }
-
-  @override
-  bool get isConst => hasModifier(Modifier.CONST);
-
-  @override
-  bool get isFinal => hasModifier(Modifier.FINAL);
-
-  @override
-  bool get isPotentiallyMutatedInClosure => false;
-
-  @override
-  bool get isPotentiallyMutatedInScope => false;
-
-  @override
-  bool get isStatic => hasModifier(Modifier.STATIC);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    buffer.write(type);
-    buffer.write(" ");
-    buffer.write(displayName);
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChild(_initializer, visitor);
-  }
-}
-
-/**
- * A variable element defined in a parameterized type where the values of the
- * type parameters are known.
- */
-abstract class VariableMember extends Member implements VariableElement {
-  @override
-  final DartType type;
-
-  /**
-   * Initialize a newly created element to represent a variable, based on the
-   * [baseElement], defined by the [definingType].
-   */
-  VariableMember(VariableElement baseElement, ParameterizedType definingType,
-      [DartType type])
-      : type = type ??
-            baseElement.type.substitute2(definingType.typeArguments,
-                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
-        super(baseElement, definingType);
-
-  // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
-  // Apparently mixins don't work with optional params.
-  VariableMember._(VariableElement baseElement, ParameterizedType definingType,
-      DartType type)
-      : this(baseElement, definingType, type);
-
-  @override
-  VariableElement get baseElement => super.baseElement as VariableElement;
-
-  @override
-  DartObject get constantValue => baseElement.constantValue;
-
-  @override
-  bool get hasImplicitType => baseElement.hasImplicitType;
-
-  @override
-  FunctionElement get initializer {
-    //
-    // Elements within this element should have type parameters substituted,
-    // just like this element.
-    //
-    throw new UnsupportedOperationException();
-    //    return getBaseElement().getInitializer();
-  }
-
-  @override
-  bool get isConst => baseElement.isConst;
-
-  @override
-  bool get isFinal => baseElement.isFinal;
-
-  @override
-  bool get isPotentiallyMutatedInClosure =>
-      baseElement.isPotentiallyMutatedInClosure;
-
-  @override
-  bool get isPotentiallyMutatedInScope =>
-      baseElement.isPotentiallyMutatedInScope;
-
-  @override
-  bool get isStatic => baseElement.isStatic;
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    // TODO(brianwilkerson) We need to finish implementing the accessors used
-    // below so that we can safely invoke them.
-    super.visitChildren(visitor);
-    safelyVisitChild(baseElement.initializer, visitor);
-  }
-}
-
-/**
- * The type `void`.
- */
-abstract class VoidType implements DartType {
-  @override
-  VoidType substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes);
-}
-
-/**
- * A concrete implementation of a [VoidType].
- */
-class VoidTypeImpl extends TypeImpl implements VoidType {
-  /**
-   * The unique instance of this class.
-   */
-  static VoidTypeImpl _INSTANCE = new VoidTypeImpl();
-
-  /**
-   * Return the unique instance of this class.
-   */
-  static VoidTypeImpl get instance => _INSTANCE;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  VoidTypeImpl() : super(null, Keyword.VOID.syntax);
-
-  @override
-  int get hashCode => 2;
-
-  @override
-  bool get isVoid => true;
-
-  @override
-  bool operator ==(Object object) => identical(object, this);
-
-  @override
-  bool isMoreSpecificThan(DartType type,
-          [bool withDynamic = false, Set<Element> visitedElements]) =>
-      isSubtypeOf(type);
-
-  @override
-  bool isSubtypeOf(DartType type) {
-    // The only subtype relations that pertain to void are therefore:
-    // void <: void (by reflexivity)
-    // bottom <: void (as bottom is a subtype of all types).
-    // void <: dynamic (as dynamic is a supertype of all types)
-    return identical(type, this) || type.isDynamic;
-  }
-
-  @override
-  TypeImpl pruned(List<FunctionTypeAliasElement> prune) => this;
-
-  @override
-  VoidTypeImpl substitute2(
-          List<DartType> argumentTypes, List<DartType> parameterTypes,
-          [List<FunctionTypeAliasElement> prune]) =>
-      this;
-}
-
-/**
- * A visitor that visit all the elements recursively and fill the given [map].
- */
-class _BuildOffsetToElementMap extends GeneralizingElementVisitor {
-  final Map<int, Element> map;
-
-  _BuildOffsetToElementMap(this.map);
-
-  @override
-  void visitElement(Element element) {
-    int offset = element.nameOffset;
-    if (offset != -1) {
-      map[offset] = element;
-    }
-    super.visitElement(element);
-  }
-}
+export 'package:analyzer/dart/element/element.dart';
+export 'package:analyzer/dart/element/type.dart';
+export 'package:analyzer/dart/element/visitor.dart';
+export 'package:analyzer/src/dart/element/element.dart';
+export 'package:analyzer/src/dart/element/member.dart';
+export 'package:analyzer/src/dart/element/type.dart';
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index 09e23c0..f36d436 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -4,11 +4,12 @@
 
 library analyzer.src.generated.element_handle;
 
+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/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.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/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -23,7 +24,9 @@
    *
    * @param element the element being represented
    */
-  ClassElementHandle(ClassElement element) : super(element);
+  ClassElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   List<PropertyAccessorElement> get accessors => actualElement.accessors;
@@ -165,7 +168,9 @@
    *
    * @param element the element being represented
    */
-  CompilationUnitElementHandle(CompilationUnitElement element) : super(element);
+  CompilationUnitElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   List<PropertyAccessorElement> get accessors => actualElement.accessors;
@@ -239,7 +244,9 @@
    *
    * @param element the element being represented
    */
-  ConstructorElementHandle(ConstructorElement element) : super(element);
+  ConstructorElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ConstructorElement get actualElement =>
@@ -285,32 +292,29 @@
   final int id = 0;
 
   /**
-   * The context in which the element is defined.
+   * The [ElementResynthesizer] which will be used to resynthesize elements on
+   * demand.
    */
-  AnalysisContext _context;
+  final ElementResynthesizer _resynthesizer;
 
   /**
    * The location of this element, used to reconstitute the element if it has been garbage
    * collected.
    */
-  ElementLocation _location;
+  final ElementLocation _location;
 
   /**
    * A reference to the element being referenced by this handle, or `null` if the element has
    * been garbage collected.
    */
-  WeakReference<Element> _elementReference;
+  Element _elementReference;
 
   /**
-   * Initialize a newly created element handle to represent the given element.
-   *
-   * @param element the element being represented
+   * Initialize a newly created element handle to represent the element at the
+   * given [_location].  [_resynthesizer] will be used to resynthesize the
+   * element when needed.
    */
-  ElementHandle(Element element) {
-    _context = element.context;
-    _location = element.location;
-    _elementReference = new WeakReference<Element>(element);
-  }
+  ElementHandle(this._resynthesizer, this._location);
 
   /**
    * Return the element being represented by this handle, reconstituting the element if the
@@ -319,16 +323,14 @@
    * @return the element being represented by this handle
    */
   Element get actualElement {
-    Element element = _elementReference.get();
-    if (element == null) {
-      element = _context.getElement(_location);
-      _elementReference = new WeakReference<Element>(element);
+    if (_elementReference == null) {
+      _elementReference = _resynthesizer.getElement(_location);
     }
-    return element;
+    return _elementReference;
   }
 
   @override
-  AnalysisContext get context => _context;
+  AnalysisContext get context => _resynthesizer.context;
 
   @override
   String get displayName => actualElement.displayName;
@@ -337,6 +339,9 @@
   SourceRange get docRange => actualElement.docRange;
 
   @override
+  String get documentationComment => actualElement.documentationComment;
+
+  @override
   Element get enclosingElement => actualElement.enclosingElement;
 
   @override
@@ -390,8 +395,7 @@
   accept(ElementVisitor visitor) => actualElement.accept(visitor);
 
   @override
-  String computeDocumentationComment() =>
-      actualElement.computeDocumentationComment();
+  String computeDocumentationComment() => documentationComment;
 
   @override
   AstNode computeNode() => actualElement.computeNode();
@@ -412,82 +416,19 @@
   void visitChildren(ElementVisitor visitor) {
     actualElement.visitChildren(visitor);
   }
+}
 
-  /**
-   * Return a handle on the given element. If the element is already a handle, then it will be
-   * returned directly, otherwise a handle of the appropriate class will be constructed.
-   *
-   * @param element the element for which a handle is to be constructed
-   * @return a handle on the given element
-   */
-  static Element forElement(Element element) {
-    if (element is ElementHandle) {
-      return element;
-    }
-    while (true) {
-      if (element.kind == ElementKind.CLASS) {
-        return new ClassElementHandle(element as ClassElement);
-      } else if (element.kind == ElementKind.COMPILATION_UNIT) {
-        return new CompilationUnitElementHandle(
-            element as CompilationUnitElement);
-      } else if (element.kind == ElementKind.CONSTRUCTOR) {
-        return new ConstructorElementHandle(element as ConstructorElement);
-      } else if (element.kind == ElementKind.EXPORT) {
-        return new ExportElementHandle(element as ExportElement);
-      } else if (element.kind == ElementKind.FIELD) {
-        return new FieldElementHandle(element as FieldElement);
-      } else if (element.kind == ElementKind.FUNCTION) {
-        return new FunctionElementHandle(element as FunctionElement);
-      } else if (element.kind == ElementKind.GETTER) {
-        return new PropertyAccessorElementHandle(
-            element as PropertyAccessorElement);
-      } else if (element.kind == ElementKind.IMPORT) {
-        return new ImportElementHandle(element as ImportElement);
-      } else if (element.kind == ElementKind.LABEL) {
-        return new LabelElementHandle(element as LabelElement);
-      } else if (element.kind == ElementKind.LIBRARY) {
-        return new LibraryElementHandle(element as LibraryElement);
-      } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
-        return new LocalVariableElementHandle(element as LocalVariableElement);
-      } else if (element.kind == ElementKind.METHOD) {
-        return new MethodElementHandle(element as MethodElement);
-      } else if (element.kind == ElementKind.PARAMETER) {
-        return new ParameterElementHandle(element as ParameterElement);
-      } else if (element.kind == ElementKind.PREFIX) {
-        return new PrefixElementHandle(element as PrefixElement);
-      } else if (element.kind == ElementKind.SETTER) {
-        return new PropertyAccessorElementHandle(
-            element as PropertyAccessorElement);
-      } else if (element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
-        return new TopLevelVariableElementHandle(
-            element as TopLevelVariableElement);
-      } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
-        return new FunctionTypeAliasElementHandle(
-            element as FunctionTypeAliasElement);
-      } else if (element.kind == ElementKind.TYPE_PARAMETER) {
-        return new TypeParameterElementHandle(element as TypeParameterElement);
-      } else {
-        throw new UnsupportedOperationException();
-      }
-      break;
-    }
-  }
+/**
+ * Interface which allows an [Element] handle to be resynthesized based on an
+ * [ElementLocation].  The concrete classes implementing element handles use
+ * this interface to retrieve the underlying elements when queried.
+ */
+abstract class ElementResynthesizer {
+  final AnalysisContext context;
 
-  /**
-   * Return an array of the same size as the given array where each element of the returned array is
-   * a handle for the corresponding element of the given array.
-   *
-   * @param elements the elements for which handles are to be created
-   * @return an array of handles to the given elements
-   */
-  static List<Element> forElements(List<Element> elements) {
-    int length = elements.length;
-    List<Element> handles = new List<Element>.from(elements);
-    for (int i = 0; i < length; i++) {
-      handles[i] = forElement(elements[i]);
-    }
-    return handles;
-  }
+  ElementResynthesizer(this.context);
+
+  Element getElement(ElementLocation location);
 }
 
 /**
@@ -501,7 +442,9 @@
    *
    * @param element the element being represented
    */
-  ExecutableElementHandle(ExecutableElement element) : super(element);
+  ExecutableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExecutableElement get actualElement =>
@@ -563,7 +506,9 @@
    *
    * @param element the element being represented
    */
-  ExportElementHandle(ExportElement element) : super(element);
+  ExportElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExportElement get actualElement => super.actualElement as ExportElement;
@@ -597,7 +542,9 @@
    *
    * @param element the element being represented
    */
-  FieldElementHandle(FieldElement element) : super(element);
+  FieldElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FieldElement get actualElement => super.actualElement as FieldElement;
@@ -626,7 +573,9 @@
    *
    * @param element the element being represented
    */
-  FunctionElementHandle(FunctionElement element) : super(element);
+  FunctionElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FunctionElement get actualElement => super.actualElement as FunctionElement;
@@ -655,8 +604,9 @@
    *
    * @param element the element being represented
    */
-  FunctionTypeAliasElementHandle(FunctionTypeAliasElement element)
-      : super(element);
+  FunctionTypeAliasElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   FunctionTypeAliasElement get actualElement =>
@@ -695,7 +645,9 @@
    *
    * @param element the element being represented
    */
-  ImportElementHandle(ImportElement element) : super(element);
+  ImportElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ImportElement get actualElement => super.actualElement as ImportElement;
@@ -737,7 +689,9 @@
    *
    * @param element the element being represented
    */
-  LabelElementHandle(LabelElement element) : super(element);
+  LabelElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ExecutableElement get enclosingElement =>
@@ -757,7 +711,9 @@
    *
    * @param element the element being represented
    */
-  LibraryElementHandle(LibraryElement element) : super(element);
+  LibraryElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   LibraryElement get actualElement => super.actualElement as LibraryElement;
@@ -785,6 +741,9 @@
   bool get hasLoadLibraryFunction => actualElement.hasLoadLibraryFunction;
 
   @override
+  String get identifier => location.components.last;
+
+  @override
   List<LibraryElement> get importedLibraries => actualElement.importedLibraries;
 
   @override
@@ -842,7 +801,9 @@
    *
    * @param element the element being represented
    */
-  LocalVariableElementHandle(LocalVariableElement element) : super(element);
+  LocalVariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   LocalVariableElement get actualElement =>
@@ -868,7 +829,9 @@
    *
    * @param element the element being represented
    */
-  MethodElementHandle(MethodElement element) : super(element);
+  MethodElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   MethodElement get actualElement => super.actualElement as MethodElement;
@@ -898,7 +861,9 @@
    *
    * @param element the element being represented
    */
-  ParameterElementHandle(ParameterElement element) : super(element);
+  ParameterElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ParameterElement get actualElement => super.actualElement as ParameterElement;
@@ -934,7 +899,9 @@
    *
    * @param element the element being represented
    */
-  PrefixElementHandle(PrefixElement element) : super(element);
+  PrefixElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PrefixElement get actualElement => super.actualElement as PrefixElement;
@@ -961,8 +928,9 @@
    *
    * @param element the element being represented
    */
-  PropertyAccessorElementHandle(PropertyAccessorElement element)
-      : super(element);
+  PropertyAccessorElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PropertyAccessorElement get actualElement =>
@@ -1006,8 +974,9 @@
    *
    * @param element the element being represented
    */
-  PropertyInducingElementHandle(PropertyInducingElement element)
-      : super(element);
+  PropertyInducingElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   PropertyInducingElement get actualElement =>
@@ -1034,8 +1003,9 @@
    *
    * @param element the element being represented
    */
-  TopLevelVariableElementHandle(TopLevelVariableElement element)
-      : super(element);
+  TopLevelVariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   ElementKind get kind => ElementKind.TOP_LEVEL_VARIABLE;
@@ -1052,7 +1022,9 @@
    *
    * @param element the element being represented
    */
-  TypeParameterElementHandle(TypeParameterElement element) : super(element);
+  TypeParameterElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   TypeParameterElement get actualElement =>
@@ -1079,7 +1051,9 @@
    *
    * @param element the element being represented
    */
-  VariableElementHandle(VariableElement element) : super(element);
+  VariableElementHandle(
+      ElementResynthesizer resynthesizer, ElementLocation location)
+      : super(resynthesizer, location);
 
   @override
   VariableElement get actualElement => super.actualElement as VariableElement;
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 70defdf..06d0c56 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -6,8 +6,12 @@
 
 import 'dart:collection';
 
+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/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -259,8 +263,8 @@
       if (element == null) {
 //        resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, prefix.getName());
       } else {
+        prefix.staticElement = element;
         if (element is PrefixElement) {
-          prefix.staticElement = element;
           // TODO(brianwilkerson) Report this error?
           element = _resolver.nameScope.lookup(identifier, _definingLibrary);
           name.staticElement = element;
@@ -275,7 +279,6 @@
         } else if (library != _definingLibrary) {
           // TODO(brianwilkerson) Report this error.
         }
-        name.staticElement = element;
         if (node.newKeyword == null) {
           if (element is ClassElement) {
             Element memberElement =
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index bafc908..1861ffe 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
@@ -14,7 +15,6 @@
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -824,8 +824,7 @@
   TaskManager get taskManager {
     if (_taskManager == null) {
       if (enginePlugin.taskExtensionPoint == null) {
-        throw new IllegalStateException(
-            'The analysis engine plugin has not been registered');
+        processRequiredPlugins();
       }
       _taskManager = new TaskManager();
       _taskManager.addTaskDescriptors(enginePlugin.taskDescriptors);
@@ -858,7 +857,7 @@
    */
   void processRequiredPlugins() {
     ExtensionManager manager = new ExtensionManager();
-    manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+    manager.processPlugins(requiredPlugins);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 621b72d..aa43a7e 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -6,9 +6,10 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/ast.dart' show AstNode;
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/scanner.dart'
@@ -40,9 +41,9 @@
    * A [Comparator] that sorts by the name of the file that the [AnalysisError]
    * was found.
    */
-  static Comparator<AnalysisError> FILE_COMPARATOR = (AnalysisError o1,
-          AnalysisError o2) =>
-      o1.source.shortName.compareTo(o2.source.shortName);
+  static Comparator<AnalysisError> FILE_COMPARATOR =
+      (AnalysisError o1, AnalysisError o2) =>
+          o1.source.shortName.compareTo(o2.source.shortName);
 
   /**
    * A [Comparator] that sorts error codes first by their severity (errors
@@ -405,7 +406,8 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    */
-  static const CheckedModeCompileTimeErrorCode CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH =
       const CheckedModeCompileTimeErrorCode(
           'CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH',
           "The object type '{0}' cannot be assigned to the field '{1}', which has type '{2}'");
@@ -414,7 +416,8 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    */
-  static const CheckedModeCompileTimeErrorCode CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH =
       const CheckedModeCompileTimeErrorCode(
           'CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH',
           "The object type '{0}' cannot be assigned to a parameter of type '{1}'");
@@ -431,7 +434,8 @@
    * 0: the name of the type of the initializer expression
    * 1: the name of the type of the field
    */
-  static const CheckedModeCompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
+  static const CheckedModeCompileTimeErrorCode
+      CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
       const CheckedModeCompileTimeErrorCode(
           'CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE',
           "The initializer type '{0}' cannot be assigned to the field type '{1}'");
@@ -449,8 +453,9 @@
    * warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>,
    * 1 &lt;= j &lt;= m</i>.
    */
-  static const CheckedModeCompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE =
-      const CheckedModeCompileTimeErrorCode('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
+  static const CheckedModeCompileTimeErrorCode
+      LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CheckedModeCompileTimeErrorCode(
+          'LIST_ELEMENT_TYPE_NOT_ASSIGNABLE',
           "The element type '{0}' cannot be assigned to the list type '{1}'");
 
   /**
@@ -717,7 +722,8 @@
    * constructor is declared by a class C if any instance variable declared in C
    * is initialized with an expression that is not a constant expression.
    */
-  static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST =
+  static const CompileTimeErrorCode
+      CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST =
       const CompileTimeErrorCode(
           'CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST',
           "Can't define the 'const' constructor because the field '{0}' is initialized with a non-constant value");
@@ -785,7 +791,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used to initialized a 'const' variable");
@@ -803,7 +810,8 @@
    * map literal is an instance of a class that implements the operator
    * <i>==</i> unless the key is a string or integer.
    */
-  static const CompileTimeErrorCode CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS =
+  static const CompileTimeErrorCode
+      CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS =
       const CompileTimeErrorCode(
           'CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS',
           "The constant map entry key expression type '{0}' cannot override the == operator");
@@ -979,7 +987,8 @@
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> explicitly
    * specifies a default value for an optional parameter.
    */
-  static const CompileTimeErrorCode DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR =
+  static const CompileTimeErrorCode
+      DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR =
       const CompileTimeErrorCode(
           'DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR',
           "Default values aren't allowed in factory constructors that redirect to another constructor");
@@ -1167,7 +1176,8 @@
    * initializer for a variable that is initialized by means of an initializing
    * formal of <i>k</i>.
    */
-  static const CompileTimeErrorCode FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER =
+  static const CompileTimeErrorCode
+      FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER =
       const CompileTimeErrorCode(
           'FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER',
           "Fields cannot be initialized in both the parameter list and the initializers");
@@ -1777,8 +1787,9 @@
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting,
    * in which case its only action is to invoke another generative constructor.
    */
-  static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS =
-      const CompileTimeErrorCode('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS',
+  static const CompileTimeErrorCode
+      MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode(
+          'MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS',
           "Constructor may have at most one 'this' redirection");
 
   /**
@@ -1865,7 +1876,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as a case expression");
@@ -1885,7 +1897,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as a default parameter value");
@@ -1905,7 +1918,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as values in a 'const' list");
@@ -1944,8 +1958,9 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
+  static const CompileTimeErrorCode
+      NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY = const CompileTimeErrorCode(
+          'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as values in a 'const' map");
 
   /**
@@ -1978,7 +1993,8 @@
    * 12.1 Constants: A qualified reference to a static constant variable that is
    * not qualified by a deferred prefix.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY =
+  static const CompileTimeErrorCode
+      NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY =
       const CompileTimeErrorCode(
           'NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library cannot be used as constant initializers");
@@ -2121,7 +2137,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS',
           "'{0}' cannot extend itself");
@@ -2139,7 +2156,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS',
           "'{0}' cannot implement itself");
@@ -2157,7 +2175,8 @@
    * Parameters:
    * 0: the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
+  static const CompileTimeErrorCode
+      RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
       const CompileTimeErrorCode(
           'RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH',
           "'{0}' cannot use itself as a mixin");
@@ -2200,7 +2219,8 @@
    * <i>redirecting</i>, in which case its only action is to invoke another
    * generative constructor.
    */
-  static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
+  static const CompileTimeErrorCode
+      REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR =
       const CompileTimeErrorCode(
           'REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR',
           "Generative constructor cannot redirect to a factory constructor");
@@ -2331,8 +2351,9 @@
    * class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT =
-      const CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
+  static const CompileTimeErrorCode
+      UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode(
+          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
           "The class '{0}' does not have a default generative constructor");
 
   /**
@@ -2410,7 +2431,8 @@
    * Parameters:
    * 0: the number of parameters found in the operator declaration
    */
-  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS =
+  static const CompileTimeErrorCode
+      WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS =
       const CompileTimeErrorCode(
           'WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS',
           "Operator '-' should declare 0 or 1 parameter, but {0} found");
@@ -2515,7 +2537,8 @@
     CompileTimeErrorCode.CONST_DEFERRED_CLASS,
     CompileTimeErrorCode.CONST_FORMAL_PARAMETER,
     CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-    CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode
+        .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY,
     CompileTimeErrorCode.CONST_INSTANCE_FIELD,
     CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
     CompileTimeErrorCode.CONST_NOT_INITIALIZED,
@@ -2618,7 +2641,8 @@
     CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY,
     CompileTimeErrorCode.NON_CONSTANT_ANNOTATION_CONSTRUCTOR,
     CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER,
-    CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
+    CompileTimeErrorCode
+        .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY,
     CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
     CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
     CompileTimeErrorCode.OBJECT_CANNOT_EXTEND_ANOTHER_CLASS,
@@ -2773,6 +2797,8 @@
     StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE,
     StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE,
     StaticWarningCode.INVALID_METHOD_OVERRIDE_RETURN_TYPE,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
+    StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
     StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
     StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
     StaticWarningCode.INVALID_OVERRIDE_NAMED,
@@ -4327,7 +4353,8 @@
    * when we are able to find the name defined in a supertype. It exists to
    * provide a more informative error message.
    */
-  static const StaticTypeWarningCode UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER =
+  static const StaticTypeWarningCode
+      UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER =
       const StaticTypeWarningCode(
           'UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER',
           "Static members from supertypes must be qualified by the name of the defining type");
@@ -4552,7 +4579,8 @@
    * Parameters:
    * 0: the name of the super class declaring a static member
    */
-  static const StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER =
+  static const StaticWarningCode
+      CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares static member with the same name");
@@ -4581,7 +4609,8 @@
    * Parameters:
    * 0: the name of the super class declaring a static member
    */
-  static const StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER =
+  static const StaticWarningCode
+      CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares static member with the same name");
@@ -4651,7 +4680,8 @@
    * been initialized at its point of declaration is also initialized in a
    * constructor.
    */
-  static const StaticWarningCode FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION =
+  static const StaticWarningCode
+      FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION =
       const StaticWarningCode(
           'FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION',
           "Values cannot be set in the constructor if they are final, and have already been set");
@@ -4664,7 +4694,8 @@
    * Parameters:
    * 0: the name of the field in question
    */
-  static const StaticWarningCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR =
+  static const StaticWarningCode
+      FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR =
       const StaticWarningCode(
           'FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR',
           "'{0}' is final and was given a value when it was declared, so it cannot be set to a new value");
@@ -4811,7 +4842,8 @@
    * getters none of the <i>m<sub>i</sub></i> are inherited, and a static
    * warning is issued.
    */
-  static const StaticWarningCode INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD =
+  static const StaticWarningCode
+      INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD =
       const StaticWarningCode(
           'INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD',
           "'{0}' is inherited as a getter and also a method");
@@ -4825,7 +4857,8 @@
    * 0: the name of the member with the name conflict
    * 1: the name of the enclosing class that has the static member
    */
-  static const StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
+  static const StaticWarningCode
+      INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
       const StaticWarningCode(
           'INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC',
           "'{0}' collides with a static member in the superclass '{1}'");
@@ -4887,8 +4920,7 @@
    * 4: the name of the class where the overridden method is declared
    */
   static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND =
-      const StaticWarningCode(
-          'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
+      const StaticWarningCode('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
           "The type parameter '{0}' extends '{1}', but that is stricter than '{2}' extends '{3}' in the overridden method from '{4}'");
 
   /**
@@ -4946,8 +4978,9 @@
    * <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static const StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED =
-      const StaticWarningCode('INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
+  static const StaticWarningCode
+      INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED = const StaticWarningCode(
+          'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
           "Parameters cannot override default values, this method overrides '{0}.{1}' where '{2}' has a different value");
 
   /**
@@ -4957,7 +4990,8 @@
    * <i>p</i> and the signature of <i>m1</i> specifies a different default value
    * for <i>p</i>.
    */
-  static const StaticWarningCode INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL =
+  static const StaticWarningCode
+      INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL =
       const StaticWarningCode(
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
           "Parameters cannot override default values, this method overrides '{0}.{1}' where this positional parameter has a different value");
@@ -5090,7 +5124,8 @@
    * with argument type <i>T</i> and a getter named <i>v</i> with return type
    * <i>S</i>, and <i>T</i> may not be assigned to <i>S</i>.
    */
-  static const StaticWarningCode MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE =
+  static const StaticWarningCode
+      MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE =
       const StaticWarningCode(
           'MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE',
           "The parameter type for setter '{0}' is '{1}' which is not assignable to its getter (of type '{2}'), from superclass '{3}'");
@@ -5192,7 +5227,8 @@
    * 3: the name of the fourth member
    * 4: the number of additional missing members that aren't listed
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
           "Missing concrete implementation of {0}, {1}, {2}, {3} and {4} more");
@@ -5217,7 +5253,8 @@
    * 2: the name of the third member
    * 3: the name of the fourth member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
           "Missing concrete implementation of {0}, {1}, {2} and {3}");
@@ -5239,8 +5276,9 @@
    * Parameters:
    * 0: the name of the member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
-      const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = const StaticWarningCode(
+          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
           "Missing concrete implementation of {0}");
 
   /**
@@ -5262,7 +5300,8 @@
    * 1: the name of the second member
    * 2: the name of the third member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
           "Missing concrete implementation of {0}, {1} and {2}");
@@ -5285,8 +5324,9 @@
    * 0: the name of the first member
    * 1: the name of the second member
    */
-  static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
-      const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
+  static const StaticWarningCode
+      NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = const StaticWarningCode(
+          'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
           "Missing concrete implementation of {0} and {1}");
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index ef6300b..6e4638a 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -7,9 +7,14 @@
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -1201,7 +1206,8 @@
         } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
           if (fieldElement.isFinal || fieldElement.isConst) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
+                StaticWarningCode
+                    .FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR,
                 formalParameter.identifier,
                 [fieldElement.displayName]);
             foundError = true;
@@ -1236,13 +1242,15 @@
           } else if (state == INIT_STATE.INIT_IN_DECLARATION) {
             if (fieldElement.isFinal || fieldElement.isConst) {
               _errorReporter.reportErrorForNode(
-                  StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
+                  StaticWarningCode
+                      .FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION,
                   fieldName);
               foundError = true;
             }
           } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
+                CompileTimeErrorCode
+                    .FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER,
                 fieldName);
             foundError = true;
           } else if (state == INIT_STATE.INIT_IN_INITIALIZERS) {
@@ -1341,14 +1349,14 @@
     FunctionType overridingFT = executableElement.type;
     FunctionType overriddenFT = overriddenExecutable.type;
     InterfaceType enclosingType = _enclosingClass.type;
-    overriddenFT = _inheritanceManager
-        .substituteTypeArgumentsInMemberFromInheritance(
+    overriddenFT =
+        _inheritanceManager.substituteTypeArgumentsInMemberFromInheritance(
             overriddenFT, executableElementName, enclosingType);
     if (overridingFT == null || overriddenFT == null) {
       return false;
     }
 
-  // Handle generic function type parameters.
+    // Handle generic function type parameters.
     // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
     // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
     // an error message once it's ready to "return false".
@@ -1466,10 +1474,10 @@
               : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
           errorNameTarget,
           [
-        overridingFTReturnType,
-        overriddenFTReturnType,
-        overriddenExecutable.enclosingElement.displayName
-      ]);
+            overridingFTReturnType,
+            overriddenFTReturnType,
+            overriddenExecutable.enclosingElement.displayName
+          ]);
       return true;
     }
     // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
@@ -1486,10 +1494,10 @@
                 : StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE,
             parameterLocations[parameterIndex],
             [
-          overridingNormalPT[i],
-          overriddenNormalPT[i],
-          overriddenExecutable.enclosingElement.displayName
-        ]);
+              overridingNormalPT[i],
+              overriddenNormalPT[i],
+              overriddenExecutable.enclosingElement.displayName
+            ]);
         return true;
       }
       parameterIndex++;
@@ -1605,12 +1613,14 @@
               }
               if (!result.equalValues(_typeProvider, overriddenResult)) {
                 _errorReporter.reportErrorForNode(
-                    StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
-                    formalParameters[i], [
-                  overriddenExecutable.enclosingElement.displayName,
-                  overriddenExecutable.displayName,
-                  parameterName
-                ]);
+                    StaticWarningCode
+                        .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED,
+                    formalParameters[i],
+                    [
+                      overriddenExecutable.enclosingElement.displayName,
+                      overriddenExecutable.displayName,
+                      parameterName
+                    ]);
                 foundError = true;
               }
             }
@@ -1642,11 +1652,13 @@
           }
           if (!result.equalValues(_typeProvider, overriddenResult)) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
-                formalParameters[i], [
-              overriddenExecutable.enclosingElement.displayName,
-              overriddenExecutable.displayName
-            ]);
+                StaticWarningCode
+                    .INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL,
+                formalParameters[i],
+                [
+                  overriddenExecutable.enclosingElement.displayName,
+                  overriddenExecutable.displayName
+                ]);
             foundError = true;
           }
         }
@@ -2159,8 +2171,8 @@
       SimpleIdentifier identifier, ErrorCode errorCode) {
     sc.Token token = identifier.token;
     if (token.type == sc.TokenType.KEYWORD) {
-      _errorReporter.reportErrorForNode(
-          errorCode, identifier, [identifier.name]);
+      _errorReporter
+          .reportErrorForNode(errorCode, identifier, [identifier.name]);
       return true;
     }
     return false;
@@ -3261,8 +3273,8 @@
       return false;
     }
     if (typeName.isDeferred) {
-      _errorReporter.reportErrorForNode(
-          errorCode, typeName, [typeName.name.name]);
+      _errorReporter
+          .reportErrorForNode(errorCode, typeName, [typeName.name.name]);
       return true;
     }
     return false;
@@ -3357,7 +3369,8 @@
       // TODO(paulberry): this error should be based on the actual type of the
       // constant, not the static type.  See dartbug.com/21119.
       _errorReporter.reportTypeErrorForNode(
-          CheckedModeCompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
+          CheckedModeCompileTimeErrorCode
+              .CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE,
           expression,
           [staticType, fieldType]);
     }
@@ -3799,7 +3812,8 @@
           // instance vs. static
           if (fieldElt.isStatic) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+                StaticWarningCode
+                    .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
                 errorNameTarget,
                 [executableElementName, fieldElt.enclosingElement.displayName]);
             return true;
@@ -3820,11 +3834,13 @@
           // instance vs. static
           if (methodElement.isStatic) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
-                errorNameTarget, [
-              executableElementName,
-              methodElement.enclosingElement.displayName
-            ]);
+                StaticWarningCode
+                    .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
+                errorNameTarget,
+                [
+                  executableElementName,
+                  methodElement.enclosingElement.displayName
+                ]);
             return true;
           }
         }
@@ -4326,8 +4342,8 @@
   void _checkForMixinHasNoConstructors(AstNode node) {
     if ((_enclosingClass as ClassElementImpl).doesMixinLackConstructors) {
       ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS;
-      _errorReporter.reportErrorForNode(
-          errorCode, node, [_enclosingClass.supertype]);
+      _errorReporter
+          .reportErrorForNode(errorCode, node, [_enclosingClass.supertype]);
     }
   }
 
@@ -4656,14 +4672,16 @@
       ]);
     } else {
       analysisError = _errorReporter.newErrorWithProperties(
-          StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
-          classNameNode, [
-        stringMembersArray[0],
-        stringMembersArray[1],
-        stringMembersArray[2],
-        stringMembersArray[3],
-        stringMembersArray.length - 4
-      ]);
+          StaticWarningCode
+              .NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS,
+          classNameNode,
+          [
+            stringMembersArray[0],
+            stringMembersArray[1],
+            stringMembersArray[2],
+            stringMembersArray[3],
+            stringMembersArray.length - 4
+          ]);
     }
     analysisError.setProperty(
         ErrorProperty.UNIMPLEMENTED_METHODS, missingOverridesArray);
@@ -4947,7 +4965,8 @@
         if (parameter is DefaultFormalParameter &&
             parameter.defaultValue != null) {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
+              CompileTimeErrorCode
+                  .DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR,
               parameter.identifier);
           errorReported = true;
         }
@@ -4979,7 +4998,8 @@
           } else {
             if (redirectingElement.isFactory) {
               _errorReporter.reportErrorForNode(
-                  CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
+                  CompileTimeErrorCode
+                      .REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR,
                   initializer);
             }
           }
@@ -5151,6 +5171,10 @@
    */
   bool _checkForStaticAccessToInstanceMember(
       ClassElement typeReference, SimpleIdentifier name) {
+    // OK, in comment
+    if (_isInComment) {
+      return false;
+    }
     // OK, target is not a type
     if (typeReference == null) {
       return false;
@@ -5761,15 +5785,18 @@
   ErrorCode _getBaseCaseErrorCode(ClassElement element) {
     InterfaceType supertype = element.supertype;
     if (supertype != null && _enclosingClass == supertype.element) {
-      return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
+      return CompileTimeErrorCode
+          .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
     }
     List<InterfaceType> mixins = element.mixins;
     for (int i = 0; i < mixins.length; i++) {
       if (_enclosingClass == mixins[i].element) {
-        return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
+        return CompileTimeErrorCode
+            .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
       }
     }
-    return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
+    return CompileTimeErrorCode
+        .RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
   }
 
   /**
@@ -5879,7 +5906,8 @@
   bool _hasTypedefSelfReference(Element element) {
     Set<Element> checked = new HashSet<Element>();
     List<Element> toCheck = new List<Element>();
-    GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisitor =
+    GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
+        elementVisitor =
         new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(
             toCheck);
     toCheck.add(element);
@@ -6031,7 +6059,8 @@
     return false;
   }
 
-  bool _isUserDefinedObject(EvaluationResultImpl result) => result == null ||
+  bool _isUserDefinedObject(EvaluationResultImpl result) =>
+      result == null ||
       (result.value != null && result.value.isUserDefinedObject);
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index 6cf9af1..36d8784 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -4,8 +4,11 @@
 
 library analyzer.src.generated.incremental_resolution_validator;
 
+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/member.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 
 /**
  * Validates that the [actual] and the [expected] units have the same structure
@@ -843,6 +846,11 @@
     if (a.nameOffset != b.nameOffset) {
       _fail('Expected: ${b.nameOffset}\n  Actual: ${a.nameOffset}');
     }
+    if (a is LocalElement && b is LocalElement) {
+      if (a.visibleRange != b.visibleRange) {
+        _fail('Expected: ${b.visibleRange}\nActual: ${a.visibleRange}');
+      }
+    }
   }
 
   void _verifyType(DartType a, DartType b) {
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index a80de52..f8cba0c 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -7,10 +7,13 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/error_verifier.dart';
@@ -916,6 +919,7 @@
         isByTask(ScanDartTask.DESCRIPTOR) ||
         isByTask(ResolveInstanceFieldsInUnitTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
+        isByTask(ResolveLibraryTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryTypeNamesTask.DESCRIPTOR) ||
         isByTask(ResolveUnitTask.DESCRIPTOR) ||
         isByTask(ResolveUnitTypeNamesTask.DESCRIPTOR) ||
@@ -1117,7 +1121,8 @@
    *
    * [node] - the node being tested.
    */
-  bool _canBeResolved(AstNode node) => node is ClassDeclaration ||
+  bool _canBeResolved(AstNode node) =>
+      node is ClassDeclaration ||
       node is ClassTypeAlias ||
       node is CompilationUnit ||
       node is ConstructorDeclaration ||
@@ -1269,7 +1274,7 @@
     LoggingTimer timer = logger.startTimer();
     try {
       _definingUnit
-          .accept(new _ElementNameOffsetUpdater(_updateOffset, _updateDelta));
+          .accept(new _ElementOffsetUpdater(_updateOffset, _updateDelta));
       _definingUnit.afterIncrementalResolution();
     } finally {
       timer.stop('update element offsets');
@@ -1987,18 +1992,34 @@
  */
 class _DeclarationMismatchException {}
 
-class _ElementNameOffsetUpdater extends GeneralizingElementVisitor {
+class _ElementOffsetUpdater extends GeneralizingElementVisitor {
   final int updateOffset;
   final int updateDelta;
 
-  _ElementNameOffsetUpdater(this.updateOffset, this.updateDelta);
+  _ElementOffsetUpdater(this.updateOffset, this.updateDelta);
 
   @override
   visitElement(Element element) {
+    // name offset
     int nameOffset = element.nameOffset;
     if (nameOffset > updateOffset) {
       (element as ElementImpl).nameOffset = nameOffset + updateDelta;
     }
+    // visible range
+    if (element is LocalElement) {
+      SourceRange visibleRange = element.visibleRange;
+      if (visibleRange != null && visibleRange.offset > updateOffset) {
+        int newOffset = visibleRange.offset + updateDelta;
+        int length = visibleRange.length;
+        if (element is FunctionElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        } else if (element is LocalVariableElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        } else if (element is ParameterElementImpl) {
+          element.setVisibleRange(newOffset, length);
+        }
+      }
+    }
     super.visitElement(element);
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index b15a92e..bd13357 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -3867,6 +3867,16 @@
         index = 3;
       }
     }
+    if (StringUtilities.startsWith4(comment, index, 0x20, 0x20, 0x20, 0x20)) {
+      int end = index + 4;
+      while (end < length &&
+          comment.codeUnitAt(end) != 0xD &&
+          comment.codeUnitAt(end) != 0xA) {
+        end = end + 1;
+      }
+      ranges.add(<int>[index, end]);
+      index = end;
+    }
     while (index < length) {
       int currentChar = comment.codeUnitAt(index);
       if (currentChar == 0xD || currentChar == 0xA) {
@@ -4052,7 +4062,8 @@
   /**
    * Return `true` if the given [character] is a valid hexadecimal digit.
    */
-  bool _isHexDigit(int character) => (0x30 <= character && character <= 0x39) ||
+  bool _isHexDigit(int character) =>
+      (0x30 <= character && character <= 0x39) ||
       (0x41 <= character && character <= 0x46) ||
       (0x61 <= character && character <= 0x66);
 
@@ -4326,7 +4337,7 @@
    */
   bool _matchesString(String identifier) =>
       _currentToken.type == TokenType.IDENTIFIER &&
-          _currentToken.lexeme == identifier;
+      _currentToken.lexeme == identifier;
 
   /**
    * If the current token has the given [type], then advance to the next token
@@ -5042,6 +5053,7 @@
     List<CommentReference> references = new List<CommentReference>();
     for (DocumentationCommentToken token in tokens) {
       String comment = token.lexeme;
+      comment = _removeCodeBlocksGitHub(comment);
       int length = comment.length;
       List<List<int>> codeBlockRanges = _getCodeBlockRanges(comment);
       int leftIndex = comment.indexOf('[');
@@ -8008,7 +8020,8 @@
    * was parsed.
    */
   StringLiteral _parseUri() {
-    bool iskeywordAfterUri(Token token) => token.lexeme == Keyword.AS.syntax ||
+    bool iskeywordAfterUri(Token token) =>
+        token.lexeme == Keyword.AS.syntax ||
         token.lexeme == _HIDE ||
         token.lexeme == _SHOW;
     if (!_matches(TokenType.STRING) &&
@@ -8230,6 +8243,25 @@
     return token;
   }
 
+  String _removeCodeBlocksGitHub(String comment) {
+    int index = 0;
+    while (true) {
+      int beginIndex = comment.indexOf('`', index);
+      if (beginIndex == -1) {
+        break;
+      }
+      int endIndex = comment.indexOf('`', beginIndex + 1);
+      if (endIndex == -1) {
+        break;
+      }
+      comment = comment.substring(0, beginIndex + 1) +
+          ' ' * (endIndex - beginIndex - 1) +
+          comment.substring(endIndex);
+      index = endIndex + 1;
+    }
+    return comment;
+  }
+
   /**
    * Report the given [error].
    */
@@ -8741,21 +8773,21 @@
    */
   bool _tokenMatchesIdentifier(Token token) =>
       _tokenMatches(token, TokenType.IDENTIFIER) ||
-          _tokenMatchesPseudoKeyword(token);
+      _tokenMatchesPseudoKeyword(token);
 
   /**
    * Return `true` if the given [token] matches the given [keyword].
    */
   bool _tokenMatchesKeyword(Token token, Keyword keyword) =>
       token.type == TokenType.KEYWORD &&
-          (token as KeywordToken).keyword == keyword;
+      (token as KeywordToken).keyword == keyword;
 
   /**
    * Return `true` if the given [token] matches a pseudo keyword.
    */
   bool _tokenMatchesPseudoKeyword(Token token) =>
       _tokenMatches(token, TokenType.KEYWORD) &&
-          (token as KeywordToken).keyword.isPseudoKeyword;
+      (token as KeywordToken).keyword.isPseudoKeyword;
 
   /**
    * Return `true` if the given [token] matches the given [identifier].
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 03452f4..a52736d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -6,9 +6,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -20,7 +25,8 @@
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/task/strong/info.dart' show InferredType, StaticInfo;
+import 'package:analyzer/src/task/strong/info.dart'
+    show InferredType, StaticInfo;
 
 export 'package:analyzer/src/generated/type_system.dart';
 
@@ -1133,8 +1139,10 @@
         result =
             _validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
         if (result != null) {
-          _reportErrorIfFromDeferredLibrary(element,
-              CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              element,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY);
         }
       }
     }
@@ -1157,8 +1165,10 @@
         DartObjectImpl valueResult = _validate(
             valueExpression, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
         if (valueResult != null) {
-          _reportErrorIfFromDeferredLibrary(valueExpression,
-              CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              valueExpression,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY);
         }
         if (keyResult != null) {
           _reportErrorIfFromDeferredLibrary(key,
@@ -1171,7 +1181,8 @@
           DartType type = keyResult.type;
           if (_implementsEqualsWhenNotAllowed(type)) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
+                CompileTimeErrorCode
+                    .CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
                 key,
                 [type.displayName]);
           }
@@ -1228,8 +1239,10 @@
         DartObjectImpl caseResult = _validate(
             expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION);
         if (caseResult != null) {
-          _reportErrorIfFromDeferredLibrary(expression,
-              CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY);
+          _reportErrorIfFromDeferredLibrary(
+              expression,
+              CompileTimeErrorCode
+                  .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY);
           DartObject value = caseResult;
           if (firstType == null) {
             firstType = value.type;
@@ -1269,8 +1282,10 @@
       }
       _reportErrors(result.errors,
           CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE);
-      _reportErrorIfFromDeferredLibrary(initializer,
-          CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY);
+      _reportErrorIfFromDeferredLibrary(
+          initializer,
+          CompileTimeErrorCode
+              .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY);
     }
     return null;
   }
@@ -1363,10 +1378,14 @@
           identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM) ||
           identical(dataErrorCode,
               CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT) ||
-          identical(dataErrorCode,
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
-          identical(dataErrorCode,
-              CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) ||
+          identical(
+              dataErrorCode,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH) ||
+          identical(
+              dataErrorCode,
+              CheckedModeCompileTimeErrorCode
+                  .CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH) ||
           identical(dataErrorCode,
               CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH)) {
         _errorReporter.reportError(data);
@@ -1463,8 +1482,10 @@
           result = _validate(
               defaultValue, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE);
           if (result != null) {
-            _reportErrorIfFromDeferredLibrary(defaultValue,
-                CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY);
+            _reportErrorIfFromDeferredLibrary(
+                defaultValue,
+                CompileTimeErrorCode
+                    .NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY);
           }
         }
         VariableElementImpl element = parameter.element as VariableElementImpl;
@@ -1504,7 +1525,8 @@
                   subErrorReporter));
               if (result == null) {
                 _errorReporter.reportErrorForNode(
-                    CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+                    CompileTimeErrorCode
+                        .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
                     errorSite,
                     [variableDeclaration.name.name]);
               }
@@ -1534,8 +1556,10 @@
     _reportErrors(errorListener.errors,
         CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER);
     if (result != null) {
-      _reportErrorIfFromDeferredLibrary(expression,
-          CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY);
+      _reportErrorIfFromDeferredLibrary(
+          expression,
+          CompileTimeErrorCode
+              .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY);
     }
   }
 
@@ -2672,7 +2696,7 @@
     interfaceType.typeArguments = typeArguments;
     element.type = interfaceType;
     element.typeParameters = typeParameters;
-    _setDocRange(element, node);
+    _setDoc(element, node);
     element.abstract = node.isAbstract;
     element.accessors = holder.accessors;
     List<ConstructorElement> constructors = holder.constructors;
@@ -2744,7 +2768,7 @@
     SimpleIdentifier constructorName = node.name;
     ConstructorElementImpl element =
         new ConstructorElementImpl.forNode(constructorName);
-    _setDocRange(element, node);
+    _setDoc(element, node);
     if (node.externalKeyword != null) {
       element.external = true;
     }
@@ -2849,7 +2873,7 @@
     SimpleIdentifier enumName = node.name;
     ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
     enumElement.enum2 = true;
-    _setDocRange(enumElement, node);
+    _setDoc(enumElement, node);
     InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
     enumElement.type = enumType;
     // The equivalent code for enums in the spec shows a single constructor,
@@ -2922,7 +2946,7 @@
         SimpleIdentifier functionName = node.name;
         FunctionElementImpl element =
             new FunctionElementImpl.forNode(functionName);
-        _setDocRange(element, node);
+        _setDoc(element, node);
         if (node.externalKeyword != null) {
           element.external = true;
         }
@@ -2969,7 +2993,7 @@
         if (node.isGetter) {
           PropertyAccessorElementImpl getter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(getter, node);
+          _setDoc(getter, node);
           if (node.externalKeyword != null) {
             getter.external = true;
           }
@@ -2995,7 +3019,7 @@
         } else {
           PropertyAccessorElementImpl setter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(setter, node);
+          _setDoc(setter, node);
           if (node.externalKeyword != null) {
             setter.external = true;
           }
@@ -3086,7 +3110,7 @@
     List<TypeParameterElement> typeParameters = holder.typeParameters;
     FunctionTypeAliasElementImpl element =
         new FunctionTypeAliasElementImpl.forNode(aliasName);
-    _setDocRange(element, node);
+    _setDoc(element, node);
     element.parameters = parameters;
     element.typeParameters = typeParameters;
     _createTypeParameterTypes(typeParameters);
@@ -3157,7 +3181,7 @@
         }
         MethodElementImpl element =
             new MethodElementImpl(nameOfMethod, methodName.offset);
-        _setDocRange(element, node);
+        _setDoc(element, node);
         element.abstract = node.isAbstract;
         if (node.externalKeyword != null) {
           element.external = true;
@@ -3194,7 +3218,7 @@
         if (node.isGetter) {
           PropertyAccessorElementImpl getter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(getter, node);
+          _setDoc(getter, node);
           if (node.externalKeyword != null) {
             getter.external = true;
           }
@@ -3220,7 +3244,7 @@
         } else {
           PropertyAccessorElementImpl setter =
               new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDocRange(setter, node);
+          _setDoc(setter, node);
           if (node.externalKeyword != null) {
             setter.external = true;
           }
@@ -3358,7 +3382,7 @@
       }
       element = field;
       if (node.parent.parent is FieldDeclaration) {
-        _setDocRange(element, node.parent.parent);
+        _setDoc(element, node.parent.parent);
       }
       if ((node.parent as VariableDeclarationList).type == null) {
         field.hasImplicitType = true;
@@ -3393,7 +3417,7 @@
       }
       element = variable;
       if (node.parent.parent is TopLevelVariableDeclaration) {
-        _setDocRange(element, node.parent.parent);
+        _setDoc(element, node.parent.parent);
       }
       if ((node.parent as VariableDeclarationList).type == null) {
         variable.hasImplicitType = true;
@@ -3527,12 +3551,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  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);
     }
   }
@@ -5673,8 +5699,9 @@
     if (memberName == null || memberName.isEmpty) {
       return null;
     }
-    ExecutableElement executable = _computeClassChainLookupMap(
-        classElt, new HashSet<ClassElement>()).get(memberName);
+    ExecutableElement executable =
+        _computeClassChainLookupMap(classElt, new HashSet<ClassElement>())
+            .get(memberName);
     if (executable == null) {
       return _computeInterfaceLookupMap(classElt, new HashSet<ClassElement>())
           .get(memberName);
@@ -6329,8 +6356,9 @@
               // Tests: test_getMapOfMembersInheritedFromInterfaces_
               // union_multipleSubtypes_*
               //
-              List<ExecutableElement> elementArrayToMerge = new List<
-                  ExecutableElement>(subtypesOfAllOtherTypesIndexes.length);
+              List<ExecutableElement> elementArrayToMerge =
+                  new List<ExecutableElement>(
+                      subtypesOfAllOtherTypesIndexes.length);
               for (int i = 0; i < elementArrayToMerge.length; i++) {
                 elementArrayToMerge[i] =
                     elements[subtypesOfAllOtherTypesIndexes[i]];
@@ -6345,7 +6373,8 @@
               classElt,
               classElt.nameOffset,
               classElt.nameLength,
-              StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
+              StaticWarningCode
+                  .INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
               [key]);
         }
       }
@@ -6492,8 +6521,8 @@
       int numOfPositionalParameters,
       List<String> namedParameters) {
     DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
-    SimpleIdentifier nameIdentifier = new SimpleIdentifier(
-        new StringToken(TokenType.IDENTIFIER, name, 0));
+    SimpleIdentifier nameIdentifier =
+        new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, name, 0));
     ExecutableElementImpl executable;
     if (elementArrayToMerge[0] is MethodElement) {
       MultiplyInheritedMethodElementImpl unionedMethod =
@@ -6582,7 +6611,7 @@
   static int _getNumOfPositionalParameters(
           ExecutableElement executableElement) =>
       _getNumOfParameters(executableElement, ParameterKind.REQUIRED) +
-          _getNumOfParameters(executableElement, ParameterKind.POSITIONAL);
+      _getNumOfParameters(executableElement, ParameterKind.POSITIONAL);
 
   /**
    * Given some [ExecutableElement] return the number of required parameters.
@@ -7929,12 +7958,6 @@
    */
   ExecutableElement _enclosingFunction = null;
 
-  /**
-   * The [Comment] before a [FunctionDeclaration] or a [MethodDeclaration] that
-   * cannot be resolved where we visited it, because it should be resolved in the scope of the body.
-   */
-  Comment _commentBeforeFunction = null;
-
   InferenceContext inferenceContext = null;
 
   /**
@@ -8095,7 +8118,6 @@
       if (element is ExecutableElement) {
         _enclosingFunction = element;
       }
-      _commentBeforeFunction = declaration.documentationComment;
     }
     _overrideManager.enterScope();
   }
@@ -8230,6 +8252,15 @@
     expression.propagatedType = type;
   }
 
+  /**
+   * Visit the given [comment] if it is not `null`.
+   */
+  void safelyVisitComment(Comment comment) {
+    if (comment != null) {
+      super.visitComment(comment);
+    }
+  }
+
   @override
   Object visitAnnotation(Annotation node) {
     AstNode parent = node.parent;
@@ -8390,7 +8421,6 @@
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     _overrideManager.enterScope();
     try {
       inferenceContext.pushReturnContext(InferenceContext.getType(node));
@@ -8470,16 +8500,14 @@
 
   @override
   Object visitComment(Comment node) {
-    if (node.parent is FunctionDeclaration ||
-        node.parent is ConstructorDeclaration ||
-        node.parent is MethodDeclaration) {
-      if (!identical(node, _commentBeforeFunction)) {
-        _commentBeforeFunction = node;
-        return null;
-      }
+    AstNode parent = node.parent;
+    if (parent is FunctionDeclaration ||
+        parent is FunctionTypeAlias ||
+        parent is ConstructorDeclaration ||
+        parent is MethodDeclaration) {
+      return null;
     }
     super.visitComment(node);
-    _commentBeforeFunction = null;
     return null;
   }
 
@@ -8604,6 +8632,12 @@
   }
 
   @override
+  void visitConstructorDeclarationInScope(ConstructorDeclaration node) {
+    super.visitConstructorDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     //
     // We visit the expression, but do not visit the field name because it needs
@@ -8649,16 +8683,10 @@
       (element.initializer as FunctionElementImpl).returnType =
           node.defaultValue.staticType;
     }
-    FormalParameterList parent = node.parent;
-    AstNode grandparent = parent.parent;
-    if (grandparent is ConstructorDeclaration &&
-        grandparent.constKeyword != null) {
-      // For const constructors, we need to clone the ASTs for default formal
-      // parameters, so that we can use them during constant evaluation.
-      ParameterElement element = node.element;
-      (element as ConstVariableElement).constantInitializer =
-          new ConstantAstCloner().cloneNode(node.defaultValue);
-    }
+    // Clone the ASTs for default formal parameters, so that we can use them
+    // during constant evaluation.
+    (element as ConstVariableElement).constantInitializer =
+        new ConstantAstCloner().cloneNode(node.defaultValue);
     return null;
   }
 
@@ -8677,7 +8705,6 @@
 
   @override
   Object visitEmptyFunctionBody(EmptyFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     if (resolveOnlyCommentInFunctionBody) {
       return null;
     }
@@ -8715,7 +8742,6 @@
 
   @override
   Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    safelyVisit(_commentBeforeFunction);
     if (resolveOnlyCommentInFunctionBody) {
       return null;
     }
@@ -8853,6 +8879,12 @@
   }
 
   @override
+  void visitFunctionDeclarationInScope(FunctionDeclaration node) {
+    super.visitFunctionDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitFunctionExpression(FunctionExpression node) {
     ExecutableElement outerFunction = _enclosingFunction;
     try {
@@ -8902,6 +8934,12 @@
   }
 
   @override
+  void visitFunctionTypeAliasInScope(FunctionTypeAlias node) {
+    super.visitFunctionTypeAliasInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitHideCombinator(HideCombinator node) => null;
 
   @override
@@ -9070,6 +9108,12 @@
   }
 
   @override
+  void visitMethodDeclarationInScope(MethodDeclaration node) {
+    super.visitMethodDeclarationInScope(node);
+    safelyVisitComment(node.documentationComment);
+  }
+
+  @override
   Object visitMethodInvocation(MethodInvocation node) {
     //
     // We visit the target and argument list, but do not visit the method name
@@ -10168,13 +10212,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, constructorElement);
       }
-      super.visitConstructorDeclaration(node);
+      visitConstructorDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitConstructorDeclarationInScope(ConstructorDeclaration node) {
+    super.visitConstructorDeclaration(node);
+  }
+
   @override
   Object visitDeclaredIdentifier(DeclaredIdentifier node) {
     VariableElement element = node.element;
@@ -10326,13 +10374,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, functionElement);
       }
-      super.visitFunctionDeclaration(node);
+      visitFunctionDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitFunctionDeclarationInScope(FunctionDeclaration node) {
+    super.visitFunctionDeclaration(node);
+  }
+
   @override
   Object visitFunctionExpression(FunctionExpression node) {
     if (node.parent is FunctionDeclaration) {
@@ -10375,13 +10427,17 @@
     Scope outerScope = nameScope;
     try {
       nameScope = new FunctionTypeScope(nameScope, node.element);
-      super.visitFunctionTypeAlias(node);
+      visitFunctionTypeAliasInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitFunctionTypeAliasInScope(FunctionTypeAlias node) {
+    super.visitFunctionTypeAlias(node);
+  }
+
   @override
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     Scope outerScope = nameScope;
@@ -10436,13 +10492,17 @@
       } else {
         nameScope = new FunctionScope(nameScope, methodElement);
       }
-      super.visitMethodDeclaration(node);
+      visitMethodDeclarationInScope(node);
     } finally {
       nameScope = outerScope;
     }
     return null;
   }
 
+  void visitMethodDeclarationInScope(MethodDeclaration node) {
+    super.visitMethodDeclaration(node);
+  }
+
   /**
    * Visit the given statement after it's scope has been created. This is used by ResolverVisitor to
    * correctly visit the 'then' and 'else' statements of an 'if' statement.
@@ -12132,10 +12192,10 @@
       } else if ((redirectingConstructorKind =
               _getRedirectingConstructorKind(node)) !=
           null) {
-        ErrorCode errorCode = (redirectingConstructorKind ==
-                RedirectingConstructorKind.CONST
-            ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
-            : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+        ErrorCode errorCode =
+            (redirectingConstructorKind == RedirectingConstructorKind.CONST
+                ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+                : StaticWarningCode.REDIRECT_TO_NON_CLASS);
         reportErrorForNode(errorCode, typeName, [typeName.name]);
       } else if (_isTypeNameInTypeArgumentList(node)) {
         reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
@@ -12192,10 +12252,10 @@
       } else if ((redirectingConstructorKind =
               _getRedirectingConstructorKind(node)) !=
           null) {
-        ErrorCode errorCode = (redirectingConstructorKind ==
-                RedirectingConstructorKind.CONST
-            ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
-            : StaticWarningCode.REDIRECT_TO_NON_CLASS);
+        ErrorCode errorCode =
+            (redirectingConstructorKind == RedirectingConstructorKind.CONST
+                ? CompileTimeErrorCode.REDIRECT_TO_NON_CLASS
+                : StaticWarningCode.REDIRECT_TO_NON_CLASS);
         reportErrorForNode(errorCode, typeName, [typeName.name]);
       } else if (_isTypeNameInTypeArgumentList(node)) {
         reportErrorForNode(StaticTypeWarningCode.NON_TYPE_AS_TYPE_ARGUMENT,
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 96971cb..106ff7a 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -6,8 +6,11 @@
 
 import 'dart:collection';
 
+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/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index bfb87b6..c6892c2 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -4,8 +4,8 @@
 
 library analyzer.src.generated.testing.ast_factory;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4932e92..0dc3c7b 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -6,9 +6,12 @@
 
 import 'dart:collection';
 
+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/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -196,7 +199,9 @@
 
   static FieldElementImpl fieldElement(
       String name, bool isStatic, bool isFinal, bool isConst, DartType type) {
-    FieldElementImpl field = new FieldElementImpl(name, 0);
+    FieldElementImpl field = isConst
+        ? new ConstFieldElementImpl(name, 0)
+        : new FieldElementImpl(name, 0);
     field.const3 = isConst;
     field.final2 = isFinal;
     field.static = isStatic;
@@ -398,8 +403,10 @@
     field.static = isStatic;
     field.synthetic = true;
     field.type = type;
+    field.final2 = true;
     PropertyAccessorElementImpl getter =
         new PropertyAccessorElementImpl.forVariable(field);
+    getter.synthetic = false;
     getter.getter = true;
     getter.variable = field;
     getter.returnType = type;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index e44e2a3..5f1a49b 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -4,10 +4,14 @@
 
 library analyzer.src.generated.testing.test_type_provider;
 
+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/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 
@@ -208,7 +212,11 @@
   @override
   InterfaceType get functionType {
     if (_functionType == null) {
-      _functionType = ElementFactory.classElement2("Function").type;
+      ClassElementImpl functionClass = ElementFactory.classElement2("Function");
+      functionClass.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(functionClass, null, false)
+      ];
+      _functionType = functionClass.type;
     }
     return _functionType;
   }
@@ -265,7 +273,10 @@
             "iterator", false, iteratorType.substitute4(<DartType>[eType])),
         ElementFactory.getterElement("last", false, eType)
       ]);
-      iterableElement.constructors = ConstructorElement.EMPTY_LIST;
+      iterableElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(iterableElement, null, true)
+          ..isCycleFree = true
+      ];
       _propagateTypeArguments(iterableElement);
     }
     return _iterableType;
@@ -280,7 +291,9 @@
       _setAccessors(iteratorElement, <PropertyAccessorElement>[
         ElementFactory.getterElement("current", false, eType)
       ]);
-      iteratorElement.constructors = ConstructorElement.EMPTY_LIST;
+      iteratorElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(iteratorElement, null, false)
+      ];
       _propagateTypeArguments(iteratorElement);
     }
     return _iteratorType;
@@ -329,7 +342,11 @@
         ElementFactory.methodElement(
             "[]=", VoidTypeImpl.instance, [kType, vType])
       ];
-      mapElement.constructors = ConstructorElement.EMPTY_LIST;
+      mapElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(mapElement, null, false)
+          ..external = true
+          ..factory = true
+      ];
       _propagateTypeArguments(mapElement);
     }
     return _mapType;
@@ -357,7 +374,10 @@
   InterfaceType get nullType {
     if (_nullType == null) {
       ClassElementImpl nullElement = ElementFactory.classElement2("Null");
-      nullElement.constructors = ConstructorElement.EMPTY_LIST;
+      nullElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(
+            nullElement, '_uninstantiatable', false)..factory = true
+      ];
       _nullType = nullElement.type;
     }
     return _nullType;
@@ -396,7 +416,12 @@
   @override
   InterfaceType get stackTraceType {
     if (_stackTraceType == null) {
-      _stackTraceType = ElementFactory.classElement2("StackTrace").type;
+      ClassElementImpl stackTraceElement =
+          ElementFactory.classElement2("StackTrace");
+      stackTraceElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(stackTraceElement, null, false)
+      ];
+      _stackTraceType = stackTraceElement.type;
     }
     return _stackTraceType;
   }
@@ -463,7 +488,12 @@
   @override
   InterfaceType get typeType {
     if (_typeType == null) {
-      _typeType = ElementFactory.classElement2("Type").type;
+      ClassElementImpl typeClass = ElementFactory.classElement2("Type");
+      typeClass.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement(typeClass, null, false)
+          ..synthetic = true
+      ];
+      _typeType = typeClass.type;
     }
     return _typeType;
   }
@@ -554,12 +584,22 @@
     ];
     fromEnvironment.factory = true;
     fromEnvironment.isCycleFree = true;
-    numElement.constructors = ConstructorElement.EMPTY_LIST;
+    numElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(numElement, null, false)
+        ..synthetic = true
+    ];
     intElement.constructors = <ConstructorElement>[fromEnvironment];
-    doubleElement.constructors = ConstructorElement.EMPTY_LIST;
+    doubleElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(doubleElement, null, false)
+        ..synthetic = true
+    ];
+    ConstFieldElementImpl varINFINITY =
+        ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType);
+    varINFINITY.constantInitializer = AstFactory.binaryExpression(
+        AstFactory.integer(1), TokenType.SLASH, AstFactory.integer(0));
     List<FieldElement> fields = <FieldElement>[
       ElementFactory.fieldElement("NAN", true, false, true, _doubleType),
-      ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType),
+      varINFINITY,
       ElementFactory.fieldElement(
           "NEGATIVE_INFINITY", true, false, true, _doubleType),
       ElementFactory.fieldElement(
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index e520222..8e813e3 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -6,7 +6,10 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/element.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' show AnalysisContext;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index dbd8963..07b0def 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -226,6 +226,7 @@
     registerExtension(taskId, ReadyResolvedUnit11Task.DESCRIPTOR);
     registerExtension(taskId, ResolveInstanceFieldsInUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
+    registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryTypeNamesTask.DESCRIPTOR);
     registerExtension(taskId, ResolveUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveUnitTypeNamesTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/summary/builder.dart b/pkg/analyzer/lib/src/summary/builder.dart
index f63bdd5..c1bedfb 100644
--- a/pkg/analyzer/lib/src/summary/builder.dart
+++ b/pkg/analyzer/lib/src/summary/builder.dart
@@ -7,8 +7,6 @@
  */
 library analyzer.src.summary.builder;
 
-import 'dart:convert';
-
 /**
  * Instances of this class encapsulate the necessary state to keep track of a
  * serialized summary that is in the process of being built.
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 4974b99..d050d81 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -14,6 +14,7 @@
   classOrEnum,
   typedef,
   other,
+  prefix,
   unresolved,
 }
 
@@ -42,16 +43,23 @@
 class PrelinkedDependencyBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   PrelinkedDependencyBuilder(builder.BuilderContext context);
 
   void set uri(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("uri"));
     if (_value != null) {
       _json["uri"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 PrelinkedDependencyBuilder encodePrelinkedDependency(builder.BuilderContext builderContext, {String uri}) {
@@ -61,38 +69,39 @@
 }
 
 class PrelinkedLibrary {
-  UnlinkedLibrary _unlinked;
+  List<PrelinkedUnit> _units;
   List<PrelinkedDependency> _dependencies;
   List<int> _importDependencies;
-  List<PrelinkedReference> _references;
 
   PrelinkedLibrary.fromJson(Map json)
-    : _unlinked = json["unlinked"] == null ? null : new UnlinkedLibrary.fromJson(json["unlinked"]),
+    : _units = json["units"]?.map((x) => new PrelinkedUnit.fromJson(x))?.toList(),
       _dependencies = json["dependencies"]?.map((x) => new PrelinkedDependency.fromJson(x))?.toList(),
-      _importDependencies = json["importDependencies"],
-      _references = json["references"]?.map((x) => new PrelinkedReference.fromJson(x))?.toList();
+      _importDependencies = json["importDependencies"];
 
   PrelinkedLibrary.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
 
-  UnlinkedLibrary get unlinked => _unlinked;
+  List<PrelinkedUnit> get units => _units ?? const <PrelinkedUnit>[];
   List<PrelinkedDependency> get dependencies => _dependencies ?? const <PrelinkedDependency>[];
   List<int> get importDependencies => _importDependencies ?? const <int>[];
-  List<PrelinkedReference> get references => _references ?? const <PrelinkedReference>[];
 }
 
 class PrelinkedLibraryBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   PrelinkedLibraryBuilder(builder.BuilderContext context);
 
-  void set unlinked(UnlinkedLibraryBuilder _value) {
-    assert(!_json.containsKey("unlinked"));
-    if (_value != null) {
-      _json["unlinked"] = _value.finish();
+  void set units(List<PrelinkedUnitBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("units"));
+    if (_value != null || _value.isEmpty) {
+      _json["units"] = _value.map((b) => b.finish()).toList();
     }
   }
 
   void set dependencies(List<PrelinkedDependencyBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("dependencies"));
     if (_value != null || _value.isEmpty) {
       _json["dependencies"] = _value.map((b) => b.finish()).toList();
@@ -100,30 +109,27 @@
   }
 
   void set importDependencies(List<int> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("importDependencies"));
     if (_value != null || _value.isEmpty) {
       _json["importDependencies"] = _value.toList();
     }
   }
 
-  void set references(List<PrelinkedReferenceBuilder> _value) {
-    assert(!_json.containsKey("references"));
-    if (_value != null || _value.isEmpty) {
-      _json["references"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
   List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-PrelinkedLibraryBuilder encodePrelinkedLibrary(builder.BuilderContext builderContext, {UnlinkedLibraryBuilder unlinked, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies, List<PrelinkedReferenceBuilder> references}) {
+PrelinkedLibraryBuilder encodePrelinkedLibrary(builder.BuilderContext builderContext, {List<PrelinkedUnitBuilder> units, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies}) {
   PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder(builderContext);
-  builder.unlinked = unlinked;
+  builder.units = units;
   builder.dependencies = dependencies;
   builder.importDependencies = importDependencies;
-  builder.references = references;
   return builder;
 }
 
@@ -145,9 +151,12 @@
 class PrelinkedReferenceBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   PrelinkedReferenceBuilder(builder.BuilderContext context);
 
   void set dependency(int _value) {
+    assert(!_finished);
     assert(!_json.containsKey("dependency"));
     if (_value != null) {
       _json["dependency"] = _value;
@@ -155,6 +164,7 @@
   }
 
   void set kind(PrelinkedReferenceKind _value) {
+    assert(!_finished);
     assert(!_json.containsKey("kind"));
     if (_value != null || _value == PrelinkedReferenceKind.classOrEnum) {
       _json["kind"] = _value.index;
@@ -162,13 +172,18 @@
   }
 
   void set unit(int _value) {
+    assert(!_finished);
     assert(!_json.containsKey("unit"));
     if (_value != null) {
       _json["unit"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 PrelinkedReferenceBuilder encodePrelinkedReference(builder.BuilderContext builderContext, {int dependency, PrelinkedReferenceKind kind, int unit}) {
@@ -179,9 +194,45 @@
   return builder;
 }
 
+class PrelinkedUnit {
+  List<PrelinkedReference> _references;
+
+  PrelinkedUnit.fromJson(Map json)
+    : _references = json["references"]?.map((x) => new PrelinkedReference.fromJson(x))?.toList();
+
+  List<PrelinkedReference> get references => _references ?? const <PrelinkedReference>[];
+}
+
+class PrelinkedUnitBuilder {
+  final Map _json = {};
+
+  bool _finished = false;
+
+  PrelinkedUnitBuilder(builder.BuilderContext context);
+
+  void set references(List<PrelinkedReferenceBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("references"));
+    if (_value != null || _value.isEmpty) {
+      _json["references"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
+}
+
+PrelinkedUnitBuilder encodePrelinkedUnit(builder.BuilderContext builderContext, {List<PrelinkedReferenceBuilder> references}) {
+  PrelinkedUnitBuilder builder = new PrelinkedUnitBuilder(builderContext);
+  builder.references = references;
+  return builder;
+}
+
 class UnlinkedClass {
   String _name;
-  int _unit;
   List<UnlinkedTypeParam> _typeParameters;
   UnlinkedTypeRef _supertype;
   List<UnlinkedTypeRef> _mixins;
@@ -190,10 +241,10 @@
   List<UnlinkedExecutable> _executables;
   bool _isAbstract;
   bool _isMixinApplication;
+  bool _hasNoSupertype;
 
   UnlinkedClass.fromJson(Map json)
     : _name = json["name"],
-      _unit = json["unit"],
       _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
       _supertype = json["supertype"] == null ? null : new UnlinkedTypeRef.fromJson(json["supertype"]),
       _mixins = json["mixins"]?.map((x) => new UnlinkedTypeRef.fromJson(x))?.toList(),
@@ -201,10 +252,10 @@
       _fields = json["fields"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList(),
       _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
       _isAbstract = json["isAbstract"],
-      _isMixinApplication = json["isMixinApplication"];
+      _isMixinApplication = json["isMixinApplication"],
+      _hasNoSupertype = json["hasNoSupertype"];
 
   String get name => _name ?? '';
-  int get unit => _unit ?? 0;
   List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
   UnlinkedTypeRef get supertype => _supertype;
   List<UnlinkedTypeRef> get mixins => _mixins ?? const <UnlinkedTypeRef>[];
@@ -213,28 +264,26 @@
   List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
   bool get isAbstract => _isAbstract ?? false;
   bool get isMixinApplication => _isMixinApplication ?? false;
+  bool get hasNoSupertype => _hasNoSupertype ?? false;
 }
 
 class UnlinkedClassBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedClassBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  void set unit(int _value) {
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
-  }
-
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("typeParameters"));
     if (_value != null || _value.isEmpty) {
       _json["typeParameters"] = _value.map((b) => b.finish()).toList();
@@ -242,6 +291,7 @@
   }
 
   void set supertype(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("supertype"));
     if (_value != null) {
       _json["supertype"] = _value.finish();
@@ -249,6 +299,7 @@
   }
 
   void set mixins(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("mixins"));
     if (_value != null || _value.isEmpty) {
       _json["mixins"] = _value.map((b) => b.finish()).toList();
@@ -256,6 +307,7 @@
   }
 
   void set interfaces(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("interfaces"));
     if (_value != null || _value.isEmpty) {
       _json["interfaces"] = _value.map((b) => b.finish()).toList();
@@ -263,6 +315,7 @@
   }
 
   void set fields(List<UnlinkedVariableBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("fields"));
     if (_value != null || _value.isEmpty) {
       _json["fields"] = _value.map((b) => b.finish()).toList();
@@ -270,6 +323,7 @@
   }
 
   void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("executables"));
     if (_value != null || _value.isEmpty) {
       _json["executables"] = _value.map((b) => b.finish()).toList();
@@ -277,6 +331,7 @@
   }
 
   void set isAbstract(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isAbstract"));
     if (_value != null) {
       _json["isAbstract"] = _value;
@@ -284,19 +339,31 @@
   }
 
   void set isMixinApplication(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isMixinApplication"));
     if (_value != null) {
       _json["isMixinApplication"] = _value;
     }
   }
 
-  Map finish() => _json;
+  void set hasNoSupertype(bool _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("hasNoSupertype"));
+    if (_value != null) {
+      _json["hasNoSupertype"] = _value;
+    }
+  }
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedClassBuilder encodeUnlinkedClass(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication}) {
+UnlinkedClassBuilder encodeUnlinkedClass(builder.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder supertype, List<UnlinkedTypeRefBuilder> mixins, List<UnlinkedTypeRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication, bool hasNoSupertype}) {
   UnlinkedClassBuilder builder = new UnlinkedClassBuilder(builderContext);
   builder.name = name;
-  builder.unit = unit;
   builder.typeParameters = typeParameters;
   builder.supertype = supertype;
   builder.mixins = mixins;
@@ -305,6 +372,7 @@
   builder.executables = executables;
   builder.isAbstract = isAbstract;
   builder.isMixinApplication = isMixinApplication;
+  builder.hasNoSupertype = hasNoSupertype;
   return builder;
 }
 
@@ -323,9 +391,12 @@
 class UnlinkedCombinatorBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedCombinatorBuilder(builder.BuilderContext context);
 
   void set shows(List<UnlinkedCombinatorNameBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("shows"));
     if (_value != null || _value.isEmpty) {
       _json["shows"] = _value.map((b) => b.finish()).toList();
@@ -333,13 +404,18 @@
   }
 
   void set hides(List<UnlinkedCombinatorNameBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("hides"));
     if (_value != null || _value.isEmpty) {
       _json["hides"] = _value.map((b) => b.finish()).toList();
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedCombinatorBuilder encodeUnlinkedCombinator(builder.BuilderContext builderContext, {List<UnlinkedCombinatorNameBuilder> shows, List<UnlinkedCombinatorNameBuilder> hides}) {
@@ -361,16 +437,23 @@
 class UnlinkedCombinatorNameBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedCombinatorNameBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedCombinatorNameBuilder encodeUnlinkedCombinatorName(builder.BuilderContext builderContext, {String name}) {
@@ -382,24 +465,24 @@
 class UnlinkedEnum {
   String _name;
   List<UnlinkedEnumValue> _values;
-  int _unit;
 
   UnlinkedEnum.fromJson(Map json)
     : _name = json["name"],
-      _values = json["values"]?.map((x) => new UnlinkedEnumValue.fromJson(x))?.toList(),
-      _unit = json["unit"];
+      _values = json["values"]?.map((x) => new UnlinkedEnumValue.fromJson(x))?.toList();
 
   String get name => _name ?? '';
   List<UnlinkedEnumValue> get values => _values ?? const <UnlinkedEnumValue>[];
-  int get unit => _unit ?? 0;
 }
 
 class UnlinkedEnumBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedEnumBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
@@ -407,27 +490,24 @@
   }
 
   void set values(List<UnlinkedEnumValueBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("values"));
     if (_value != null || _value.isEmpty) {
       _json["values"] = _value.map((b) => b.finish()).toList();
     }
   }
 
-  void set unit(int _value) {
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
   }
-
-  Map finish() => _json;
 }
 
-UnlinkedEnumBuilder encodeUnlinkedEnum(builder.BuilderContext builderContext, {String name, List<UnlinkedEnumValueBuilder> values, int unit}) {
+UnlinkedEnumBuilder encodeUnlinkedEnum(builder.BuilderContext builderContext, {String name, List<UnlinkedEnumValueBuilder> values}) {
   UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder(builderContext);
   builder.name = name;
   builder.values = values;
-  builder.unit = unit;
   return builder;
 }
 
@@ -443,16 +523,23 @@
 class UnlinkedEnumValueBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedEnumValueBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedEnumValueBuilder encodeUnlinkedEnumValue(builder.BuilderContext builderContext, {String name}) {
@@ -463,7 +550,6 @@
 
 class UnlinkedExecutable {
   String _name;
-  int _unit;
   List<UnlinkedTypeParam> _typeParameters;
   UnlinkedTypeRef _returnType;
   List<UnlinkedParam> _parameters;
@@ -472,10 +558,11 @@
   bool _isStatic;
   bool _isConst;
   bool _isFactory;
+  bool _hasImplicitReturnType;
+  bool _isExternal;
 
   UnlinkedExecutable.fromJson(Map json)
     : _name = json["name"],
-      _unit = json["unit"],
       _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
       _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
       _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
@@ -483,10 +570,11 @@
       _isAbstract = json["isAbstract"],
       _isStatic = json["isStatic"],
       _isConst = json["isConst"],
-      _isFactory = json["isFactory"];
+      _isFactory = json["isFactory"],
+      _hasImplicitReturnType = json["hasImplicitReturnType"],
+      _isExternal = json["isExternal"];
 
   String get name => _name ?? '';
-  int get unit => _unit ?? 0;
   List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
   UnlinkedTypeRef get returnType => _returnType;
   List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
@@ -495,28 +583,27 @@
   bool get isStatic => _isStatic ?? false;
   bool get isConst => _isConst ?? false;
   bool get isFactory => _isFactory ?? false;
+  bool get hasImplicitReturnType => _hasImplicitReturnType ?? false;
+  bool get isExternal => _isExternal ?? false;
 }
 
 class UnlinkedExecutableBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedExecutableBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  void set unit(int _value) {
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
-  }
-
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("typeParameters"));
     if (_value != null || _value.isEmpty) {
       _json["typeParameters"] = _value.map((b) => b.finish()).toList();
@@ -524,6 +611,7 @@
   }
 
   void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("returnType"));
     if (_value != null) {
       _json["returnType"] = _value.finish();
@@ -531,6 +619,7 @@
   }
 
   void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("parameters"));
     if (_value != null || _value.isEmpty) {
       _json["parameters"] = _value.map((b) => b.finish()).toList();
@@ -538,6 +627,7 @@
   }
 
   void set kind(UnlinkedExecutableKind _value) {
+    assert(!_finished);
     assert(!_json.containsKey("kind"));
     if (_value != null || _value == UnlinkedExecutableKind.functionOrMethod) {
       _json["kind"] = _value.index;
@@ -545,6 +635,7 @@
   }
 
   void set isAbstract(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isAbstract"));
     if (_value != null) {
       _json["isAbstract"] = _value;
@@ -552,6 +643,7 @@
   }
 
   void set isStatic(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isStatic"));
     if (_value != null) {
       _json["isStatic"] = _value;
@@ -559,6 +651,7 @@
   }
 
   void set isConst(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isConst"));
     if (_value != null) {
       _json["isConst"] = _value;
@@ -566,19 +659,39 @@
   }
 
   void set isFactory(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isFactory"));
     if (_value != null) {
       _json["isFactory"] = _value;
     }
   }
 
-  Map finish() => _json;
+  void set hasImplicitReturnType(bool _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("hasImplicitReturnType"));
+    if (_value != null) {
+      _json["hasImplicitReturnType"] = _value;
+    }
+  }
+
+  void set isExternal(bool _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("isExternal"));
+    if (_value != null) {
+      _json["isExternal"] = _value;
+    }
+  }
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedExecutableBuilder encodeUnlinkedExecutable(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory}) {
+UnlinkedExecutableBuilder encodeUnlinkedExecutable(builder.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory, bool hasImplicitReturnType, bool isExternal}) {
   UnlinkedExecutableBuilder builder = new UnlinkedExecutableBuilder(builderContext);
   builder.name = name;
-  builder.unit = unit;
   builder.typeParameters = typeParameters;
   builder.returnType = returnType;
   builder.parameters = parameters;
@@ -587,6 +700,8 @@
   builder.isStatic = isStatic;
   builder.isConst = isConst;
   builder.isFactory = isFactory;
+  builder.hasImplicitReturnType = hasImplicitReturnType;
+  builder.isExternal = isExternal;
   return builder;
 }
 
@@ -605,9 +720,12 @@
 class UnlinkedExportBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedExportBuilder(builder.BuilderContext context);
 
   void set uri(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("uri"));
     if (_value != null) {
       _json["uri"] = _value;
@@ -615,13 +733,18 @@
   }
 
   void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("combinators"));
     if (_value != null || _value.isEmpty) {
       _json["combinators"] = _value.map((b) => b.finish()).toList();
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedExportBuilder encodeUnlinkedExport(builder.BuilderContext builderContext, {String uri, List<UnlinkedCombinatorBuilder> combinators}) {
@@ -634,7 +757,7 @@
 class UnlinkedImport {
   String _uri;
   int _offset;
-  int _prefix;
+  int _prefixReference;
   List<UnlinkedCombinator> _combinators;
   bool _isDeferred;
   bool _isImplicit;
@@ -642,14 +765,14 @@
   UnlinkedImport.fromJson(Map json)
     : _uri = json["uri"],
       _offset = json["offset"],
-      _prefix = json["prefix"],
+      _prefixReference = json["prefixReference"],
       _combinators = json["combinators"]?.map((x) => new UnlinkedCombinator.fromJson(x))?.toList(),
       _isDeferred = json["isDeferred"],
       _isImplicit = json["isImplicit"];
 
   String get uri => _uri ?? '';
   int get offset => _offset ?? 0;
-  int get prefix => _prefix ?? 0;
+  int get prefixReference => _prefixReference ?? 0;
   List<UnlinkedCombinator> get combinators => _combinators ?? const <UnlinkedCombinator>[];
   bool get isDeferred => _isDeferred ?? false;
   bool get isImplicit => _isImplicit ?? false;
@@ -658,9 +781,12 @@
 class UnlinkedImportBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedImportBuilder(builder.BuilderContext context);
 
   void set uri(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("uri"));
     if (_value != null) {
       _json["uri"] = _value;
@@ -668,20 +794,23 @@
   }
 
   void set offset(int _value) {
+    assert(!_finished);
     assert(!_json.containsKey("offset"));
     if (_value != null) {
       _json["offset"] = _value;
     }
   }
 
-  void set prefix(int _value) {
-    assert(!_json.containsKey("prefix"));
+  void set prefixReference(int _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("prefixReference"));
     if (_value != null) {
-      _json["prefix"] = _value;
+      _json["prefixReference"] = _value;
     }
   }
 
   void set combinators(List<UnlinkedCombinatorBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("combinators"));
     if (_value != null || _value.isEmpty) {
       _json["combinators"] = _value.map((b) => b.finish()).toList();
@@ -689,6 +818,7 @@
   }
 
   void set isDeferred(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isDeferred"));
     if (_value != null) {
       _json["isDeferred"] = _value;
@@ -696,166 +826,31 @@
   }
 
   void set isImplicit(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isImplicit"));
     if (_value != null) {
       _json["isImplicit"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedImportBuilder encodeUnlinkedImport(builder.BuilderContext builderContext, {String uri, int offset, int prefix, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit}) {
+UnlinkedImportBuilder encodeUnlinkedImport(builder.BuilderContext builderContext, {String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit}) {
   UnlinkedImportBuilder builder = new UnlinkedImportBuilder(builderContext);
   builder.uri = uri;
   builder.offset = offset;
-  builder.prefix = prefix;
+  builder.prefixReference = prefixReference;
   builder.combinators = combinators;
   builder.isDeferred = isDeferred;
   builder.isImplicit = isImplicit;
   return builder;
 }
 
-class UnlinkedLibrary {
-  List<UnlinkedReference> _references;
-  List<UnlinkedUnit> _units;
-  String _name;
-  List<UnlinkedClass> _classes;
-  List<UnlinkedEnum> _enums;
-  List<UnlinkedExecutable> _executables;
-  List<UnlinkedExport> _exports;
-  List<UnlinkedImport> _imports;
-  List<UnlinkedTypedef> _typedefs;
-  List<UnlinkedVariable> _variables;
-  List<UnlinkedPrefix> _prefixes;
-
-  UnlinkedLibrary.fromJson(Map json)
-    : _references = json["references"]?.map((x) => new UnlinkedReference.fromJson(x))?.toList(),
-      _units = json["units"]?.map((x) => new UnlinkedUnit.fromJson(x))?.toList(),
-      _name = json["name"],
-      _classes = json["classes"]?.map((x) => new UnlinkedClass.fromJson(x))?.toList(),
-      _enums = json["enums"]?.map((x) => new UnlinkedEnum.fromJson(x))?.toList(),
-      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
-      _exports = json["exports"]?.map((x) => new UnlinkedExport.fromJson(x))?.toList(),
-      _imports = json["imports"]?.map((x) => new UnlinkedImport.fromJson(x))?.toList(),
-      _typedefs = json["typedefs"]?.map((x) => new UnlinkedTypedef.fromJson(x))?.toList(),
-      _variables = json["variables"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList(),
-      _prefixes = json["prefixes"]?.map((x) => new UnlinkedPrefix.fromJson(x))?.toList();
-
-  List<UnlinkedReference> get references => _references ?? const <UnlinkedReference>[];
-  List<UnlinkedUnit> get units => _units ?? const <UnlinkedUnit>[];
-  String get name => _name ?? '';
-  List<UnlinkedClass> get classes => _classes ?? const <UnlinkedClass>[];
-  List<UnlinkedEnum> get enums => _enums ?? const <UnlinkedEnum>[];
-  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
-  List<UnlinkedExport> get exports => _exports ?? const <UnlinkedExport>[];
-  List<UnlinkedImport> get imports => _imports ?? const <UnlinkedImport>[];
-  List<UnlinkedTypedef> get typedefs => _typedefs ?? const <UnlinkedTypedef>[];
-  List<UnlinkedVariable> get variables => _variables ?? const <UnlinkedVariable>[];
-  List<UnlinkedPrefix> get prefixes => _prefixes ?? const <UnlinkedPrefix>[];
-}
-
-class UnlinkedLibraryBuilder {
-  final Map _json = {};
-
-  UnlinkedLibraryBuilder(builder.BuilderContext context);
-
-  void set references(List<UnlinkedReferenceBuilder> _value) {
-    assert(!_json.containsKey("references"));
-    if (_value != null || _value.isEmpty) {
-      _json["references"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set units(List<UnlinkedUnitBuilder> _value) {
-    assert(!_json.containsKey("units"));
-    if (_value != null || _value.isEmpty) {
-      _json["units"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set name(String _value) {
-    assert(!_json.containsKey("name"));
-    if (_value != null) {
-      _json["name"] = _value;
-    }
-  }
-
-  void set classes(List<UnlinkedClassBuilder> _value) {
-    assert(!_json.containsKey("classes"));
-    if (_value != null || _value.isEmpty) {
-      _json["classes"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set enums(List<UnlinkedEnumBuilder> _value) {
-    assert(!_json.containsKey("enums"));
-    if (_value != null || _value.isEmpty) {
-      _json["enums"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set executables(List<UnlinkedExecutableBuilder> _value) {
-    assert(!_json.containsKey("executables"));
-    if (_value != null || _value.isEmpty) {
-      _json["executables"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set exports(List<UnlinkedExportBuilder> _value) {
-    assert(!_json.containsKey("exports"));
-    if (_value != null || _value.isEmpty) {
-      _json["exports"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set imports(List<UnlinkedImportBuilder> _value) {
-    assert(!_json.containsKey("imports"));
-    if (_value != null || _value.isEmpty) {
-      _json["imports"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set typedefs(List<UnlinkedTypedefBuilder> _value) {
-    assert(!_json.containsKey("typedefs"));
-    if (_value != null || _value.isEmpty) {
-      _json["typedefs"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set variables(List<UnlinkedVariableBuilder> _value) {
-    assert(!_json.containsKey("variables"));
-    if (_value != null || _value.isEmpty) {
-      _json["variables"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  void set prefixes(List<UnlinkedPrefixBuilder> _value) {
-    assert(!_json.containsKey("prefixes"));
-    if (_value != null || _value.isEmpty) {
-      _json["prefixes"] = _value.map((b) => b.finish()).toList();
-    }
-  }
-
-  Map finish() => _json;
-}
-
-UnlinkedLibraryBuilder encodeUnlinkedLibrary(builder.BuilderContext builderContext, {List<UnlinkedReferenceBuilder> references, List<UnlinkedUnitBuilder> units, String name, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables, List<UnlinkedPrefixBuilder> prefixes}) {
-  UnlinkedLibraryBuilder builder = new UnlinkedLibraryBuilder(builderContext);
-  builder.references = references;
-  builder.units = units;
-  builder.name = name;
-  builder.classes = classes;
-  builder.enums = enums;
-  builder.executables = executables;
-  builder.exports = exports;
-  builder.imports = imports;
-  builder.typedefs = typedefs;
-  builder.variables = variables;
-  builder.prefixes = prefixes;
-  return builder;
-}
-
 class UnlinkedParam {
   String _name;
   UnlinkedTypeRef _type;
@@ -863,6 +858,7 @@
   UnlinkedParamKind _kind;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
+  bool _hasImplicitType;
 
   UnlinkedParam.fromJson(Map json)
     : _name = json["name"],
@@ -870,7 +866,8 @@
       _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList(),
       _kind = json["kind"] == null ? null : UnlinkedParamKind.values[json["kind"]],
       _isFunctionTyped = json["isFunctionTyped"],
-      _isInitializingFormal = json["isInitializingFormal"];
+      _isInitializingFormal = json["isInitializingFormal"],
+      _hasImplicitType = json["hasImplicitType"];
 
   String get name => _name ?? '';
   UnlinkedTypeRef get type => _type;
@@ -878,14 +875,18 @@
   UnlinkedParamKind get kind => _kind ?? UnlinkedParamKind.required;
   bool get isFunctionTyped => _isFunctionTyped ?? false;
   bool get isInitializingFormal => _isInitializingFormal ?? false;
+  bool get hasImplicitType => _hasImplicitType ?? false;
 }
 
 class UnlinkedParamBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedParamBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
@@ -893,6 +894,7 @@
   }
 
   void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("type"));
     if (_value != null) {
       _json["type"] = _value.finish();
@@ -900,6 +902,7 @@
   }
 
   void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("parameters"));
     if (_value != null || _value.isEmpty) {
       _json["parameters"] = _value.map((b) => b.finish()).toList();
@@ -907,6 +910,7 @@
   }
 
   void set kind(UnlinkedParamKind _value) {
+    assert(!_finished);
     assert(!_json.containsKey("kind"));
     if (_value != null || _value == UnlinkedParamKind.required) {
       _json["kind"] = _value.index;
@@ -914,6 +918,7 @@
   }
 
   void set isFunctionTyped(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isFunctionTyped"));
     if (_value != null) {
       _json["isFunctionTyped"] = _value;
@@ -921,16 +926,29 @@
   }
 
   void set isInitializingFormal(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isInitializingFormal"));
     if (_value != null) {
       _json["isInitializingFormal"] = _value;
     }
   }
 
-  Map finish() => _json;
+  void set hasImplicitType(bool _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("hasImplicitType"));
+    if (_value != null) {
+      _json["hasImplicitType"] = _value;
+    }
+  }
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedParamBuilder encodeUnlinkedParam(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal}) {
+UnlinkedParamBuilder encodeUnlinkedParam(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, bool hasImplicitType}) {
   UnlinkedParamBuilder builder = new UnlinkedParamBuilder(builderContext);
   builder.name = name;
   builder.type = type;
@@ -938,96 +956,109 @@
   builder.kind = kind;
   builder.isFunctionTyped = isFunctionTyped;
   builder.isInitializingFormal = isInitializingFormal;
+  builder.hasImplicitType = hasImplicitType;
   return builder;
 }
 
-class UnlinkedPrefix {
-  String _name;
+class UnlinkedPart {
+  String _uri;
 
-  UnlinkedPrefix.fromJson(Map json)
-    : _name = json["name"];
+  UnlinkedPart.fromJson(Map json)
+    : _uri = json["uri"];
 
-  String get name => _name ?? '';
+  String get uri => _uri ?? '';
 }
 
-class UnlinkedPrefixBuilder {
+class UnlinkedPartBuilder {
   final Map _json = {};
 
-  UnlinkedPrefixBuilder(builder.BuilderContext context);
+  bool _finished = false;
 
-  void set name(String _value) {
-    assert(!_json.containsKey("name"));
+  UnlinkedPartBuilder(builder.BuilderContext context);
+
+  void set uri(String _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("uri"));
     if (_value != null) {
-      _json["name"] = _value;
+      _json["uri"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedPrefixBuilder encodeUnlinkedPrefix(builder.BuilderContext builderContext, {String name}) {
-  UnlinkedPrefixBuilder builder = new UnlinkedPrefixBuilder(builderContext);
-  builder.name = name;
+UnlinkedPartBuilder encodeUnlinkedPart(builder.BuilderContext builderContext, {String uri}) {
+  UnlinkedPartBuilder builder = new UnlinkedPartBuilder(builderContext);
+  builder.uri = uri;
   return builder;
 }
 
 class UnlinkedReference {
   String _name;
-  int _prefix;
+  int _prefixReference;
 
   UnlinkedReference.fromJson(Map json)
     : _name = json["name"],
-      _prefix = json["prefix"];
+      _prefixReference = json["prefixReference"];
 
   String get name => _name ?? '';
-  int get prefix => _prefix ?? 0;
+  int get prefixReference => _prefixReference ?? 0;
 }
 
 class UnlinkedReferenceBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedReferenceBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  void set prefix(int _value) {
-    assert(!_json.containsKey("prefix"));
+  void set prefixReference(int _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("prefixReference"));
     if (_value != null) {
-      _json["prefix"] = _value;
+      _json["prefixReference"] = _value;
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedReferenceBuilder encodeUnlinkedReference(builder.BuilderContext builderContext, {String name, int prefix}) {
+UnlinkedReferenceBuilder encodeUnlinkedReference(builder.BuilderContext builderContext, {String name, int prefixReference}) {
   UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder(builderContext);
   builder.name = name;
-  builder.prefix = prefix;
+  builder.prefixReference = prefixReference;
   return builder;
 }
 
 class UnlinkedTypedef {
   String _name;
-  int _unit;
   List<UnlinkedTypeParam> _typeParameters;
   UnlinkedTypeRef _returnType;
   List<UnlinkedParam> _parameters;
 
   UnlinkedTypedef.fromJson(Map json)
     : _name = json["name"],
-      _unit = json["unit"],
       _typeParameters = json["typeParameters"]?.map((x) => new UnlinkedTypeParam.fromJson(x))?.toList(),
       _returnType = json["returnType"] == null ? null : new UnlinkedTypeRef.fromJson(json["returnType"]),
       _parameters = json["parameters"]?.map((x) => new UnlinkedParam.fromJson(x))?.toList();
 
   String get name => _name ?? '';
-  int get unit => _unit ?? 0;
   List<UnlinkedTypeParam> get typeParameters => _typeParameters ?? const <UnlinkedTypeParam>[];
   UnlinkedTypeRef get returnType => _returnType;
   List<UnlinkedParam> get parameters => _parameters ?? const <UnlinkedParam>[];
@@ -1036,23 +1067,20 @@
 class UnlinkedTypedefBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedTypedefBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  void set unit(int _value) {
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
-  }
-
   void set typeParameters(List<UnlinkedTypeParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("typeParameters"));
     if (_value != null || _value.isEmpty) {
       _json["typeParameters"] = _value.map((b) => b.finish()).toList();
@@ -1060,6 +1088,7 @@
   }
 
   void set returnType(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("returnType"));
     if (_value != null) {
       _json["returnType"] = _value.finish();
@@ -1067,19 +1096,23 @@
   }
 
   void set parameters(List<UnlinkedParamBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("parameters"));
     if (_value != null || _value.isEmpty) {
       _json["parameters"] = _value.map((b) => b.finish()).toList();
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedTypedefBuilder encodeUnlinkedTypedef(builder.BuilderContext builderContext, {String name, int unit, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
+UnlinkedTypedefBuilder encodeUnlinkedTypedef(builder.BuilderContext builderContext, {String name, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
   UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder(builderContext);
   builder.name = name;
-  builder.unit = unit;
   builder.typeParameters = typeParameters;
   builder.returnType = returnType;
   builder.parameters = parameters;
@@ -1101,9 +1134,12 @@
 class UnlinkedTypeParamBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedTypeParamBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
@@ -1111,13 +1147,18 @@
   }
 
   void set bound(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("bound"));
     if (_value != null) {
       _json["bound"] = _value.finish();
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedTypeParamBuilder encodeUnlinkedTypeParam(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder bound}) {
@@ -1145,9 +1186,12 @@
 class UnlinkedTypeRefBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedTypeRefBuilder(builder.BuilderContext context);
 
   void set reference(int _value) {
+    assert(!_finished);
     assert(!_json.containsKey("reference"));
     if (_value != null) {
       _json["reference"] = _value;
@@ -1155,6 +1199,7 @@
   }
 
   void set paramReference(int _value) {
+    assert(!_finished);
     assert(!_json.containsKey("paramReference"));
     if (_value != null) {
       _json["paramReference"] = _value;
@@ -1162,13 +1207,18 @@
   }
 
   void set typeArguments(List<UnlinkedTypeRefBuilder> _value) {
+    assert(!_finished);
     assert(!_json.containsKey("typeArguments"));
     if (_value != null || _value.isEmpty) {
       _json["typeArguments"] = _value.map((b) => b.finish()).toList();
     }
   }
 
-  Map finish() => _json;
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
 UnlinkedTypeRefBuilder encodeUnlinkedTypeRef(builder.BuilderContext builderContext, {int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
@@ -1180,79 +1230,195 @@
 }
 
 class UnlinkedUnit {
-  String _uri;
+  String _libraryName;
+  List<UnlinkedReference> _references;
+  List<UnlinkedClass> _classes;
+  List<UnlinkedEnum> _enums;
+  List<UnlinkedExecutable> _executables;
+  List<UnlinkedExport> _exports;
+  List<UnlinkedImport> _imports;
+  List<UnlinkedPart> _parts;
+  List<UnlinkedTypedef> _typedefs;
+  List<UnlinkedVariable> _variables;
 
   UnlinkedUnit.fromJson(Map json)
-    : _uri = json["uri"];
+    : _libraryName = json["libraryName"],
+      _references = json["references"]?.map((x) => new UnlinkedReference.fromJson(x))?.toList(),
+      _classes = json["classes"]?.map((x) => new UnlinkedClass.fromJson(x))?.toList(),
+      _enums = json["enums"]?.map((x) => new UnlinkedEnum.fromJson(x))?.toList(),
+      _executables = json["executables"]?.map((x) => new UnlinkedExecutable.fromJson(x))?.toList(),
+      _exports = json["exports"]?.map((x) => new UnlinkedExport.fromJson(x))?.toList(),
+      _imports = json["imports"]?.map((x) => new UnlinkedImport.fromJson(x))?.toList(),
+      _parts = json["parts"]?.map((x) => new UnlinkedPart.fromJson(x))?.toList(),
+      _typedefs = json["typedefs"]?.map((x) => new UnlinkedTypedef.fromJson(x))?.toList(),
+      _variables = json["variables"]?.map((x) => new UnlinkedVariable.fromJson(x))?.toList();
 
-  String get uri => _uri ?? '';
+  UnlinkedUnit.fromBuffer(List<int> buffer) : this.fromJson(JSON.decode(UTF8.decode(buffer)));
+
+  String get libraryName => _libraryName ?? '';
+  List<UnlinkedReference> get references => _references ?? const <UnlinkedReference>[];
+  List<UnlinkedClass> get classes => _classes ?? const <UnlinkedClass>[];
+  List<UnlinkedEnum> get enums => _enums ?? const <UnlinkedEnum>[];
+  List<UnlinkedExecutable> get executables => _executables ?? const <UnlinkedExecutable>[];
+  List<UnlinkedExport> get exports => _exports ?? const <UnlinkedExport>[];
+  List<UnlinkedImport> get imports => _imports ?? const <UnlinkedImport>[];
+  List<UnlinkedPart> get parts => _parts ?? const <UnlinkedPart>[];
+  List<UnlinkedTypedef> get typedefs => _typedefs ?? const <UnlinkedTypedef>[];
+  List<UnlinkedVariable> get variables => _variables ?? const <UnlinkedVariable>[];
 }
 
 class UnlinkedUnitBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedUnitBuilder(builder.BuilderContext context);
 
-  void set uri(String _value) {
-    assert(!_json.containsKey("uri"));
+  void set libraryName(String _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("libraryName"));
     if (_value != null) {
-      _json["uri"] = _value;
+      _json["libraryName"] = _value;
     }
   }
 
-  Map finish() => _json;
+  void set references(List<UnlinkedReferenceBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("references"));
+    if (_value != null || _value.isEmpty) {
+      _json["references"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set classes(List<UnlinkedClassBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("classes"));
+    if (_value != null || _value.isEmpty) {
+      _json["classes"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set enums(List<UnlinkedEnumBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("enums"));
+    if (_value != null || _value.isEmpty) {
+      _json["enums"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set executables(List<UnlinkedExecutableBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("executables"));
+    if (_value != null || _value.isEmpty) {
+      _json["executables"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set exports(List<UnlinkedExportBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("exports"));
+    if (_value != null || _value.isEmpty) {
+      _json["exports"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set imports(List<UnlinkedImportBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("imports"));
+    if (_value != null || _value.isEmpty) {
+      _json["imports"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set parts(List<UnlinkedPartBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("parts"));
+    if (_value != null || _value.isEmpty) {
+      _json["parts"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set typedefs(List<UnlinkedTypedefBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("typedefs"));
+    if (_value != null || _value.isEmpty) {
+      _json["typedefs"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  void set variables(List<UnlinkedVariableBuilder> _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("variables"));
+    if (_value != null || _value.isEmpty) {
+      _json["variables"] = _value.map((b) => b.finish()).toList();
+    }
+  }
+
+  List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedUnitBuilder encodeUnlinkedUnit(builder.BuilderContext builderContext, {String uri}) {
+UnlinkedUnitBuilder encodeUnlinkedUnit(builder.BuilderContext builderContext, {String libraryName, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedPartBuilder> parts, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables}) {
   UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder(builderContext);
-  builder.uri = uri;
+  builder.libraryName = libraryName;
+  builder.references = references;
+  builder.classes = classes;
+  builder.enums = enums;
+  builder.executables = executables;
+  builder.exports = exports;
+  builder.imports = imports;
+  builder.parts = parts;
+  builder.typedefs = typedefs;
+  builder.variables = variables;
   return builder;
 }
 
 class UnlinkedVariable {
   String _name;
-  int _unit;
   UnlinkedTypeRef _type;
   bool _isStatic;
   bool _isFinal;
   bool _isConst;
+  bool _hasImplicitType;
 
   UnlinkedVariable.fromJson(Map json)
     : _name = json["name"],
-      _unit = json["unit"],
       _type = json["type"] == null ? null : new UnlinkedTypeRef.fromJson(json["type"]),
       _isStatic = json["isStatic"],
       _isFinal = json["isFinal"],
-      _isConst = json["isConst"];
+      _isConst = json["isConst"],
+      _hasImplicitType = json["hasImplicitType"];
 
   String get name => _name ?? '';
-  int get unit => _unit ?? 0;
   UnlinkedTypeRef get type => _type;
   bool get isStatic => _isStatic ?? false;
   bool get isFinal => _isFinal ?? false;
   bool get isConst => _isConst ?? false;
+  bool get hasImplicitType => _hasImplicitType ?? false;
 }
 
 class UnlinkedVariableBuilder {
   final Map _json = {};
 
+  bool _finished = false;
+
   UnlinkedVariableBuilder(builder.BuilderContext context);
 
   void set name(String _value) {
+    assert(!_finished);
     assert(!_json.containsKey("name"));
     if (_value != null) {
       _json["name"] = _value;
     }
   }
 
-  void set unit(int _value) {
-    assert(!_json.containsKey("unit"));
-    if (_value != null) {
-      _json["unit"] = _value;
-    }
-  }
-
   void set type(UnlinkedTypeRefBuilder _value) {
+    assert(!_finished);
     assert(!_json.containsKey("type"));
     if (_value != null) {
       _json["type"] = _value.finish();
@@ -1260,6 +1426,7 @@
   }
 
   void set isStatic(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isStatic"));
     if (_value != null) {
       _json["isStatic"] = _value;
@@ -1267,6 +1434,7 @@
   }
 
   void set isFinal(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isFinal"));
     if (_value != null) {
       _json["isFinal"] = _value;
@@ -1274,23 +1442,36 @@
   }
 
   void set isConst(bool _value) {
+    assert(!_finished);
     assert(!_json.containsKey("isConst"));
     if (_value != null) {
       _json["isConst"] = _value;
     }
   }
 
-  Map finish() => _json;
+  void set hasImplicitType(bool _value) {
+    assert(!_finished);
+    assert(!_json.containsKey("hasImplicitType"));
+    if (_value != null) {
+      _json["hasImplicitType"] = _value;
+    }
+  }
+
+  Map finish() {
+    assert(!_finished);
+    _finished = true;
+    return _json;
+  }
 }
 
-UnlinkedVariableBuilder encodeUnlinkedVariable(builder.BuilderContext builderContext, {String name, int unit, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst}) {
+UnlinkedVariableBuilder encodeUnlinkedVariable(builder.BuilderContext builderContext, {String name, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst, bool hasImplicitType}) {
   UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder(builderContext);
   builder.name = name;
-  builder.unit = unit;
   builder.type = type;
   builder.isStatic = isStatic;
   builder.isFinal = isFinal;
   builder.isConst = isConst;
+  builder.hasImplicitType = hasImplicitType;
   return builder;
 }
 
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
new file mode 100644
index 0000000..719c2f8
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -0,0 +1,949 @@
+// 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 summary_resynthesizer;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/element.dart';
+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/source_io.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * Callback used by [SummaryResynthesizer] to obtain the prelinked summary for
+ * a given URI.
+ */
+typedef PrelinkedLibrary GetPrelinkedSummaryCallback(String uri);
+
+/**
+ * Callback used by [SummaryResynthesizer] to obtain the unlinked summary for a
+ * given URI.
+ */
+typedef UnlinkedUnit GetUnlinkedSummaryCallback(String uri);
+
+/**
+ * Specialization of [FunctionTypeImpl] used for function types resynthesized
+ * from summaries.
+ */
+class ResynthesizedFunctionTypeImpl extends FunctionTypeImpl
+    with ResynthesizedType {
+  final SummaryResynthesizer summaryResynthesizer;
+
+  ResynthesizedFunctionTypeImpl(
+      FunctionTypeAliasElement element, String name, this.summaryResynthesizer)
+      : super.elementWithName(element, name);
+
+  int get _numTypeParameters {
+    FunctionTypeAliasElement element = this.element;
+    return element.typeParameters.length;
+  }
+}
+
+/**
+ * Specialization of [InterfaceTypeImpl] used for interface types resynthesized
+ * from summaries.
+ */
+class ResynthesizedInterfaceTypeImpl extends InterfaceTypeImpl
+    with ResynthesizedType {
+  final SummaryResynthesizer summaryResynthesizer;
+
+  ResynthesizedInterfaceTypeImpl(
+      ClassElement element, String name, this.summaryResynthesizer)
+      : super.elementWithName(element, name);
+
+  int get _numTypeParameters => element.typeParameters.length;
+}
+
+/**
+ * Common code for types resynthesized from summaries.  This code takes care of
+ * filling in the appropriate number of copies of `dynamic` when it is queried
+ * for type parameters on a bare type reference (i.e. it converts `List` to
+ * `List<dynamic>`).
+ */
+abstract class ResynthesizedType implements DartType {
+  /**
+   * The type arguments, if known.  Otherwise `null`.
+   */
+  List<DartType> _typeArguments;
+
+  SummaryResynthesizer get summaryResynthesizer;
+
+  List<DartType> get typeArguments {
+    if (_typeArguments == null) {
+      // Default to replicating "dynamic" as many times as the class element
+      // requires.
+      _typeArguments = new List<DartType>.filled(
+          _numTypeParameters, summaryResynthesizer.typeProvider.dynamicType);
+    }
+    return _typeArguments;
+  }
+
+  int get _numTypeParameters;
+}
+
+/**
+ * Implementation of [ElementResynthesizer] used when resynthesizing an element
+ * model from summaries.
+ */
+class SummaryResynthesizer extends ElementResynthesizer {
+  /**
+   * Callback used to obtain the prelinked summary for a given URI.
+   */
+  final GetPrelinkedSummaryCallback getPrelinkedSummary;
+
+  /**
+   * Callback used to obtain the unlinked summary for a given URI.
+   */
+  final GetUnlinkedSummaryCallback getUnlinkedSummary;
+
+  /**
+   * Source factory used to convert URIs to [Source] objects.
+   */
+  final SourceFactory sourceFactory;
+
+  /**
+   * Cache of [Source] objects that have already been converted from URIs.
+   */
+  final Map<String, Source> _sources = <String, Source>{};
+
+  /**
+   * The [TypeProvider] used to obtain core types (such as Object, int, List,
+   * and dynamic) during resynthesis.
+   *
+   * TODO(paulberry): will this create a chicken-and-egg problem when trying to
+   * resynthesize the core library from summaries?
+   */
+  final TypeProvider typeProvider;
+
+  /**
+   * Map of top level elements resynthesized from summaries.  The three map
+   * keys are the first three elements of the element's location (the library
+   * URI, the compilation unit URI, and the name of the top level declaration).
+   */
+  final Map<String, Map<String, Map<String, Element>>> _resynthesizedElements =
+      <String, Map<String, Map<String, Element>>>{};
+
+  /**
+   * Map of libraries which have been resynthesized from summaries.  The map
+   * key is the library URI.
+   */
+  final Map<String, LibraryElement> _resynthesizedLibraries =
+      <String, LibraryElement>{};
+
+  SummaryResynthesizer(AnalysisContext context, this.getPrelinkedSummary,
+      this.getUnlinkedSummary, this.sourceFactory)
+      : super(context),
+        typeProvider = context.typeProvider;
+
+  /**
+   * Number of libraries that have been resynthesized so far.
+   */
+  int get resynthesisCount => _resynthesizedLibraries.length;
+
+  @override
+  Element getElement(ElementLocation location) {
+    if (location.components.length == 1) {
+      return getLibraryElement(location.components[0]);
+    } else if (location.components.length == 3) {
+      String uri = location.components[0];
+      Map<String, Map<String, Element>> libraryMap =
+          _resynthesizedElements[uri];
+      if (libraryMap == null) {
+        getLibraryElement(uri);
+        libraryMap = _resynthesizedElements[uri];
+        assert(libraryMap != null);
+      }
+      Map<String, Element> compilationUnitElements =
+          libraryMap[location.components[1]];
+      if (compilationUnitElements != null) {
+        Element element = compilationUnitElements[location.components[2]];
+        if (element != null) {
+          return element;
+        }
+      }
+      throw new Exception('Element not found in summary: $location');
+    } else {
+      throw new UnimplementedError(location.toString());
+    }
+  }
+
+  /**
+   * Get the [LibraryElement] for the given [uri], resynthesizing it if it
+   * hasn't been resynthesized already.
+   */
+  LibraryElement getLibraryElement(String uri) {
+    return _resynthesizedLibraries.putIfAbsent(uri, () {
+      PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri);
+      List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[
+        getUnlinkedSummary(uri)
+      ];
+      Source librarySource = _getSource(uri);
+      for (UnlinkedPart part in serializedUnits[0].parts) {
+        String partAbsUri =
+            sourceFactory.resolveUri(librarySource, part.uri).uri.toString();
+        serializedUnits.add(getUnlinkedSummary(partAbsUri));
+      }
+      _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
+          this, serializedLibrary, serializedUnits, librarySource);
+      LibraryElement library = libraryResynthesizer.buildLibrary();
+      _resynthesizedElements[uri] = libraryResynthesizer.resummarizedElements;
+      return library;
+    });
+  }
+
+  /**
+   * Get the [Source] object for the given [uri].
+   */
+  Source _getSource(String uri) {
+    return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri));
+  }
+}
+
+/**
+ * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
+ * elements in a single library from that library's summary.
+ */
+class _LibraryResynthesizer {
+  /**
+   * The [SummaryResynthesizer] which is being used to obtain summaries.
+   */
+  final SummaryResynthesizer summaryResynthesizer;
+
+  /**
+   * Prelinked summary of the library to be resynthesized.
+   */
+  final PrelinkedLibrary prelinkedLibrary;
+
+  /**
+   * Unlinked compilation units constituting the library to be resynthesized.
+   */
+  final List<UnlinkedUnit> unlinkedUnits;
+
+  /**
+   * [Source] object for the library to be resynthesized.
+   */
+  final Source librarySource;
+
+  /**
+   * [ElementHolder] into which resynthesized elements should be placed.  This
+   * object is recreated afresh for each unit in the library, and is used to
+   * populate the [CompilationUnitElement].
+   */
+  ElementHolder unitHolder;
+
+  /**
+   * The [PrelinkedUnit] from which elements are currently being resynthesized.
+   */
+  PrelinkedUnit prelinkedUnit;
+
+  /**
+   * The [UnlinkedUnit] from which elements are currently being resynthesized.
+   */
+  UnlinkedUnit unlinkedUnit;
+
+  /**
+   * Map of top level elements that have been resynthesized so far.  The first
+   * key is the URI of the compilation unit; the second is the name of the top
+   * level element.
+   */
+  final Map<String, Map<String, Element>> resummarizedElements =
+      <String, Map<String, Element>>{};
+
+  /**
+   * Type parameters for the class or typedef currently being resynthesized.
+   *
+   * TODO(paulberry): extend this to do the right thing for generic methods.
+   */
+  List<TypeParameterElement> currentTypeParameters;
+
+  _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
+      this.unlinkedUnits, this.librarySource);
+
+  /**
+   * Resynthesize a [ClassElement] and place it in [unitHolder].
+   */
+  void buildClass(UnlinkedClass serializedClass) {
+    try {
+      currentTypeParameters =
+          serializedClass.typeParameters.map(buildTypeParameter).toList();
+      for (int i = 0; i < serializedClass.typeParameters.length; i++) {
+        finishTypeParameter(
+            serializedClass.typeParameters[i], currentTypeParameters[i]);
+      }
+      ClassElementImpl classElement =
+          new ClassElementImpl(serializedClass.name, -1);
+      classElement.mixinApplication = serializedClass.isMixinApplication;
+      InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
+      if (serializedClass.supertype != null) {
+        classElement.supertype = buildType(serializedClass.supertype);
+      } else if (!serializedClass.hasNoSupertype) {
+        classElement.supertype = summaryResynthesizer.typeProvider.objectType;
+      }
+      classElement.interfaces =
+          serializedClass.interfaces.map(buildType).toList();
+      classElement.mixins = serializedClass.mixins.map(buildType).toList();
+      classElement.typeParameters = currentTypeParameters;
+      ElementHolder memberHolder = new ElementHolder();
+      bool constructorFound = false;
+      for (UnlinkedExecutable serializedExecutable
+          in serializedClass.executables) {
+        switch (serializedExecutable.kind) {
+          case UnlinkedExecutableKind.constructor:
+            constructorFound = true;
+            buildConstructor(serializedExecutable, memberHolder);
+            break;
+          case UnlinkedExecutableKind.functionOrMethod:
+          case UnlinkedExecutableKind.getter:
+          case UnlinkedExecutableKind.setter:
+            buildExecutable(serializedExecutable, memberHolder);
+            break;
+        }
+      }
+      for (UnlinkedVariable serializedVariable in serializedClass.fields) {
+        buildVariable(serializedVariable, memberHolder);
+      }
+      if (!serializedClass.isMixinApplication) {
+        if (!constructorFound) {
+          // Synthesize implicit constructors.
+          ConstructorElementImpl constructor =
+              new ConstructorElementImpl('', -1);
+          constructor.synthetic = true;
+          constructor.returnType = correspondingType;
+          constructor.type = new FunctionTypeImpl(constructor);
+          memberHolder.addConstructor(constructor);
+        }
+        classElement.constructors = memberHolder.constructors;
+      }
+      classElement.accessors = memberHolder.accessors;
+      classElement.fields = memberHolder.fields;
+      classElement.methods = memberHolder.methods;
+      correspondingType.typeArguments =
+          currentTypeParameters.map((param) => param.type).toList();
+      classElement.type = correspondingType;
+      unitHolder.addType(classElement);
+    } finally {
+      currentTypeParameters = null;
+    }
+  }
+
+  /**
+   * Resynthesize a [NamespaceCombinator].
+   */
+  NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
+    if (serializedCombinator.shows.isNotEmpty) {
+      ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl();
+      combinator.shownNames = serializedCombinator.shows
+          .map((UnlinkedCombinatorName n) => n.name)
+          .toList();
+      return combinator;
+    } else {
+      HideElementCombinatorImpl combinator = new HideElementCombinatorImpl();
+      combinator.hiddenNames = serializedCombinator.hides
+          .map((UnlinkedCombinatorName n) => n.name)
+          .toList();
+      return combinator;
+    }
+  }
+
+  /**
+   * Resynthesize a [ConstructorElement] and place it in the given [holder].
+   */
+  void buildConstructor(
+      UnlinkedExecutable serializedExecutable, ElementHolder holder) {
+    assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor);
+    ConstructorElementImpl constructorElement =
+        new ConstructorElementImpl(serializedExecutable.name, -1);
+    buildExecutableCommonParts(constructorElement, serializedExecutable);
+    constructorElement.factory = serializedExecutable.isFactory;
+    constructorElement.const2 = serializedExecutable.isConst;
+    holder.addConstructor(constructorElement);
+  }
+
+  /**
+   * Resynthesize the [ClassElement] corresponding to an enum, along with the
+   * associated fields and implicit accessors.
+   */
+  void buildEnum(UnlinkedEnum serializedEnum) {
+    // TODO(paulberry): add offset support (for this element type and others)
+    ClassElementImpl classElement =
+        new ClassElementImpl(serializedEnum.name, -1);
+    classElement.enum2 = true;
+    InterfaceType enumType = new InterfaceTypeImpl(classElement);
+    classElement.type = enumType;
+    classElement.supertype = summaryResynthesizer.typeProvider.objectType;
+    ElementHolder memberHolder = new ElementHolder();
+    FieldElementImpl indexField = new FieldElementImpl('index', -1);
+    indexField.final2 = true;
+    indexField.synthetic = true;
+    indexField.type = summaryResynthesizer.typeProvider.intType;
+    memberHolder.addField(indexField);
+    buildImplicitAccessors(indexField, memberHolder);
+    FieldElementImpl valuesField = new ConstFieldElementImpl('values', -1);
+    valuesField.synthetic = true;
+    valuesField.const3 = true;
+    valuesField.static = true;
+    valuesField.type = summaryResynthesizer.typeProvider.listType
+        .substitute4(<DartType>[enumType]);
+    memberHolder.addField(valuesField);
+    buildImplicitAccessors(valuesField, memberHolder);
+    for (UnlinkedEnumValue serializedEnumValue in serializedEnum.values) {
+      ConstFieldElementImpl valueField =
+          new ConstFieldElementImpl(serializedEnumValue.name, -1);
+      valueField.const3 = true;
+      valueField.static = true;
+      valueField.type = enumType;
+      memberHolder.addField(valueField);
+      buildImplicitAccessors(valueField, memberHolder);
+    }
+    classElement.fields = memberHolder.fields;
+    classElement.accessors = memberHolder.accessors;
+    classElement.constructors = <ConstructorElement>[];
+    unitHolder.addEnum(classElement);
+  }
+
+  /**
+   * Resynthesize an [ExecutableElement] and place it in the given [holder].
+   */
+  void buildExecutable(UnlinkedExecutable serializedExecutable,
+      [ElementHolder holder]) {
+    bool isTopLevel = holder == null;
+    if (holder == null) {
+      holder = unitHolder;
+    }
+    UnlinkedExecutableKind kind = serializedExecutable.kind;
+    String name = serializedExecutable.name;
+    if (kind == UnlinkedExecutableKind.setter) {
+      assert(name.endsWith('='));
+      name = name.substring(0, name.length - 1);
+    }
+    switch (kind) {
+      case UnlinkedExecutableKind.functionOrMethod:
+        if (isTopLevel) {
+          FunctionElementImpl executableElement =
+              new FunctionElementImpl(name, -1);
+          buildExecutableCommonParts(executableElement, serializedExecutable);
+          holder.addFunction(executableElement);
+        } else {
+          MethodElementImpl executableElement = new MethodElementImpl(name, -1);
+          buildExecutableCommonParts(executableElement, serializedExecutable);
+          executableElement.static = serializedExecutable.isStatic;
+          holder.addMethod(executableElement);
+        }
+        break;
+      case UnlinkedExecutableKind.getter:
+      case UnlinkedExecutableKind.setter:
+        PropertyAccessorElementImpl executableElement =
+            new PropertyAccessorElementImpl(name, -1);
+        if (isTopLevel) {
+          executableElement.static = true;
+        } else {
+          executableElement.static = serializedExecutable.isStatic;
+        }
+        buildExecutableCommonParts(executableElement, serializedExecutable);
+        DartType type;
+        if (kind == UnlinkedExecutableKind.getter) {
+          executableElement.getter = true;
+          type = executableElement.returnType;
+        } else {
+          executableElement.setter = true;
+          type = executableElement.parameters[0].type;
+        }
+        holder.addAccessor(executableElement);
+        // TODO(paulberry): consider removing implicit variables from the
+        // element model; the spec doesn't call for them, and they cause
+        // trouble when getters/setters exist in different parts.
+        PropertyInducingElementImpl implicitVariable;
+        if (isTopLevel) {
+          implicitVariable = buildImplicitTopLevelVariable(name, kind, holder);
+        } else {
+          FieldElementImpl field = buildImplicitField(name, type, kind, holder);
+          field.static = serializedExecutable.isStatic;
+          implicitVariable = field;
+        }
+        executableElement.variable = implicitVariable;
+        if (kind == UnlinkedExecutableKind.getter) {
+          implicitVariable.getter = executableElement;
+        } else {
+          implicitVariable.setter = executableElement;
+        }
+        // TODO(paulberry): do the right thing when getter and setter are in
+        // different units.
+        break;
+      default:
+        // The only other executable type is a constructor, and that is handled
+        // separately (in [buildConstructor].  So this code should be
+        // unreachable.
+        assert(false);
+    }
+  }
+
+  /**
+   * Handle the parts of an executable element that are common to constructors,
+   * functions, methods, getters, and setters.
+   */
+  void buildExecutableCommonParts(ExecutableElementImpl executableElement,
+      UnlinkedExecutable serializedExecutable) {
+    executableElement.parameters =
+        serializedExecutable.parameters.map(buildParameter).toList();
+    if (serializedExecutable.returnType != null) {
+      executableElement.returnType = buildType(serializedExecutable.returnType);
+    } else {
+      executableElement.returnType = VoidTypeImpl.instance;
+    }
+    executableElement.type = new FunctionTypeImpl(executableElement);
+    executableElement.hasImplicitReturnType =
+        serializedExecutable.hasImplicitReturnType;
+    executableElement.external = serializedExecutable.isExternal;
+  }
+
+  /**
+   * Resynthesize an [ExportElement],
+   */
+  ExportElement buildExport(UnlinkedExport serializedExport) {
+    ExportElementImpl exportElement = new ExportElementImpl(0);
+    String exportedLibraryUri = summaryResynthesizer.sourceFactory
+        .resolveUri(librarySource, serializedExport.uri)
+        .uri
+        .toString();
+    exportElement.exportedLibrary = new LibraryElementHandle(
+        summaryResynthesizer,
+        new ElementLocationImpl.con3(<String>[exportedLibraryUri]));
+    exportElement.uri = serializedExport.uri;
+    exportElement.combinators =
+        serializedExport.combinators.map(buildCombinator).toList();
+    return exportElement;
+  }
+
+  /**
+   * Resynthesize a [FieldElement].
+   */
+  FieldElement buildField(UnlinkedVariable serializedField) {
+    FieldElementImpl fieldElement =
+        new FieldElementImpl(serializedField.name, -1);
+    fieldElement.type = buildType(serializedField.type);
+    fieldElement.const3 = serializedField.isConst;
+    return fieldElement;
+  }
+
+  /**
+   * Build the implicit getter and setter associated with [element], and place
+   * them in [holder].
+   */
+  void buildImplicitAccessors(
+      PropertyInducingElementImpl element, ElementHolder holder) {
+    String name = element.name;
+    DartType type = element.type;
+    PropertyAccessorElementImpl getter =
+        new PropertyAccessorElementImpl(name, -1);
+    getter.getter = true;
+    getter.static = element.isStatic;
+    getter.synthetic = true;
+    getter.returnType = type;
+    getter.type = new FunctionTypeImpl(getter);
+    getter.variable = element;
+    holder.addAccessor(getter);
+    element.getter = getter;
+    if (!(element.isConst || element.isFinal)) {
+      PropertyAccessorElementImpl setter =
+          new PropertyAccessorElementImpl(name, -1);
+      setter.setter = true;
+      setter.static = element.isStatic;
+      setter.synthetic = true;
+      setter.parameters = <ParameterElement>[
+        new ParameterElementImpl('_$name', -1)
+          ..synthetic = true
+          ..type = type
+          ..parameterKind = ParameterKind.REQUIRED
+      ];
+      setter.returnType = VoidTypeImpl.instance;
+      setter.type = new FunctionTypeImpl(setter);
+      setter.variable = element;
+      holder.addAccessor(setter);
+      element.setter = setter;
+    }
+  }
+
+  /**
+   * Build the implicit field associated with a getter or setter, and place it
+   * in [holder].
+   */
+  FieldElementImpl buildImplicitField(String name, DartType type,
+      UnlinkedExecutableKind kind, ElementHolder holder) {
+    if (holder.getField(name) == null) {
+      FieldElementImpl field = new FieldElementImpl(name, -1);
+      field.synthetic = true;
+      field.final2 = kind == UnlinkedExecutableKind.getter;
+      field.type = type;
+      holder.addField(field);
+      return field;
+    } else {
+      // TODO(paulberry): if adding a setter where there was previously
+      // only a getter, remove "final" modifier.
+      // TODO(paulberry): what if the getter and setter have a type mismatch?
+      throw new UnimplementedError();
+    }
+  }
+
+  /**
+   * Build the implicit top level variable associated with a getter or setter,
+   * and place it in [holder].
+   */
+  PropertyInducingElementImpl buildImplicitTopLevelVariable(
+      String name, UnlinkedExecutableKind kind, ElementHolder holder) {
+    if (holder.getTopLevelVariable(name) == null) {
+      TopLevelVariableElementImpl variable =
+          new TopLevelVariableElementImpl(name, -1);
+      variable.synthetic = true;
+      variable.final2 = kind == UnlinkedExecutableKind.getter;
+      holder.addTopLevelVariable(variable);
+      return variable;
+    } else {
+      // TODO(paulberry): if adding a setter where there was previously
+      // only a getter, remove "final" modifier.
+      // TODO(paulberry): what if the getter and setter have a type mismatch?
+      throw new UnimplementedError();
+    }
+  }
+
+  /**
+   * Resynthesize an [ImportElement].
+   */
+  ImportElement buildImport(UnlinkedImport serializedImport, int dependency) {
+    bool isSynthetic = serializedImport.isImplicit;
+    // TODO(paulberry): it seems problematic for the offset to be 0 for
+    // non-synthetic imports, since it is used to disambiguate location.
+    ImportElementImpl importElement =
+        new ImportElementImpl(isSynthetic ? -1 : serializedImport.offset);
+    String absoluteUri = summaryResynthesizer.sourceFactory
+        .resolveUri(
+            librarySource, prelinkedLibrary.dependencies[dependency].uri)
+        .uri
+        .toString();
+    importElement.importedLibrary = new LibraryElementHandle(
+        summaryResynthesizer,
+        new ElementLocationImpl.con3(<String>[absoluteUri]));
+    if (isSynthetic) {
+      importElement.synthetic = true;
+    } else {
+      importElement.uri = serializedImport.uri;
+    }
+    if (serializedImport.prefixReference != 0) {
+      UnlinkedReference serializedPrefix =
+          unlinkedUnits[0].references[serializedImport.prefixReference];
+      importElement.prefix = new PrefixElementImpl(serializedPrefix.name, -1);
+    }
+    importElement.combinators =
+        serializedImport.combinators.map(buildCombinator).toList();
+    return importElement;
+  }
+
+  /**
+   * Main entry point.  Resynthesize the [LibraryElement] and return it.
+   */
+  LibraryElement buildLibrary() {
+    // TODO(paulberry): is it ok to pass -1 for offset and nameLength?
+    LibraryElementImpl libraryElement = new LibraryElementImpl(
+        summaryResynthesizer.context, unlinkedUnits[0].libraryName, -1, -1);
+    CompilationUnitElementImpl definingCompilationUnit =
+        new CompilationUnitElementImpl(librarySource.shortName);
+    libraryElement.definingCompilationUnit = definingCompilationUnit;
+    definingCompilationUnit.source = librarySource;
+    definingCompilationUnit.librarySource = librarySource;
+    List<CompilationUnitElement> parts = <CompilationUnitElement>[];
+    UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
+    assert(
+        unlinkedDefiningUnit.parts.length + 1 == prelinkedLibrary.units.length);
+    for (int i = 1; i < prelinkedLibrary.units.length; i++) {
+      CompilationUnitElementImpl part =
+          buildPart(unlinkedDefiningUnit.parts[i - 1].uri, unlinkedUnits[i]);
+      parts.add(part);
+    }
+    libraryElement.parts = parts;
+    List<ImportElement> imports = <ImportElement>[];
+    for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) {
+      imports.add(buildImport(unlinkedDefiningUnit.imports[i],
+          prelinkedLibrary.importDependencies[i]));
+    }
+    libraryElement.imports = imports;
+    libraryElement.exports =
+        unlinkedDefiningUnit.exports.map(buildExport).toList();
+    populateUnit(definingCompilationUnit, 0);
+    for (int i = 0; i < parts.length; i++) {
+      populateUnit(parts[i], i + 1);
+    }
+    return libraryElement;
+  }
+
+  /**
+   * Resynthesize a [ParameterElement].
+   */
+  ParameterElement buildParameter(UnlinkedParam serializedParameter) {
+    ParameterElementImpl parameterElement =
+        new ParameterElementImpl(serializedParameter.name, -1);
+    if (serializedParameter.isFunctionTyped) {
+      FunctionElementImpl parameterTypeElement =
+          new FunctionElementImpl('', -1);
+      parameterTypeElement.synthetic = true;
+      parameterElement.parameters =
+          serializedParameter.parameters.map(buildParameter).toList();
+      parameterTypeElement.enclosingElement = parameterElement;
+      parameterTypeElement.shareParameters(parameterElement.parameters);
+      if (serializedParameter.type != null) {
+        parameterTypeElement.returnType = buildType(serializedParameter.type);
+      } else {
+        parameterTypeElement.returnType = VoidTypeImpl.instance;
+      }
+      parameterElement.type = new FunctionTypeImpl(parameterTypeElement);
+    } else {
+      parameterElement.type = buildType(serializedParameter.type);
+      parameterElement.hasImplicitType = serializedParameter.hasImplicitType;
+    }
+    switch (serializedParameter.kind) {
+      case UnlinkedParamKind.named:
+        parameterElement.parameterKind = ParameterKind.NAMED;
+        break;
+      case UnlinkedParamKind.positional:
+        parameterElement.parameterKind = ParameterKind.POSITIONAL;
+        break;
+      case UnlinkedParamKind.required:
+        parameterElement.parameterKind = ParameterKind.REQUIRED;
+        break;
+    }
+    return parameterElement;
+  }
+
+  /**
+   * Create, but do not populate, the [CompilationUnitElement] for a part other
+   * than the defining compilation unit.
+   */
+  CompilationUnitElementImpl buildPart(
+      String uri, UnlinkedUnit serializedPart) {
+    Source unitSource =
+        summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+    CompilationUnitElementImpl partUnit =
+        new CompilationUnitElementImpl(unitSource.shortName);
+    partUnit.source = unitSource;
+    partUnit.librarySource = librarySource;
+    partUnit.uri = uri;
+    return partUnit;
+  }
+
+  /**
+   * Build a [DartType] object based on an [UnlinkedTypeRef].  This [DartType]
+   * may refer to elements in other libraries than the library being
+   * deserialized, so handles are used to avoid having to deserialize other
+   * libraries in the process.
+   */
+  DartType buildType(UnlinkedTypeRef type) {
+    if (type.paramReference != 0) {
+      // TODO(paulberry): make this work for generic methods.
+      return currentTypeParameters[
+          currentTypeParameters.length - type.paramReference].type;
+    } else {
+      // TODO(paulberry): handle references to things other than classes (note:
+      // this should only occur in the case of erroneous code).
+      // TODO(paulberry): test reference to something inside a part.
+      // TODO(paulberry): test reference to something inside a part of the
+      // current lib.
+      UnlinkedReference reference = unlinkedUnit.references[type.reference];
+      PrelinkedReference referenceResolution =
+          prelinkedUnit.references[type.reference];
+      String referencedLibraryUri;
+      String partUri;
+      if (referenceResolution.dependency != 0) {
+        PrelinkedDependency dependency =
+            prelinkedLibrary.dependencies[referenceResolution.dependency];
+        Source referencedLibrarySource = summaryResynthesizer.sourceFactory
+            .resolveUri(librarySource, dependency.uri);
+        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).
+        if (referenceResolution.unit != 0) {
+          UnlinkedUnit referencedLibraryDefiningUnit =
+              summaryResynthesizer.getUnlinkedSummary(referencedLibraryUri);
+          String uri = referencedLibraryDefiningUnit.parts[0].uri;
+          Source partSource = summaryResynthesizer.sourceFactory
+              .resolveUri(referencedLibrarySource, uri);
+          partUri = partSource.uri.toString();
+        } else {
+          partUri = referencedLibraryUri;
+        }
+      } else if (referenceResolution.kind ==
+          PrelinkedReferenceKind.unresolved) {
+        return summaryResynthesizer.typeProvider.undefinedType;
+      } else if (reference.name.isEmpty) {
+        return summaryResynthesizer.typeProvider.dynamicType;
+      } else {
+        referencedLibraryUri = librarySource.uri.toString();
+        if (referenceResolution.unit != 0) {
+          String uri = unlinkedUnits[0].parts[referenceResolution.unit - 1].uri;
+          Source partSource =
+              summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+          partUri = partSource.uri.toString();
+        } else {
+          partUri = referencedLibraryUri;
+        }
+      }
+      ResynthesizedType resynthesizedType;
+      ElementLocationImpl location = new ElementLocationImpl.con3(
+          <String>[referencedLibraryUri, partUri, reference.name]);
+      switch (referenceResolution.kind) {
+        case PrelinkedReferenceKind.classOrEnum:
+          resynthesizedType = new ResynthesizedInterfaceTypeImpl(
+              new ClassElementHandle(summaryResynthesizer, location),
+              reference.name,
+              summaryResynthesizer);
+          break;
+        case PrelinkedReferenceKind.typedef:
+          resynthesizedType = new ResynthesizedFunctionTypeImpl(
+              new FunctionTypeAliasElementHandle(
+                  summaryResynthesizer, location),
+              reference.name,
+              summaryResynthesizer);
+          break;
+        default:
+          // TODO(paulberry): figure out how to handle this case (which should
+          // only occur in the event of erroneous code).
+          throw new UnimplementedError();
+      }
+      if (type.typeArguments.isNotEmpty) {
+        resynthesizedType._typeArguments =
+            type.typeArguments.map(buildType).toList();
+      }
+      return resynthesizedType;
+    }
+  }
+
+  /**
+   * Resynthesize a [FunctionTypeAliasElement] and place it in the
+   * [unitHolder].
+   */
+  void buildTypedef(UnlinkedTypedef serializedTypedef) {
+    try {
+      currentTypeParameters =
+          serializedTypedef.typeParameters.map(buildTypeParameter).toList();
+      for (int i = 0; i < serializedTypedef.typeParameters.length; i++) {
+        finishTypeParameter(
+            serializedTypedef.typeParameters[i], currentTypeParameters[i]);
+      }
+      FunctionTypeAliasElementImpl functionTypeAliasElement =
+          new FunctionTypeAliasElementImpl(serializedTypedef.name, -1);
+      functionTypeAliasElement.parameters =
+          serializedTypedef.parameters.map(buildParameter).toList();
+      if (serializedTypedef.returnType != null) {
+        functionTypeAliasElement.returnType =
+            buildType(serializedTypedef.returnType);
+      } else {
+        functionTypeAliasElement.returnType = VoidTypeImpl.instance;
+      }
+      functionTypeAliasElement.type =
+          new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
+      functionTypeAliasElement.typeParameters = currentTypeParameters;
+      unitHolder.addTypeAlias(functionTypeAliasElement);
+    } finally {
+      currentTypeParameters = null;
+    }
+  }
+
+  /**
+   * Resynthesize a [TypeParameterElement], handling all parts of its except
+   * its bound.
+   *
+   * The bound is deferred until later since it may refer to other type
+   * parameters that have not been resynthesized yet.  To handle the bound,
+   * call [finishTypeParameter].
+   */
+  TypeParameterElement buildTypeParameter(
+      UnlinkedTypeParam serializedTypeParameter) {
+    TypeParameterElementImpl typeParameterElement =
+        new TypeParameterElementImpl(serializedTypeParameter.name, -1);
+    typeParameterElement.type = new TypeParameterTypeImpl(typeParameterElement);
+    return typeParameterElement;
+  }
+
+  /**
+   * Resynthesize a [TopLevelVariableElement] or [FieldElement].
+   */
+  void buildVariable(UnlinkedVariable serializedVariable,
+      [ElementHolder holder]) {
+    if (holder == null) {
+      TopLevelVariableElementImpl element =
+          new TopLevelVariableElementImpl(serializedVariable.name, -1);
+      buildVariableCommonParts(element, serializedVariable);
+      unitHolder.addTopLevelVariable(element);
+      buildImplicitAccessors(element, unitHolder);
+    } else {
+      FieldElementImpl element =
+          new FieldElementImpl(serializedVariable.name, -1);
+      buildVariableCommonParts(element, serializedVariable);
+      element.static = serializedVariable.isStatic;
+      holder.addField(element);
+      buildImplicitAccessors(element, holder);
+    }
+  }
+
+  /**
+   * Handle the parts that are common to top level variables and fields.
+   */
+  void buildVariableCommonParts(PropertyInducingElementImpl element,
+      UnlinkedVariable serializedVariable) {
+    element.type = buildType(serializedVariable.type);
+    element.const3 = serializedVariable.isConst;
+  }
+
+  /**
+   * Finish creating a [TypeParameterElement] by deserializing its bound.
+   */
+  void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
+      TypeParameterElementImpl typeParameterElement) {
+    if (serializedTypeParameter.bound != null) {
+      typeParameterElement.bound = buildType(serializedTypeParameter.bound);
+    }
+  }
+
+  /**
+   * Populate a [CompilationUnitElement] by deserializing all the elements
+   * contained in it.
+   */
+  void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
+    prelinkedUnit = prelinkedLibrary.units[unitNum];
+    unlinkedUnit = unlinkedUnits[unitNum];
+    unitHolder = new ElementHolder();
+    unlinkedUnit.classes.forEach(buildClass);
+    unlinkedUnit.enums.forEach(buildEnum);
+    unlinkedUnit.executables.forEach(buildExecutable);
+    unlinkedUnit.typedefs.forEach(buildTypedef);
+    unlinkedUnit.variables.forEach(buildVariable);
+    String absoluteUri = unit.source.uri.toString();
+    unit.accessors = unitHolder.accessors;
+    unit.enums = unitHolder.enums;
+    unit.functions = unitHolder.functions;
+    List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
+    for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
+      if (typeAlias.isSynthetic) {
+        typeAlias.enclosingElement = unit;
+      }
+    }
+    unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
+    unit.types = unitHolder.types;
+    unit.topLevelVariables = unitHolder.topLevelVariables;
+    Map<String, Element> elementMap = <String, Element>{};
+    for (ClassElement cls in unit.types) {
+      elementMap[cls.name] = cls;
+    }
+    for (ClassElement cls in unit.enums) {
+      elementMap[cls.name] = cls;
+    }
+    for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
+      elementMap[typeAlias.name] = typeAlias;
+    }
+    resummarizedElements[absoluteUri] = elementMap;
+    unitHolder = null;
+    prelinkedUnit = null;
+    unlinkedUnit = null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 1ad8dd7..9a13020 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -4,7 +4,9 @@
 
 library serialization.elements;
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/builder.dart';
@@ -14,9 +16,37 @@
  * Serialize all the elements in [lib] to a summary using [ctx] as the context
  * for building the summary, and using [typeProvider] to find built-in types.
  */
-PrelinkedLibraryBuilder serializeLibrary(
+LibrarySerializationResult serializeLibrary(
     BuilderContext ctx, LibraryElement lib, TypeProvider typeProvider) {
-  return new _LibrarySerializer(ctx, lib, typeProvider).serializeLibrary();
+  var serializer = new _LibrarySerializer(ctx, lib, typeProvider);
+  PrelinkedLibraryBuilder prelinked = serializer.serializeLibrary();
+  return new LibrarySerializationResult(
+      prelinked, serializer.unlinkedUnits, serializer.unitUris);
+}
+
+/**
+ * Data structure holding the result of serializing a [LibraryElement].
+ */
+class LibrarySerializationResult {
+  /**
+   * Pre-linked information the given library.
+   */
+  final PrelinkedLibraryBuilder prelinked;
+
+  /**
+   * Unlinked information for the compilation units constituting the library.
+   * The zeroth entry in the list is the defining compilation unit; the
+   * remaining entries are the parts, in the order listed in the defining
+   * compilation unit's part declarations.
+   */
+  final List<UnlinkedUnitBuilder> unlinkedUnits;
+
+  /**
+   * Absolute URI of each compilation unit appearing in the library.
+   */
+  final List<String> unitUris;
+
+  LibrarySerializationResult(this.prelinked, this.unlinkedUnits, this.unitUris);
 }
 
 /**
@@ -35,35 +65,20 @@
   final TypeProvider typeProvider;
 
   /**
-   * List of objects which should be written to [UnlinkedLibrary.classes].
+   * List of objects which should be written to [PrelinkedLibrary.units].
    */
-  final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
+  final List<PrelinkedUnitBuilder> prelinkedUnits = <PrelinkedUnitBuilder>[];
 
   /**
-   * List of objects which should be written to [UnlinkedLibrary.enums].
+   * List of unlinked units corresponding to the pre-linked units in
+   * [prelinkedUnits],
    */
-  final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
+  final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
 
   /**
-   * List of objects which should be written to [UnlinkedLibrary.executables].
+   * List of absolute URIs of the compilation units in the library.
    */
-  final List<UnlinkedExecutableBuilder> executables =
-      <UnlinkedExecutableBuilder>[];
-
-  /**
-   * List of objects which should be written to [UnlinkedLibrary.typedefs].
-   */
-  final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
-
-  /**
-   * List of objects which should be written to [UnlinkedLibrary.units].
-   */
-  final List<UnlinkedUnitBuilder> units = <UnlinkedUnitBuilder>[];
-
-  /**
-   * List of objects which should be written to [UnlinkedLibrary.variables].
-   */
-  final List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
+  final List<String> unitUris = <String>[];
 
   /**
    * Map from [LibraryElement] to the index of the entry in the "dependency
@@ -79,30 +94,12 @@
       <PrelinkedDependencyBuilder>[];
 
   /**
-   * The unlinked portion of the "imports table".  This is the list of objects
-   * which should be written to [UnlinkedLibrary.imports].
-   */
-  final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
-
-  /**
    * The prelinked portion of the "imports table".  This is the list of ints
    * which should be written to [PrelinkedLibrary.imports].
    */
   final List<int> prelinkedImports = <int>[];
 
   /**
-   * Map from prefix [String] to the index of the entry in the "prefix" table
-   * that refers to it.  The empty prefix is not included in this map.
-   */
-  final Map<String, int> prefixMap = <String, int>{};
-
-  /**
-   * The "prefix table".  This is the list of objects which should be written
-   * to [UnlinkedLibrary.prefixes].
-   */
-  final List<UnlinkedPrefixBuilder> prefixes = <UnlinkedPrefixBuilder>[];
-
-  /**
    * Map from [Element] to the index of the entry in the "references table"
    * that refers to it.
    */
@@ -110,28 +107,19 @@
 
   /**
    * The unlinked portion of the "references table".  This is the list of
-   * objects which should be written to [UnlinkedLibrary.references].
+   * objects which should be written to [UnlinkedUnit.references].
    */
-  final List<UnlinkedReferenceBuilder> unlinkedReferences =
-      <UnlinkedReferenceBuilder>[];
+  List<UnlinkedReferenceBuilder> unlinkedReferences;
 
   /**
    * The prelinked portion of the "references table".  This is the list of
-   * objects which should be written to [PrelinkedLibrary.references].
+   * objects which should be written to [PrelinkedUnit.references].
    */
-  final List<PrelinkedReferenceBuilder> prelinkedReferences =
-      <PrelinkedReferenceBuilder>[];
+  List<PrelinkedReferenceBuilder> prelinkedReferences;
 
   //final Map<String, int> prefixIndices = <String, int>{};
 
   /**
-   * Index into the "references table" representing `dynamic`, if such an index
-   * exists.  `null` if no such entry has been made in the references table
-   * yet.
-   */
-  int dynamicReferenceIndex = null;
-
-  /**
    * Index into the "references table" representing an unresolved reference, if
    * such an index exists.  `null` if no such entry has been made in the
    * references table yet.
@@ -153,7 +141,6 @@
   _LibrarySerializer(this.ctx, this.libraryElement, this.typeProvider) {
     dependencies.add(encodePrelinkedDependency(ctx));
     dependencyMap[libraryElement] = 0;
-    prefixes.add(encodeUnlinkedPrefix(ctx));
   }
 
   /**
@@ -169,33 +156,58 @@
    */
   void addCompilationUnitElements(CompilationUnitElement element, int unitNum) {
     UnlinkedUnitBuilder b = new UnlinkedUnitBuilder(ctx);
-    if (element.uri != null) {
-      b.uri = element.uri;
+    unlinkedReferences = <UnlinkedReferenceBuilder>[
+      encodeUnlinkedReference(ctx)
+    ];
+    prelinkedReferences = <PrelinkedReferenceBuilder>[
+      encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.classOrEnum)
+    ];
+    if (unitNum == 0) {
+      // TODO(paulberry): we need to figure out a way to record library, part,
+      // import, and export declarations that appear in non-defining
+      // compilation units (even though such declarations are prohibited by the
+      // language), so that if the user makes code changes that cause a
+      // non-defining compilation unit to become a defining compilation unit,
+      // we can create a correct summary by simply re-linking.
+      if (libraryElement.name.isNotEmpty) {
+        b.libraryName = libraryElement.name;
+      }
+      b.exports = libraryElement.exports.map(serializeExport).toList();
+      b.imports = libraryElement.imports.map(serializeImport).toList();
+      b.parts = libraryElement.parts
+          .map(
+              (CompilationUnitElement e) => encodeUnlinkedPart(ctx, uri: e.uri))
+          .toList();
     }
-    units.add(b);
-    for (ClassElement cls in element.types) {
-      classes.add(serializeClass(cls, unitNum));
-    }
-    for (ClassElement e in element.enums) {
-      enums.add(serializeEnum(e, unitNum));
-    }
-    for (FunctionTypeAliasElement type in element.functionTypeAliases) {
-      typedefs.add(serializeTypedef(type, unitNum));
-    }
-    for (FunctionElement executable in element.functions) {
-      executables.add(serializeExecutable(executable, unitNum));
-    }
+    b.classes = element.types.map(serializeClass).toList();
+    b.enums = element.enums.map(serializeEnum).toList();
+    b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList();
+    List<UnlinkedExecutableBuilder> executables =
+        element.functions.map(serializeExecutable).toList();
     for (PropertyAccessorElement accessor in element.accessors) {
       if (!accessor.isSynthetic) {
-        executables.add(serializeExecutable(accessor, unitNum));
-      } else if (accessor.isGetter) {
+        executables.add(serializeExecutable(accessor));
+      }
+    }
+    b.executables = executables;
+    List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
+    for (PropertyAccessorElement accessor in element.accessors) {
+      if (accessor.isSynthetic && accessor.isGetter) {
         PropertyInducingElement variable = accessor.variable;
         if (variable != null) {
           assert(!variable.isSynthetic);
-          variables.add(serializeVariable(variable, unitNum));
+          variables.add(serializeVariable(variable));
         }
       }
     }
+    b.variables = variables;
+    b.references = unlinkedReferences;
+    unlinkedUnits.add(b);
+    prelinkedUnits
+        .add(encodePrelinkedUnit(ctx, references: prelinkedReferences));
+    unitUris.add(element.source.uri.toString());
+    unlinkedReferences = null;
+    prelinkedReferences = null;
   }
 
   /**
@@ -242,16 +254,16 @@
   }
 
   /**
-   * Serialize the given [classElement], which exists in the unit numbered
-   * [unitNum], creating an [UnlinkedClass].
+   * Serialize the given [classElement], creating an [UnlinkedClass].
    */
-  UnlinkedClassBuilder serializeClass(ClassElement classElement, int unitNum) {
+  UnlinkedClassBuilder serializeClass(ClassElement classElement) {
     UnlinkedClassBuilder b = new UnlinkedClassBuilder(ctx);
     b.name = classElement.name;
-    b.unit = unitNum;
     b.typeParameters =
         classElement.typeParameters.map(serializeTypeParam).toList();
-    if (classElement.supertype != null && !classElement.supertype.isObject) {
+    if (classElement.supertype == null) {
+      b.hasNoSupertype = true;
+    } else if (!classElement.supertype.isObject) {
       b.supertype = serializeTypeRef(classElement.supertype, classElement);
     }
     b.mixins = classElement.mixins
@@ -264,19 +276,19 @@
     List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
     for (ConstructorElement executable in classElement.constructors) {
       if (!executable.isSynthetic) {
-        executables.add(serializeExecutable(executable, 0));
+        executables.add(serializeExecutable(executable));
       }
     }
     for (MethodElement executable in classElement.methods) {
-      executables.add(serializeExecutable(executable, 0));
+      executables.add(serializeExecutable(executable));
     }
     for (PropertyAccessorElement accessor in classElement.accessors) {
       if (!accessor.isSynthetic) {
-        executables.add(serializeExecutable(accessor, 0));
+        executables.add(serializeExecutable(accessor));
       } else if (accessor.isGetter) {
         PropertyInducingElement field = accessor.variable;
         if (field != null && !field.isSynthetic) {
-          fields.add(serializeVariable(field, 0));
+          fields.add(serializeVariable(field));
         }
       }
     }
@@ -325,25 +337,14 @@
   /**
    * Return the index of the entry in the references table
    * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references])
-   * representing the pseudo-type `dynamic`.  A new entry is added to the table
-   * if necessary to satisfy the request.
+   * representing the pseudo-type `dynamic`.
    */
-  int serializeDynamicReference() {
-    if (dynamicReferenceIndex == null) {
-      assert(unlinkedReferences.length == prelinkedReferences.length);
-      dynamicReferenceIndex = unlinkedReferences.length;
-      unlinkedReferences.add(encodeUnlinkedReference(ctx));
-      prelinkedReferences.add(encodePrelinkedReference(ctx,
-          kind: PrelinkedReferenceKind.classOrEnum));
-    }
-    return dynamicReferenceIndex;
-  }
+  int serializeDynamicReference() => 0;
 
   /**
-   * Serialize the given [enumElement], which exists in the unit numbered
-   * [unitNum], creating an [UnlinkedEnum].
+   * Serialize the given [enumElement], creating an [UnlinkedEnum].
    */
-  UnlinkedEnumBuilder serializeEnum(ClassElement enumElement, int unitNum) {
+  UnlinkedEnumBuilder serializeEnum(ClassElement enumElement) {
     UnlinkedEnumBuilder b = new UnlinkedEnumBuilder(ctx);
     b.name = enumElement.name;
     List<UnlinkedEnumValueBuilder> values = <UnlinkedEnumValueBuilder>[];
@@ -353,23 +354,16 @@
       }
     }
     b.values = values;
-    b.unit = unitNum;
     return b;
   }
 
   /**
-   * Serialize the given [executableElement], which exists in the unit numbered
-   * [unitNum], creating an [UnlinkedExecutable].  For elements declared inside
-   * a class, [unitNum] should be zero.
+   * Serialize the given [executableElement], creating an [UnlinkedExecutable].
    */
   UnlinkedExecutableBuilder serializeExecutable(
-      ExecutableElement executableElement, int unitNum) {
-    if (executableElement.enclosingElement is ClassElement) {
-      assert(unitNum == 0);
-    }
+      ExecutableElement executableElement) {
     UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder(ctx);
     b.name = executableElement.name;
-    b.unit = unitNum;
     if (!executableElement.type.returnType.isVoid) {
       b.returnType = serializeTypeRef(
           executableElement.type.returnType, executableElement);
@@ -394,6 +388,8 @@
     b.isAbstract = executableElement.isAbstract;
     b.isStatic = executableElement.isStatic &&
         executableElement.enclosingElement is ClassElement;
+    b.hasImplicitReturnType = executableElement.hasImplicitReturnType;
+    b.isExternal = executableElement.isExternal;
     return b;
   }
 
@@ -408,22 +404,16 @@
   }
 
   /**
-   * Serialize the given [importElement], adding information about it to
-   * the [unlinkedImports] and [prelinkedImports] lists.
+   * Serialize the given [importElement] yielding an [UnlinkedImportBuilder].
+   * Also, add pre-linked information about it to the [prelinkedImports] list.
    */
-  void serializeImport(ImportElement importElement) {
-    assert(unlinkedImports.length == prelinkedImports.length);
+  UnlinkedImportBuilder serializeImport(ImportElement importElement) {
     UnlinkedImportBuilder b = new UnlinkedImportBuilder(ctx);
     b.isDeferred = importElement.isDeferred;
     b.offset = importElement.nameOffset;
     b.combinators = importElement.combinators.map(serializeCombinator).toList();
     if (importElement.prefix != null) {
-      b.prefix = prefixMap.putIfAbsent(importElement.prefix.name, () {
-        int index = prefixes.length;
-        prefixes
-            .add(encodeUnlinkedPrefix(ctx, name: importElement.prefix.name));
-        return index;
-      });
+      b.prefixReference = serializePrefix(importElement.prefix);
     }
     if (importElement.isSynthetic) {
       b.isImplicit = true;
@@ -431,41 +421,26 @@
       b.uri = importElement.uri;
     }
     addTransitiveExportClosure(importElement.importedLibrary);
-    unlinkedImports.add(b);
     prelinkedImports.add(serializeDependency(importElement.importedLibrary));
+    return b;
   }
 
   /**
    * Serialize the whole library element into a [PrelinkedLibrary].  Should be
    * called exactly once for each instance of [_LibrarySerializer].
+   *
+   * The unlinked compilation units are stored in [unlinkedUnits], and their
+   * absolute URIs are stored in [unitUris].
    */
   PrelinkedLibraryBuilder serializeLibrary() {
-    UnlinkedLibraryBuilder ub = new UnlinkedLibraryBuilder(ctx);
     PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder(ctx);
-    if (libraryElement.name.isNotEmpty) {
-      ub.name = libraryElement.name;
-    }
-    for (ImportElement importElement in libraryElement.imports) {
-      serializeImport(importElement);
-    }
-    ub.exports = libraryElement.exports.map(serializeExport).toList();
     addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
     for (int i = 0; i < libraryElement.parts.length; i++) {
       addCompilationUnitElements(libraryElement.parts[i], i + 1);
     }
-    ub.classes = classes;
-    ub.enums = enums;
-    ub.executables = executables;
-    ub.imports = unlinkedImports;
-    ub.prefixes = prefixes;
-    ub.references = unlinkedReferences;
-    ub.typedefs = typedefs;
-    ub.units = units;
-    ub.variables = variables;
-    pb.unlinked = ub;
+    pb.units = prelinkedUnits;
     pb.dependencies = dependencies;
     pb.importDependencies = prelinkedImports;
-    pb.references = prelinkedReferences;
     return pb;
   }
 
@@ -496,19 +471,32 @@
       b.parameters = type.parameters.map(serializeParam).toList();
     } else {
       b.type = serializeTypeRef(type, parameter);
+      b.hasImplicitType = parameter.hasImplicitType;
     }
     return b;
   }
 
   /**
-   * Serialize the given [typedefElement], which exists in the unit numbered
-   * [unitNum], creating an [UnlinkedTypedef].
+   * Serialize the given [prefix] into an index into the references table.
+   */
+  int serializePrefix(PrefixElement element) {
+    return referenceMap.putIfAbsent(element, () {
+      assert(unlinkedReferences.length == prelinkedReferences.length);
+      int index = unlinkedReferences.length;
+      unlinkedReferences.add(encodeUnlinkedReference(ctx, name: element.name));
+      prelinkedReferences.add(
+          encodePrelinkedReference(ctx, kind: PrelinkedReferenceKind.prefix));
+      return index;
+    });
+  }
+
+  /**
+   * Serialize the given [typedefElement], creating an [UnlinkedTypedef].
    */
   UnlinkedTypedefBuilder serializeTypedef(
-      FunctionTypeAliasElement typedefElement, int unitNum) {
+      FunctionTypeAliasElement typedefElement) {
     UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder(ctx);
     b.name = typedefElement.name;
-    b.unit = unitNum;
     b.typeParameters =
         typedefElement.typeParameters.map(serializeTypeParam).toList();
     if (!typedefElement.returnType.isVoid) {
@@ -538,12 +526,9 @@
   UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) {
     UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder(ctx);
     if (type is TypeParameterType) {
-      Element enclosingElement = type.element.enclosingElement;
       b.paramReference = findTypeParameterIndex(type, context);
     } else {
       Element element = type.element;
-      CompilationUnitElement dependentCompilationUnit =
-          element.getAncestor((Element e) => e is CompilationUnitElement);
       LibraryElement dependentLibrary = element.library;
       if (dependentLibrary == null) {
         assert(type.isDynamic);
@@ -609,22 +594,16 @@
   }
 
   /**
-   * Serialize the given [variable], which exists in the unit numbered
-   * [unitNum], creating an [UnlinkedVariable].  For variables declared inside
-   * a class (i.e. fields), [unitNum] should be zero.
+   * Serialize the given [variable], creating an [UnlinkedVariable].
    */
-  UnlinkedVariableBuilder serializeVariable(
-      PropertyInducingElement variable, int unitNum) {
-    if (variable.enclosingElement is ClassElement) {
-      assert(unitNum == 0);
-    }
+  UnlinkedVariableBuilder serializeVariable(PropertyInducingElement variable) {
     UnlinkedVariableBuilder b = new UnlinkedVariableBuilder(ctx);
     b.name = variable.name;
-    b.unit = unitNum;
     b.type = serializeTypeRef(variable.type, variable);
     b.isStatic = variable.isStatic && variable.enclosingElement is ClassElement;
     b.isFinal = variable.isFinal;
     b.isConst = variable.isConst;
+    b.hasImplicitType = variable.hasImplicitType;
     return b;
   }
 }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 773515c..5a64d4c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -6,10 +6,12 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/error_verifier.dart';
@@ -78,12 +80,12 @@
  * A list of the [ConstantEvaluationTarget]s defined in a unit.  This includes
  * constants defined at top level, statically inside classes, and local to
  * functions, as well as constant constructors, annotations, and default values
- * of parameters to constant constructors.
+ * of parameters.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
-final ListResultDescriptor<
-        ConstantEvaluationTarget> COMPILATION_UNIT_CONSTANTS =
+final ListResultDescriptor<ConstantEvaluationTarget>
+    COMPILATION_UNIT_CONSTANTS =
     new ListResultDescriptor<ConstantEvaluationTarget>(
         'COMPILATION_UNIT_CONSTANTS', null,
         cachingPolicy: ELEMENT_CACHING_POLICY);
@@ -111,6 +113,18 @@
         'CONSTANT_DEPENDENCIES', const <ConstantEvaluationTarget>[]);
 
 /**
+ * The list of [ConstantEvaluationTarget]s on which constant expressions of a
+ * unit depend.
+ *
+ * The result is only available for [LibrarySpecificUnit]s.
+ */
+final ListResultDescriptor<ConstantEvaluationTarget>
+    CONSTANT_EXPRESSIONS_DEPENDENCIES =
+    new ListResultDescriptor<ConstantEvaluationTarget>(
+        'CONSTANT_EXPRESSIONS_DEPENDENCIES',
+        const <ConstantEvaluationTarget>[]);
+
+/**
  * A [ConstantEvaluationTarget] that has been successfully constant-evaluated.
  *
  * TODO(paulberry): is ELEMENT_CACHING_POLICY the correct caching policy?
@@ -157,8 +171,8 @@
  * The result is only available for [VariableElement]s, and only when strong
  * mode is enabled.
  */
-final ListResultDescriptor<
-        VariableElement> INFERABLE_STATIC_VARIABLE_DEPENDENCIES =
+final ListResultDescriptor<VariableElement>
+    INFERABLE_STATIC_VARIABLE_DEPENDENCIES =
     new ListResultDescriptor<VariableElement>(
         'INFERABLE_STATIC_VARIABLE_DEPENDENCIES', null);
 
@@ -306,6 +320,17 @@
         cachingPolicy: ELEMENT_CACHING_POLICY);
 
 /**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * The same as a [LIBRARY_ELEMENT7].
+ *
+ * The result is only available for [Source]s representing a library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT8 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT8', null,
+        cachingPolicy: ELEMENT_CACHING_POLICY);
+
+/**
  * The flag specifying whether all analysis errors are computed in a specific
  * library.
  *
@@ -416,7 +441,7 @@
 
 /**
  * The flag specifying that [RESOLVED_UNIT] is ready for all of the units of a
- * library and its import/export closure.
+ * library.
  *
  * The result is only available for [Source]s representing a library.
  */
@@ -756,8 +781,9 @@
     ConstantFinder constantFinder =
         new ConstantFinder(context, source, librarySpecificUnit.library);
     unit.accept(constantFinder);
-    List<ConstantEvaluationTarget> constants = new List<
-        ConstantEvaluationTarget>.from(constantFinder.constantsToCompute);
+    List<ConstantEvaluationTarget> constants =
+        new List<ConstantEvaluationTarget>.from(
+            constantFinder.constantsToCompute);
     //
     // Record outputs.
     //
@@ -894,7 +920,7 @@
             importElement.deferred = importDirective.deferredKeyword != null;
             importElement.combinators = _buildCombinators(importDirective);
             importElement.importedLibrary = importedLibrary;
-            _setDocRange(importElement, importDirective);
+            _setDoc(importElement, importDirective);
             SimpleIdentifier prefixNode = directive.prefix;
             if (prefixNode != null) {
               importElement.prefixOffset = prefixNode.offset;
@@ -936,7 +962,7 @@
             exportElement.uri = exportDirective.uriContent;
             exportElement.combinators = _buildCombinators(exportDirective);
             exportElement.exportedLibrary = exportedLibrary;
-            _setDocRange(exportElement, exportDirective);
+            _setDoc(exportElement, exportDirective);
             directive.element = exportElement;
             exports.add(exportElement);
             if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
@@ -977,12 +1003,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  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);
     }
   }
@@ -1353,7 +1381,7 @@
       _patchTopLevelAccessors(libraryElement);
     }
     if (libraryDirective != null) {
-      _setDocRange(libraryElement, libraryDirective);
+      _setDoc(libraryElement, libraryDirective);
     }
     //
     // Record outputs.
@@ -1441,12 +1469,14 @@
   }
 
   /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
    */
-  void _setDocRange(ElementImpl element, AnnotatedNode node) {
+  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);
     }
   }
@@ -1875,7 +1905,8 @@
    * Return `true` if the given [variable] is a static variable whose type
    * should be inferred.
    */
-  bool _isInferableStatic(VariableElement variable) => variable.isStatic &&
+  bool _isInferableStatic(VariableElement variable) =>
+      variable.isStatic &&
       variable.hasImplicitType &&
       variable.initializer != null;
 
@@ -2060,9 +2091,9 @@
    */
   bool _isPropagable(VariableElement variable) =>
       variable is PropertyInducingElement &&
-          (variable.isConst || variable.isFinal) &&
-          variable.hasImplicitType &&
-          variable.initializer != null;
+      (variable.isConst || variable.isFinal) &&
+      variable.hasImplicitType &&
+      variable.initializer != null;
 
   /**
    * Return a map from the names of the inputs of this kind of task to the task
@@ -2391,10 +2422,12 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      'libraryElement': LIBRARY_ELEMENT.of(unit.library),
+      'libraryElement': LIBRARY_ELEMENT8.of(unit.library),
       UNIT_INPUT: RESOLVED_UNIT10.of(unit),
       CONSTANT_VALUES:
-          COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE)
+          COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
+      'constantExpressionsDependencies':
+          CONSTANT_EXPRESSIONS_DEPENDENCIES.of(unit).toListOf(CONSTANT_VALUE)
     };
   }
 
@@ -3201,7 +3234,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      'allErrors': UNITS.of(source).toListOf(DART_ERRORS)
+      'allErrors': UNITS.of(source).toListOf(DART_ERRORS),
+      'libraryElement': LIBRARY_ELEMENT.of(source)
     };
   }
 
@@ -4200,10 +4234,6 @@
     return <String, TaskInput>{
       'thisLibraryUnitsReady':
           LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT),
-      'directlyImportedLibrariesReady':
-          IMPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT),
-      'directlyExportedLibrariesReady':
-          EXPORTED_LIBRARIES.of(source).toListOf(READY_RESOLVED_UNIT),
     };
   }
 
@@ -4426,11 +4456,11 @@
 
 /**
  * A task that finishes resolution by requesting [RESOLVED_UNIT10] for every
- * unit in the libraries closure and produces [LIBRARY_ELEMENT].
+ * unit in the libraries closure and produces [LIBRARY_ELEMENT8].
  */
 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [LIBRARY_ELEMENT5] input.
+   * The name of the [LIBRARY_ELEMENT7] input.
    */
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
@@ -4446,7 +4476,7 @@
       'ResolveLibraryReferencesTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]);
+      <ResultDescriptor>[LIBRARY_ELEMENT8, REFERENCED_NAMES]);
 
   ResolveLibraryReferencesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -4470,7 +4500,7 @@
     //
     // Record outputs.
     //
-    outputs[LIBRARY_ELEMENT] = library;
+    outputs[LIBRARY_ELEMENT8] = library;
     outputs[REFERENCED_NAMES] = referencedNames;
   }
 
@@ -4482,9 +4512,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      LIBRARY_INPUT: LIBRARY_ELEMENT5.of(source),
+      LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
       UNITS_INPUT: LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT10),
-      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT10.of(source),
     };
   }
 
@@ -4499,6 +4528,71 @@
 }
 
 /**
+ * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
+ * unit in the libraries closure and produces [LIBRARY_ELEMENT].
+ */
+class ResolveLibraryTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT8] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The name of the list of [RESOLVED_UNIT11] input.
+   */
+  static const String UNITS_INPUT = 'UNITS_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolveLibraryTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT]);
+
+  ResolveLibraryTask(InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    //
+    // Record outputs.
+    //
+    outputs[LIBRARY_ELEMENT] = library;
+  }
+
+/**
+ * Return a map from the names of the inputs of this kind of task to the task
+ * input descriptors describing those inputs for a task with the
+ * given [target].
+ */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
+      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT.of(source),
+    };
+  }
+
+/**
+ * Create a [ResolveLibraryTask] based on the given [target] in the given
+ * [context].
+ */
+  static ResolveLibraryTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolveLibraryTask(context, target);
+  }
+}
+
+/**
  * An artificial task that does nothing except to force type names resolution
  * for the defining and part units of a library.
  */
@@ -4592,10 +4686,11 @@
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ResolveUnitTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[RESOLVE_UNIT_ERRORS, RESOLVED_UNIT10]);
+      'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
+    CONSTANT_EXPRESSIONS_DEPENDENCIES,
+    RESOLVE_UNIT_ERRORS,
+    RESOLVED_UNIT10
+  ]);
 
   ResolveUnitTask(
       InternalAnalysisContext context, LibrarySpecificUnit compilationUnit)
@@ -4609,6 +4704,7 @@
     //
     // Prepare inputs.
     //
+    LibrarySpecificUnit target = this.target;
     LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
@@ -4621,12 +4717,23 @@
         libraryElement, unitElement.source, typeProvider, errorListener);
     unit.accept(visitor);
     //
+    // Compute constant expressions' dependencies.
+    //
+    List<ConstantEvaluationTarget> constExprDependencies;
+    {
+      ConstantExpressionsDependenciesFinder finder =
+          new ConstantExpressionsDependenciesFinder();
+      unit.accept(finder);
+      constExprDependencies = finder.dependencies.toList();
+    }
+    //
     // Record outputs.
     //
     // TODO(brianwilkerson) This task modifies the element model (by copying the
     // AST's for constructor initializers into it) but does not produce an
     // updated version of the element model.
     //
+    outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
     outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
     outputs[RESOLVED_UNIT10] = unit;
   }
@@ -5012,7 +5119,6 @@
     return <String, TaskInput>{
       UNIT_INPUT: RESOLVED_UNIT11.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      'thisLibraryClosureIsReady': READY_RESOLVED_UNIT11.of(unit.library),
     };
   }
 
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index c5bc076..7cdbe1c 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -46,8 +46,8 @@
   /**
    * The map of [ComputedResult] controllers.
    */
-  final Map<ResultDescriptor,
-          StreamController<ComputedResult>> resultComputedControllers =
+  final Map<ResultDescriptor, StreamController<ComputedResult>>
+      resultComputedControllers =
       <ResultDescriptor, StreamController<ComputedResult>>{};
 
   /**
@@ -168,7 +168,7 @@
     TaskDescriptor taskDescriptor = taskManager.findTask(target, result);
     try {
       WorkItem workItem =
-          new WorkItem(context, target, taskDescriptor, result, null);
+          new WorkItem(context, target, taskDescriptor, result, 0, null);
       return new WorkOrder(taskManager, workItem);
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -550,6 +550,11 @@
   final ResultDescriptor spawningResult;
 
   /**
+   * The level of this item in its [WorkOrder].
+   */
+  final int level;
+
+  /**
    * The work order that this item is part of, may be `null`.
    */
   WorkOrder workOrder;
@@ -593,11 +598,12 @@
    * described by the given descriptor.
    */
   WorkItem(this.context, this.target, this.descriptor, this.spawningResult,
-      this.workOrder) {
+      this.level, this.workOrder) {
     AnalysisTarget actualTarget =
         identical(target, AnalysisContextTarget.request)
             ? new AnalysisContextTarget(context)
             : target;
+//    print('${'\t' * level}$spawningResult of $actualTarget');
     Map<String, TaskInput> inputDescriptors =
         descriptor.createTaskInputs(actualTarget);
     builder = new TopLevelTaskInputBuilder(inputDescriptors);
@@ -699,8 +705,8 @@
         try {
           TaskDescriptor descriptor =
               taskManager.findTask(inputTarget, inputResult);
-          return new WorkItem(
-              context, inputTarget, descriptor, inputResult, workOrder);
+          return new WorkItem(context, inputTarget, descriptor, inputResult,
+              level + 1, workOrder);
         } on AnalysisException catch (exception, stackTrace) {
           this.exception = new CaughtException(exception, stackTrace);
           return null;
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index d6a0c14..07550c5 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -6,8 +6,10 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -222,8 +224,9 @@
           }
         }
       }
-    } else if (node is PartDirective || node is PartOfDirective) {
-    } else if (node is Directive && node.element != null) {
+    } else if (node is PartDirective || node is PartOfDirective) {} else if (node
+        is Directive &&
+        node.element != null) {
       elements.add(node.element);
     } else if (node is Declaration && node.element != null) {
       Element element = node.element;
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 5004368..2ad6c59 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -7,14 +7,917 @@
 library analyzer.src.task.strong.checker;
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
 import 'package:analyzer/src/generated/type_system.dart';
 
 import 'info.dart';
 
+DartType _elementType(Element e) {
+  if (e == null) {
+    // Malformed code - just return dynamic.
+    return DynamicTypeImpl.instance;
+  }
+  return (e as dynamic).type;
+}
+
+PropertyInducingElement _getMemberField(
+    InterfaceType type, PropertyAccessorElement member) {
+  String memberName = member.name;
+  PropertyInducingElement field;
+  if (member.isGetter) {
+    // The subclass member is an explicit getter or a field
+    // - lookup the getter on the superclass.
+    var getter = type.getGetter(memberName);
+    if (getter == null || getter.isStatic) return null;
+    field = getter.variable;
+  } else if (!member.isSynthetic) {
+    // The subclass member is an explicit setter
+    // - lookup the setter on the superclass.
+    // Note: an implicit (synthetic) setter would have already been flagged on
+    // the getter above.
+    var setter = type.getSetter(memberName);
+    if (setter == null || setter.isStatic) return null;
+    field = setter.variable;
+  } else {
+    return null;
+  }
+  if (field.isSynthetic) return null;
+  return field;
+}
+
+// Return the field on type corresponding to member, or null if none
+// exists or the "field" is actually a getter/setter.
+/// Looks up the declaration that matches [member] in [type] and returns it's
+/// declared type.
+FunctionType _getMemberType(InterfaceType type, ExecutableElement member) =>
+    _memberTypeGetter(member)(type);
+
+_MemberTypeGetter _memberTypeGetter(ExecutableElement member) {
+  String memberName = member.name;
+  final isGetter = member is PropertyAccessorElement && member.isGetter;
+  final isSetter = member is PropertyAccessorElement && member.isSetter;
+
+  FunctionType f(InterfaceType type) {
+    ExecutableElement baseMethod;
+
+    if (member.isPrivate) {
+      var subtypeLibrary = member.library;
+      var baseLibrary = type.element.library;
+      if (baseLibrary != subtypeLibrary) {
+        return null;
+      }
+    }
+
+    try {
+      if (isGetter) {
+        assert(!isSetter);
+        // Look for getter or field.
+        baseMethod = type.getGetter(memberName);
+      } else if (isSetter) {
+        baseMethod = type.getSetter(memberName);
+      } else {
+        baseMethod = type.getMethod(memberName);
+      }
+    } catch (e) {
+      // TODO(sigmund): remove this try-catch block (see issue #48).
+    }
+    if (baseMethod == null || baseMethod.isStatic) return null;
+    return baseMethod.type;
+  }
+  return f;
+}
+
+typedef FunctionType _MemberTypeGetter(InterfaceType type);
+
+/// Checks the body of functions and properties.
+class CodeChecker extends RecursiveAstVisitor {
+  final StrongTypeSystemImpl rules;
+  final TypeProvider typeProvider;
+  final AnalysisErrorListener reporter;
+  final _OverrideChecker _overrideChecker;
+  final bool _hints;
+
+  bool _failure = false;
+  CodeChecker(this.typeProvider, StrongTypeSystemImpl rules,
+      AnalysisErrorListener reporter,
+      {bool hints: false})
+      : rules = rules,
+        reporter = reporter,
+        _hints = hints,
+        _overrideChecker = new _OverrideChecker(rules, reporter);
+
+  bool get failure => _failure || _overrideChecker._failure;
+
+  void checkArgument(Expression arg, DartType expectedType) {
+    // Preserve named argument structure, so their immediate parent is the
+    // method invocation.
+    if (arg is NamedExpression) {
+      arg = (arg as NamedExpression).expression;
+    }
+    checkAssignment(arg, expectedType);
+  }
+
+  void checkArgumentList(ArgumentList node, FunctionType type) {
+    NodeList<Expression> list = node.arguments;
+    int len = list.length;
+    for (int i = 0; i < len; ++i) {
+      Expression arg = list[i];
+      ParameterElement element = arg.staticParameterElement;
+      if (element == null) {
+        if (type.parameters.length < len) {
+          // We found an argument mismatch, the analyzer will report this too,
+          // so no need to insert an error for this here.
+          continue;
+        }
+        element = type.parameters[i];
+        // TODO(vsm): When can this happen?
+        assert(element != null);
+      }
+      DartType expectedType = _elementType(element);
+      if (expectedType == null) expectedType = DynamicTypeImpl.instance;
+      checkArgument(arg, expectedType);
+    }
+  }
+
+  void checkAssignment(Expression expr, DartType type) {
+    if (expr is ParenthesizedExpression) {
+      checkAssignment(expr.expression, type);
+    } else {
+      _recordMessage(_checkAssignment(expr, type));
+    }
+  }
+
+  /// Analyzer checks boolean conversions, but we need to check too, because
+  /// it uses the default assignability rules that allow `dynamic` and `Object`
+  /// to be assigned to bool with no message.
+  void checkBoolean(Expression expr) =>
+      checkAssignment(expr, typeProvider.boolType);
+
+  void checkFunctionApplication(
+      Expression node, Expression f, ArgumentList list) {
+    if (_isDynamicCall(f)) {
+      // If f is Function and this is a method invocation, we should have
+      // gotten an analyzer error, so no need to issue another error.
+      _recordDynamicInvoke(node, f);
+    } else {
+      checkArgumentList(list, _getTypeAsCaller(f));
+    }
+  }
+
+  DartType getType(TypeName name) {
+    return (name == null) ? DynamicTypeImpl.instance : name.type;
+  }
+
+  void reset() {
+    _failure = false;
+    _overrideChecker._failure = false;
+  }
+
+  @override
+  void visitAsExpression(AsExpression node) {
+    // We could do the same check as the IsExpression below, but that is
+    // potentially too conservative.  Instead, at runtime, we must fail hard
+    // if the Dart as and the DDC as would return different values.
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression node) {
+    var token = node.operator;
+    if (token.type != TokenType.EQ) {
+      _checkCompoundAssignment(node);
+    } else {
+      DartType staticType = _getStaticType(node.leftHandSide);
+      checkAssignment(node.rightHandSide, staticType);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitBinaryExpression(BinaryExpression node) {
+    var op = node.operator;
+    if (op.isUserDefinableOperator) {
+      if (_isDynamicTarget(node.leftOperand)) {
+        // Dynamic invocation
+        // TODO(vsm): Move this logic to the resolver?
+        if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
+          _recordDynamicInvoke(node, node.leftOperand);
+        }
+      } else {
+        var element = node.staticElement;
+        // Method invocation.
+        if (element is MethodElement) {
+          var type = element.type;
+          // Analyzer should enforce number of parameter types, but check in
+          // case we have erroneous input.
+          if (type.normalParameterTypes.isNotEmpty) {
+            checkArgument(node.rightOperand, type.normalParameterTypes[0]);
+          }
+        } else {
+          // TODO(vsm): Assert that the analyzer found an error here?
+        }
+      }
+    } else {
+      // Non-method operator.
+      switch (op.type) {
+        case TokenType.AMPERSAND_AMPERSAND:
+        case TokenType.BAR_BAR:
+          checkBoolean(node.leftOperand);
+          checkBoolean(node.rightOperand);
+          break;
+        case TokenType.BANG_EQ:
+          break;
+        case TokenType.QUESTION_QUESTION:
+          break;
+        default:
+          assert(false);
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    _overrideChecker.check(node);
+    super.visitClassDeclaration(node);
+  }
+
+  @override
+  void visitComment(Comment node) {
+    // skip, no need to do typechecking inside comments (they may contain
+    // comment references which would require resolution).
+  }
+
+  @override
+  void visitConditionalExpression(ConditionalExpression node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  /// Check constructor declaration to ensure correct super call placement.
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.visitChildren(this);
+
+    final init = node.initializers;
+    for (int i = 0, last = init.length - 1; i < last; i++) {
+      final node = init[i];
+      if (node is SuperConstructorInvocation) {
+        _recordMessage(new InvalidSuperInvocation(node));
+      }
+    }
+  }
+
+  // Check invocations
+  @override
+  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
+    var field = node.fieldName;
+    var element = field.staticElement;
+    DartType staticType = _elementType(element);
+    checkAssignment(node.expression, staticType);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    // Check that defaults have the proper subtype.
+    var parameter = node.parameter;
+    var parameterType = _elementType(parameter.element);
+    assert(parameterType != null);
+    var defaultValue = node.defaultValue;
+    if (defaultValue != null) {
+      checkAssignment(defaultValue, parameterType);
+    }
+
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    _checkReturnOrYield(node.expression, node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    var element = node.element;
+    var typeName = node.type;
+    if (typeName != null) {
+      var type = _elementType(element);
+      var fieldElement =
+          node.identifier.staticElement as FieldFormalParameterElement;
+      var fieldType = _elementType(fieldElement.field);
+      if (!rules.isSubtypeOf(type, fieldType)) {
+        var staticInfo =
+            new InvalidParameterDeclaration(rules, node, fieldType);
+        _recordMessage(staticInfo);
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    // Check that the expression is an Iterable.
+    var expr = node.iterable;
+    var iterableType = node.awaitKeyword != null
+        ? typeProvider.streamType
+        : typeProvider.iterableType;
+    var loopVariable = node.identifier != null
+        ? node.identifier
+        : node.loopVariable?.identifier;
+    if (loopVariable != null) {
+      var iteratorType = loopVariable.staticType;
+      var checkedType = iterableType.substitute4([iteratorType]);
+      checkAssignment(expr, checkedType);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    if (node.condition != null) {
+      checkBoolean(node.condition);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    checkFunctionApplication(node, node.function, node.argumentList);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIndexExpression(IndexExpression node) {
+    var target = node.realTarget;
+    if (_isDynamicTarget(target)) {
+      _recordDynamicInvoke(node, target);
+    } else {
+      var element = node.staticElement;
+      if (element is MethodElement) {
+        var type = element.type;
+        // Analyzer should enforce number of parameter types, but check in
+        // case we have erroneous input.
+        if (type.normalParameterTypes.isNotEmpty) {
+          checkArgument(node.index, type.normalParameterTypes[0]);
+        }
+      } else {
+        // TODO(vsm): Assert that the analyzer found an error here?
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    var arguments = node.argumentList;
+    var element = node.staticElement;
+    if (element != null) {
+      var type = _elementType(node.staticElement);
+      checkArgumentList(arguments, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitIsExpression(IsExpression node) {
+    _checkRuntimeTypeCheck(node, node.type);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral node) {
+    var type = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments;
+      if (targs.length > 0) type = targs[0].type;
+    } else if (node.staticType is InterfaceType) {
+      InterfaceType listT = node.staticType;
+      var targs = listT.typeArguments;
+      if (targs != null && targs.length > 0) type = targs[0];
+    }
+    var elements = node.elements;
+    for (int i = 0; i < elements.length; i++) {
+      checkArgument(elements[i], type);
+    }
+    super.visitListLiteral(node);
+  }
+
+  @override
+  void visitMapLiteral(MapLiteral node) {
+    var ktype = DynamicTypeImpl.instance;
+    var vtype = DynamicTypeImpl.instance;
+    if (node.typeArguments != null) {
+      var targs = node.typeArguments.arguments;
+      if (targs.length > 0) ktype = targs[0].type;
+      if (targs.length > 1) vtype = targs[1].type;
+    } else if (node.staticType is InterfaceType) {
+      InterfaceType mapT = node.staticType;
+      var targs = mapT.typeArguments;
+      if (targs != null) {
+        if (targs.length > 0) ktype = targs[0];
+        if (targs.length > 1) vtype = targs[1];
+      }
+    }
+    var entries = node.entries;
+    for (int i = 0; i < entries.length; i++) {
+      var entry = entries[i];
+      checkArgument(entry.key, ktype);
+      checkArgument(entry.value, vtype);
+    }
+    super.visitMapLiteral(node);
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    var target = node.realTarget;
+    if (_isDynamicTarget(target) && !_isObjectMethod(node, node.methodName)) {
+      _recordDynamicInvoke(node, target);
+
+      // Mark the tear-off as being dynamic, too. This lets us distinguish
+      // cases like:
+      //
+      //     dynamic d;
+      //     d.someMethod(...); // the whole method call must be a dynamic send.
+      //
+      // ... from case like:
+      //
+      //     SomeType s;
+      //     s.someDynamicField(...); // static get, followed by dynamic call.
+      //
+      // The first case is handled here, the second case is handled below when
+      // we call [checkFunctionApplication].
+      DynamicInvoke.set(node.methodName, true);
+    } else {
+      checkFunctionApplication(node, node.methodName, node.argumentList);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPostfixExpression(PostfixExpression node) {
+    _checkUnary(node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _checkFieldAccess(node, node.prefix, node.identifier);
+  }
+
+  @override
+  void visitPrefixExpression(PrefixExpression node) {
+    if (node.operator.type == TokenType.BANG) {
+      checkBoolean(node.operand);
+    } else {
+      _checkUnary(node);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    _checkFieldAccess(node, node.realTarget, node.propertyName);
+  }
+
+  @override
+  void visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node) {
+    var type = node.staticElement?.type;
+    // TODO(leafp): There's a TODO in visitRedirectingConstructorInvocation
+    // in the element_resolver to handle the case that the element is null
+    // and emit an error.  In the meantime, just be defensive here.
+    if (type != null) {
+      checkArgumentList(node.argumentList, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    _checkReturnOrYield(node.expression, node);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    var element = node.staticElement;
+    if (element != null) {
+      var type = node.staticElement.type;
+      checkArgumentList(node.argumentList, type);
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    // SwitchStatement defines a boolean conversion to check the result of the
+    // case value == the switch value, but in dev_compiler we require a boolean
+    // return type from an overridden == operator (because Object.==), so
+    // checking in SwitchStatement shouldn't be necessary.
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    TypeName type = node.type;
+    if (type == null) {
+      // No checks are needed when the type is var. Although internally the
+      // typing rules may have inferred a more precise type for the variable
+      // based on the initializer.
+    } else {
+      var dartType = getType(type);
+      for (VariableDeclaration variable in node.variables) {
+        var initializer = variable.initializer;
+        if (initializer != null) {
+          checkAssignment(initializer, dartType);
+        }
+      }
+    }
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    checkBoolean(node.condition);
+    node.visitChildren(this);
+  }
+
+  @override
+  void visitYieldStatement(YieldStatement node) {
+    _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
+    node.visitChildren(this);
+  }
+
+  StaticInfo _checkAssignment(Expression expr, DartType toT) {
+    final fromT = expr.staticType ?? DynamicTypeImpl.instance;
+    final Coercion c = _coerceTo(fromT, toT);
+    if (c is Identity) return null;
+    if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
+    var reason = null;
+
+    var errors = <String>[];
+
+    var ok = _inferExpression(expr, toT, errors);
+    if (ok) return InferredType.create(rules, expr, toT);
+    reason = (errors.isNotEmpty) ? errors.first : null;
+
+    if (c is Cast) return DownCast.create(rules, expr, c, reason: reason);
+    assert(false);
+    return null;
+  }
+
+  void _checkCompoundAssignment(AssignmentExpression expr) {
+    var op = expr.operator.type;
+    assert(op.isAssignmentOperator && op != TokenType.EQ);
+    var methodElement = expr.staticElement;
+    if (methodElement == null) {
+      // Dynamic invocation
+      _recordDynamicInvoke(expr, expr.leftHandSide);
+    } else {
+      // Sanity check the operator
+      assert(methodElement.isOperator);
+      var functionType = methodElement.type;
+      var paramTypes = functionType.normalParameterTypes;
+      assert(paramTypes.length == 1);
+      assert(functionType.namedParameterTypes.isEmpty);
+      assert(functionType.optionalParameterTypes.isEmpty);
+
+      // Check the lhs type
+      var staticInfo;
+      var rhsType = _getStaticType(expr.rightHandSide);
+      var lhsType = _getStaticType(expr.leftHandSide);
+      var returnType = _specializedBinaryReturnType(
+          op, lhsType, rhsType, functionType.returnType);
+
+      if (!rules.isSubtypeOf(returnType, lhsType)) {
+        final numType = typeProvider.numType;
+        // Try to fix up the numerical case if possible.
+        if (rules.isSubtypeOf(lhsType, numType) &&
+            rules.isSubtypeOf(lhsType, rhsType)) {
+          // This is also slightly different from spec, but allows us to keep
+          // compound operators in the int += num and num += dynamic cases.
+          staticInfo = DownCast.create(
+              rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
+          rhsType = lhsType;
+        } else {
+          // Static type error
+          staticInfo = new StaticTypeError(rules, expr, lhsType);
+        }
+        _recordMessage(staticInfo);
+      }
+
+      // Check the rhs type
+      if (staticInfo is! CoercionInfo) {
+        var paramType = paramTypes.first;
+        staticInfo = _checkAssignment(expr.rightHandSide, paramType);
+        _recordMessage(staticInfo);
+      }
+    }
+  }
+
+  void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
+    if ((_isDynamicTarget(target) || field.staticElement == null) &&
+        !_isObjectProperty(target, field)) {
+      _recordDynamicInvoke(node, target);
+    }
+    node.visitChildren(this);
+  }
+
+  void _checkReturnOrYield(Expression expression, AstNode node,
+      {bool yieldStar: false}) {
+    var body = node.getAncestor((n) => n is FunctionBody);
+    var type = _getExpectedReturnType(body, yieldStar: yieldStar);
+    if (type == null) {
+      // We have a type mismatch: the async/async*/sync* modifier does
+      // not match the return or yield type.  We should have already gotten an
+      // analyzer error in this case.
+      return;
+    }
+    InterfaceType futureType = typeProvider.futureType;
+    DartType actualType = expression?.staticType;
+    if (body.isAsynchronous &&
+        !body.isGenerator &&
+        actualType is InterfaceType &&
+        actualType.element == futureType.element) {
+      type = futureType.substitute4([type]);
+    }
+    // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
+    if (expression != null) checkAssignment(expression, type);
+  }
+
+  void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) {
+    var type = getType(typeName);
+    if (!rules.isGroundType(type)) {
+      _recordMessage(new NonGroundTypeCheckInfo(node, type));
+    }
+  }
+
+  void _checkUnary(/*PrefixExpression|PostfixExpression*/ node) {
+    var op = node.operator;
+    if (op.isUserDefinableOperator ||
+        op.type == TokenType.PLUS_PLUS ||
+        op.type == TokenType.MINUS_MINUS) {
+      if (_isDynamicTarget(node.operand)) {
+        _recordDynamicInvoke(node, node.operand);
+      }
+      // For ++ and --, even if it is not dynamic, we still need to check
+      // that the user defined method accepts an `int` as the RHS.
+      // We assume Analyzer has done this already.
+    }
+  }
+
+  Coercion _coerceTo(DartType fromT, DartType toT) {
+    // We can use anything as void
+    if (toT.isVoid) return Coercion.identity(toT);
+
+    // fromT <: toT, no coercion needed
+    if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+
+    // TODO(vsm): We can get rid of the second clause if we disallow
+    // all sideways casts - see TODO below.
+    // -------
+    // Note: a function type is never assignable to a class per the Dart
+    // spec - even if it has a compatible call method.  We disallow as
+    // well for consistency.
+    if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
+        (toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
+      return Coercion.error();
+    }
+
+    // Downcast if toT <: fromT
+    if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+
+    // TODO(vsm): Once we have generic methods, we should delete this
+    // workaround.  These sideways casts are always ones we warn about
+    // - i.e., we think they are likely to fail at runtime.
+    // -------
+    // Downcast if toT <===> fromT
+    // The intention here is to allow casts that are sideways in the restricted
+    // type system, but allowed in the regular dart type system, since these
+    // are likely to succeed.  The canonical example is List<dynamic> and
+    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
+    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
+    if (fromT.isAssignableTo(toT)) {
+      return Coercion.cast(fromT, toT);
+    }
+
+    return Coercion.error();
+  }
+
+  // Produce a coercion which coerces something of type fromT
+  // to something of type toT.
+  // Returns the error coercion if the types cannot be coerced
+  // according to our current criteria.
+  /// Gets the expected return type of the given function [body], either from
+  /// a normal return/yield, or from a yield*.
+  DartType _getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
+    FunctionType functionType;
+    var parent = body.parent;
+    if (parent is Declaration) {
+      functionType = _elementType(parent.element);
+    } else {
+      assert(parent is FunctionExpression);
+      functionType = parent.staticType ?? DynamicTypeImpl.instance;
+    }
+
+    var type = functionType.returnType;
+
+    InterfaceType expectedType = null;
+    if (body.isAsynchronous) {
+      if (body.isGenerator) {
+        // Stream<T> -> T
+        expectedType = typeProvider.streamType;
+      } else {
+        // Future<T> -> T
+        // TODO(vsm): Revisit with issue #228.
+        expectedType = typeProvider.futureType;
+      }
+    } else {
+      if (body.isGenerator) {
+        // Iterable<T> -> T
+        expectedType = typeProvider.iterableType;
+      } else {
+        // T -> T
+        return type;
+      }
+    }
+    if (yieldStar) {
+      if (type.isDynamic) {
+        // Ensure it's at least a Stream / Iterable.
+        return expectedType.substitute4([typeProvider.dynamicType]);
+      } else {
+        // Analyzer will provide a separate error if expected type
+        // is not compatible with type.
+        return type;
+      }
+    }
+    if (type.isDynamic) {
+      return type;
+    } else if (type is InterfaceType && type.element == expectedType.element) {
+      return type.typeArguments[0];
+    } else {
+      // Malformed type - fallback on analyzer error.
+      return null;
+    }
+  }
+
+  DartType _getStaticType(Expression expr) {
+    return expr.staticType ?? DynamicTypeImpl.instance;
+  }
+
+  /// Given an expression, return its type assuming it is
+  /// in the caller position of a call (that is, accounting
+  /// for the possibility of a call method).  Returns null
+  /// if expression is not statically callable.
+  FunctionType _getTypeAsCaller(Expression applicand) {
+    var t = applicand.staticType ?? DynamicTypeImpl.instance;
+    if (t is InterfaceType) {
+      return rules.getCallMethodType(t);
+    }
+    if (t is FunctionType) return t;
+    return null;
+  }
+
+  /// Checks if we can perform downwards inference on [e] tp get type [t].
+  /// If it is not possible, this will add a message to [errors].
+  bool _inferExpression(Expression e, DartType t, List<String> errors) {
+    DartType staticType = e.staticType ?? DynamicTypeImpl.instance;
+    if (rules.isSubtypeOf(staticType, t)) {
+      return true;
+    }
+    errors.add("$e cannot be typed as $t");
+    return false;
+  }
+
+  /// Returns `true` if the expression is a dynamic function call or method
+  /// invocation.
+  bool _isDynamicCall(Expression call) {
+    var ft = _getTypeAsCaller(call);
+    // TODO(leafp): This will currently return true if t is Function
+    // This is probably the most correct thing to do for now, since
+    // this code is also used by the back end.  Maybe revisit at some
+    // point?
+    if (ft == null) return true;
+    // Dynamic as the parameter type is treated as bottom.  A function with
+    // a dynamic parameter type requires a dynamic call in general.
+    // However, as an optimization, if we have an original definition, we know
+    // dynamic is reified as Object - in this case a regular call is fine.
+    if (call is SimpleIdentifier) {
+      var element = call.staticElement;
+      if (element is FunctionElement || element is MethodElement) {
+        // An original declaration.
+        return false;
+      }
+    }
+
+    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+  }
+
+  /// Returns `true` if the target expression is dynamic.
+  bool _isDynamicTarget(Expression node) {
+    if (node == null) return false;
+
+    if (_isLibraryPrefix(node)) return false;
+
+    // Null type happens when we have unknown identifiers, like a dart: import
+    // that doesn't resolve.
+    var type = node.staticType;
+    return type == null || type.isDynamic;
+  }
+
+  bool _isLibraryPrefix(Expression node) =>
+      node is SimpleIdentifier && node.staticElement is PrefixElement;
+
+  bool _isObjectGetter(Expression target, SimpleIdentifier id) {
+    PropertyAccessorElement element =
+        typeProvider.objectType.element.getGetter(id.name);
+    return (element != null && !element.isStatic);
+  }
+
+  bool _isObjectMethod(Expression target, SimpleIdentifier id) {
+    MethodElement element = typeProvider.objectType.element.getMethod(id.name);
+    return (element != null && !element.isStatic);
+  }
+
+  bool _isObjectProperty(Expression target, SimpleIdentifier id) {
+    return _isObjectGetter(target, id) || _isObjectMethod(target, id);
+  }
+
+  void _recordDynamicInvoke(AstNode node, AstNode target) {
+    if (_hints) {
+      reporter.onError(new DynamicInvoke(rules, node).toAnalysisError());
+    }
+    // TODO(jmesserly): we may eventually want to record if the whole operation
+    // (node) was dynamic, rather than the target, but this is an easier fit
+    // with what we used to do.
+    DynamicInvoke.set(target, true);
+  }
+
+  void _recordMessage(StaticInfo info) {
+    if (info == null) return;
+    var error = info.toAnalysisError();
+    var severity = error.errorCode.errorSeverity;
+    if (severity == ErrorSeverity.ERROR) _failure = true;
+    if (severity != ErrorSeverity.INFO || _hints) {
+      reporter.onError(error);
+    }
+
+    if (info is CoercionInfo) {
+      // TODO(jmesserly): if we're run again on the same AST, we'll produce the
+      // same annotations. This should be harmless. This might go away once
+      // CodeChecker is integrated better with analyzer, as it will know that
+      // checking has already been performed.
+      // assert(CoercionInfo.get(info.node) == null);
+      CoercionInfo.set(info.node, info);
+    }
+  }
+
+  DartType _specializedBinaryReturnType(
+      TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
+    // This special cases binary return types as per 16.26 and 16.27 of the
+    // Dart language spec.
+    switch (op) {
+      case TokenType.PLUS:
+      case TokenType.MINUS:
+      case TokenType.STAR:
+      case TokenType.TILDE_SLASH:
+      case TokenType.PERCENT:
+      case TokenType.PLUS_EQ:
+      case TokenType.MINUS_EQ:
+      case TokenType.STAR_EQ:
+      case TokenType.TILDE_SLASH_EQ:
+      case TokenType.PERCENT_EQ:
+        if (t1 == typeProvider.intType && t2 == typeProvider.intType) return t1;
+        if (t1 == typeProvider.doubleType && t2 == typeProvider.doubleType)
+          return t1;
+        // This particular combo is not spelled out in the spec, but all
+        // implementations and analyzer seem to follow this.
+        if (t1 == typeProvider.doubleType && t2 == typeProvider.intType)
+          return t1;
+    }
+    return normalReturnType;
+  }
+}
+
 /// Checks for overriding declarations of fields and methods. This is used to
 /// check overrides between classes and superclasses, interfaces, and mixin
 /// applications.
@@ -32,68 +935,6 @@
     _checkAllInterfaceOverrides(node);
   }
 
-  /// Check overrides from mixin applications themselves. For example, in:
-  ///
-  ///      A extends B with E, F
-  ///
-  ///  we check:
-  ///
-  ///      B & E against B (equivalently how E overrides B)
-  ///      B & E & F against B & E (equivalently how F overrides both B and E)
-  void _checkMixinApplicationOverrides(ClassDeclaration node) {
-    var type = node.element.type;
-    var parent = type.superclass;
-    var mixins = type.mixins;
-
-    // Check overrides from applying mixins
-    for (int i = 0; i < mixins.length; i++) {
-      var seen = new Set<String>();
-      var current = mixins[i];
-      var errorLocation = node.withClause.mixinTypes[i];
-      for (int j = i - 1; j >= 0; j--) {
-        _checkIndividualOverridesFromType(
-            current, mixins[j], errorLocation, seen, true);
-      }
-      _checkIndividualOverridesFromType(
-          current, parent, errorLocation, seen, true);
-    }
-  }
-
-  /// Check overrides between a class and its superclasses and mixins. For
-  /// example, in:
-  ///
-  ///      A extends B with E, F
-  ///
-  /// we check A against B, B super classes, E, and F.
-  ///
-  /// Internally we avoid reporting errors twice and we visit classes bottom up
-  /// to ensure we report the most immediate invalid override first. For
-  /// example, in the following code we'll report that `Test` has an invalid
-  /// override with respect to `Parent` (as opposed to an invalid override with
-  /// respect to `Grandparent`):
-  ///
-  ///     class Grandparent {
-  ///         m(A a) {}
-  ///     }
-  ///     class Parent extends Grandparent {
-  ///         m(A a) {}
-  ///     }
-  ///     class Test extends Parent {
-  ///         m(B a) {} // invalid override
-  ///     }
-  void _checkSuperOverrides(ClassDeclaration node) {
-    var seen = new Set<String>();
-    var current = node.element.type;
-    var visited = new Set<InterfaceType>();
-    do {
-      visited.add(current);
-      current.mixins.reversed.forEach(
-          (m) => _checkIndividualOverridesFromClass(node, m, seen, true));
-      _checkIndividualOverridesFromClass(node, current.superclass, seen, true);
-      current = current.superclass;
-    } while (!current.isObject && !visited.contains(current));
-  }
-
   /// Checks that implementations correctly override all reachable interfaces.
   /// In particular, we need to check these overrides for the definitions in
   /// the class itself and each its superclasses. If a superclass is not
@@ -145,6 +986,72 @@
         includeParents: false);
   }
 
+  /// Check that individual methods and fields in [subType] correctly override
+  /// the declarations in [baseType].
+  ///
+  /// The [errorLocation] node indicates where errors are reported, see
+  /// [_checkSingleOverride] for more details.
+  _checkIndividualOverridesFromClass(ClassDeclaration node,
+      InterfaceType baseType, Set<String> seen, bool isSubclass) {
+    for (var member in node.members) {
+      if (member is ConstructorDeclaration) continue;
+      if (member is FieldDeclaration) {
+        if (member.isStatic) continue;
+        for (var variable in member.fields.variables) {
+          var element = variable.element as PropertyInducingElement;
+          var name = element.name;
+          if (seen.contains(name)) continue;
+          var getter = element.getter;
+          var setter = element.setter;
+          bool found = _checkSingleOverride(
+              getter, baseType, variable, member, isSubclass);
+          if (!variable.isFinal &&
+              !variable.isConst &&
+              _checkSingleOverride(
+                  setter, baseType, variable, member, isSubclass)) {
+            found = true;
+          }
+          if (found) seen.add(name);
+        }
+      } else {
+        if ((member as MethodDeclaration).isStatic) continue;
+        var method = (member as MethodDeclaration).element;
+        if (seen.contains(method.name)) continue;
+        if (_checkSingleOverride(
+            method, baseType, member, member, isSubclass)) {
+          seen.add(method.name);
+        }
+      }
+    }
+  }
+
+  /// Check that individual methods and fields in [subType] correctly override
+  /// the declarations in [baseType].
+  ///
+  /// The [errorLocation] node indicates where errors are reported, see
+  /// [_checkSingleOverride] for more details.
+  ///
+  /// The set [seen] is used to avoid reporting overrides more than once. It
+  /// is used when invoking this function multiple times when checking several
+  /// types in a class hierarchy. Errors are reported only the first time an
+  /// invalid override involving a specific member is encountered.
+  _checkIndividualOverridesFromType(
+      InterfaceType subType,
+      InterfaceType baseType,
+      AstNode errorLocation,
+      Set<String> seen,
+      bool isSubclass) {
+    void checkHelper(ExecutableElement e) {
+      if (e.isStatic) return;
+      if (seen.contains(e.name)) return;
+      if (_checkSingleOverride(e, baseType, null, errorLocation, isSubclass)) {
+        seen.add(e.name);
+      }
+    }
+    subType.methods.forEach(checkHelper);
+    subType.accessors.forEach(checkHelper);
+  }
+
   /// Checks that [cls] and its super classes (including mixins) correctly
   /// overrides each interface in [interfaces]. If [includeParents] is false,
   /// then mixins are still checked, but the base type and it's transitive
@@ -204,69 +1111,30 @@
     }
   }
 
-  /// Check that individual methods and fields in [subType] correctly override
-  /// the declarations in [baseType].
+  /// Check overrides from mixin applications themselves. For example, in:
   ///
-  /// The [errorLocation] node indicates where errors are reported, see
-  /// [_checkSingleOverride] for more details.
+  ///      A extends B with E, F
   ///
-  /// The set [seen] is used to avoid reporting overrides more than once. It
-  /// is used when invoking this function multiple times when checking several
-  /// types in a class hierarchy. Errors are reported only the first time an
-  /// invalid override involving a specific member is encountered.
-  _checkIndividualOverridesFromType(
-      InterfaceType subType,
-      InterfaceType baseType,
-      AstNode errorLocation,
-      Set<String> seen,
-      bool isSubclass) {
-    void checkHelper(ExecutableElement e) {
-      if (e.isStatic) return;
-      if (seen.contains(e.name)) return;
-      if (_checkSingleOverride(e, baseType, null, errorLocation, isSubclass)) {
-        seen.add(e.name);
-      }
-    }
-    subType.methods.forEach(checkHelper);
-    subType.accessors.forEach(checkHelper);
-  }
+  ///  we check:
+  ///
+  ///      B & E against B (equivalently how E overrides B)
+  ///      B & E & F against B & E (equivalently how F overrides both B and E)
+  void _checkMixinApplicationOverrides(ClassDeclaration node) {
+    var type = node.element.type;
+    var parent = type.superclass;
+    var mixins = type.mixins;
 
-  /// Check that individual methods and fields in [subType] correctly override
-  /// the declarations in [baseType].
-  ///
-  /// The [errorLocation] node indicates where errors are reported, see
-  /// [_checkSingleOverride] for more details.
-  _checkIndividualOverridesFromClass(ClassDeclaration node,
-      InterfaceType baseType, Set<String> seen, bool isSubclass) {
-    for (var member in node.members) {
-      if (member is ConstructorDeclaration) continue;
-      if (member is FieldDeclaration) {
-        if (member.isStatic) continue;
-        for (var variable in member.fields.variables) {
-          var element = variable.element as PropertyInducingElement;
-          var name = element.name;
-          if (seen.contains(name)) continue;
-          var getter = element.getter;
-          var setter = element.setter;
-          bool found = _checkSingleOverride(
-              getter, baseType, variable, member, isSubclass);
-          if (!variable.isFinal &&
-              !variable.isConst &&
-              _checkSingleOverride(
-                  setter, baseType, variable, member, isSubclass)) {
-            found = true;
-          }
-          if (found) seen.add(name);
-        }
-      } else {
-        if ((member as MethodDeclaration).isStatic) continue;
-        var method = (member as MethodDeclaration).element;
-        if (seen.contains(method.name)) continue;
-        if (_checkSingleOverride(
-            method, baseType, member, member, isSubclass)) {
-          seen.add(method.name);
-        }
+    // Check overrides from applying mixins
+    for (int i = 0; i < mixins.length; i++) {
+      var seen = new Set<String>();
+      var current = mixins[i];
+      var errorLocation = node.withClause.mixinTypes[i];
+      for (int j = i - 1; j >= 0; j--) {
+        _checkIndividualOverridesFromType(
+            current, mixins[j], errorLocation, seen, true);
       }
+      _checkIndividualOverridesFromType(
+          current, parent, errorLocation, seen, true);
     }
   }
 
@@ -332,6 +1200,41 @@
     return true;
   }
 
+  /// Check overrides between a class and its superclasses and mixins. For
+  /// example, in:
+  ///
+  ///      A extends B with E, F
+  ///
+  /// we check A against B, B super classes, E, and F.
+  ///
+  /// Internally we avoid reporting errors twice and we visit classes bottom up
+  /// to ensure we report the most immediate invalid override first. For
+  /// example, in the following code we'll report that `Test` has an invalid
+  /// override with respect to `Parent` (as opposed to an invalid override with
+  /// respect to `Grandparent`):
+  ///
+  ///     class Grandparent {
+  ///         m(A a) {}
+  ///     }
+  ///     class Parent extends Grandparent {
+  ///         m(A a) {}
+  ///     }
+  ///     class Test extends Parent {
+  ///         m(B a) {} // invalid override
+  ///     }
+  void _checkSuperOverrides(ClassDeclaration node) {
+    var seen = new Set<String>();
+    var current = node.element.type;
+    var visited = new Set<InterfaceType>();
+    do {
+      visited.add(current);
+      current.mixins.reversed.forEach(
+          (m) => _checkIndividualOverridesFromClass(node, m, seen, true));
+      _checkIndividualOverridesFromClass(node, current.superclass, seen, true);
+      current = current.superclass;
+    } while (!current.isObject && !visited.contains(current));
+  }
+
   void _recordMessage(StaticInfo info) {
     if (info == null) return;
     var error = info.toAnalysisError();
@@ -339,907 +1242,3 @@
     _reporter.onError(error);
   }
 }
-
-/// Checks the body of functions and properties.
-class CodeChecker extends RecursiveAstVisitor {
-  final StrongTypeSystemImpl rules;
-  final TypeProvider typeProvider;
-  final AnalysisErrorListener reporter;
-  final _OverrideChecker _overrideChecker;
-  final bool _hints;
-
-  bool _failure = false;
-  bool get failure => _failure || _overrideChecker._failure;
-
-  void reset() {
-    _failure = false;
-    _overrideChecker._failure = false;
-  }
-
-  CodeChecker(this.typeProvider, StrongTypeSystemImpl rules, AnalysisErrorListener reporter,
-      {bool hints: false})
-      : rules = rules,
-        reporter = reporter,
-        _hints = hints,
-        _overrideChecker = new _OverrideChecker(rules, reporter);
-
-  @override
-  void visitComment(Comment node) {
-    // skip, no need to do typechecking inside comments (they may contain
-    // comment references which would require resolution).
-  }
-
-  @override
-  void visitClassDeclaration(ClassDeclaration node) {
-    _overrideChecker.check(node);
-    super.visitClassDeclaration(node);
-  }
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression node) {
-    var token = node.operator;
-    if (token.type != TokenType.EQ) {
-      _checkCompoundAssignment(node);
-    } else {
-      DartType staticType = _getStaticType(node.leftHandSide);
-      checkAssignment(node.rightHandSide, staticType);
-    }
-    node.visitChildren(this);
-  }
-
-  /// Check constructor declaration to ensure correct super call placement.
-  @override
-  void visitConstructorDeclaration(ConstructorDeclaration node) {
-    node.visitChildren(this);
-
-    final init = node.initializers;
-    for (int i = 0, last = init.length - 1; i < last; i++) {
-      final node = init[i];
-      if (node is SuperConstructorInvocation) {
-        _recordMessage(new InvalidSuperInvocation(node));
-      }
-    }
-  }
-
-  @override
-  void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    var field = node.fieldName;
-    var element = field.staticElement;
-    DartType staticType = _elementType(element);
-    checkAssignment(node.expression, staticType);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForEachStatement(ForEachStatement node) {
-    // Check that the expression is an Iterable.
-    var expr = node.iterable;
-    var iterableType = node.awaitKeyword != null
-        ? typeProvider.streamType
-        : typeProvider.iterableType;
-    var loopVariable = node.identifier != null
-        ? node.identifier
-        : node.loopVariable?.identifier;
-    if (loopVariable != null) {
-      var iteratorType = loopVariable.staticType;
-      var checkedType = iterableType.substitute4([iteratorType]);
-      checkAssignment(expr, checkedType);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitForStatement(ForStatement node) {
-    if (node.condition != null) {
-      checkBoolean(node.condition);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIfStatement(IfStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitDoStatement(DoStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitWhileStatement(WhileStatement node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSwitchStatement(SwitchStatement node) {
-    // SwitchStatement defines a boolean conversion to check the result of the
-    // case value == the switch value, but in dev_compiler we require a boolean
-    // return type from an overridden == operator (because Object.==), so
-    // checking in SwitchStatement shouldn't be necessary.
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitListLiteral(ListLiteral node) {
-    var type = DynamicTypeImpl.instance;
-    if (node.typeArguments != null) {
-      var targs = node.typeArguments.arguments;
-      if (targs.length > 0) type = targs[0].type;
-    } else if (node.staticType is InterfaceType) {
-      InterfaceType listT = node.staticType;
-      var targs = listT.typeArguments;
-      if (targs != null && targs.length > 0) type = targs[0];
-    }
-    var elements = node.elements;
-    for (int i = 0; i < elements.length; i++) {
-      checkArgument(elements[i], type);
-    }
-    super.visitListLiteral(node);
-  }
-
-  @override
-  void visitMapLiteral(MapLiteral node) {
-    var ktype = DynamicTypeImpl.instance;
-    var vtype = DynamicTypeImpl.instance;
-    if (node.typeArguments != null) {
-      var targs = node.typeArguments.arguments;
-      if (targs.length > 0) ktype = targs[0].type;
-      if (targs.length > 1) vtype = targs[1].type;
-    } else if (node.staticType is InterfaceType) {
-      InterfaceType mapT = node.staticType;
-      var targs = mapT.typeArguments;
-      if (targs != null) {
-        if (targs.length > 0) ktype = targs[0];
-        if (targs.length > 1) vtype = targs[1];
-      }
-    }
-    var entries = node.entries;
-    for (int i = 0; i < entries.length; i++) {
-      var entry = entries[i];
-      checkArgument(entry.key, ktype);
-      checkArgument(entry.value, vtype);
-    }
-    super.visitMapLiteral(node);
-  }
-
-  // Check invocations
-  void checkArgumentList(ArgumentList node, FunctionType type) {
-    NodeList<Expression> list = node.arguments;
-    int len = list.length;
-    for (int i = 0; i < len; ++i) {
-      Expression arg = list[i];
-      ParameterElement element = arg.staticParameterElement;
-      if (element == null) {
-        if (type.parameters.length < len) {
-          // We found an argument mismatch, the analyzer will report this too,
-          // so no need to insert an error for this here.
-          continue;
-        }
-        element = type.parameters[i];
-        // TODO(vsm): When can this happen?
-        assert(element != null);
-      }
-      DartType expectedType = _elementType(element);
-      if (expectedType == null) expectedType = DynamicTypeImpl.instance;
-      checkArgument(arg, expectedType);
-    }
-  }
-
-  void checkArgument(Expression arg, DartType expectedType) {
-    // Preserve named argument structure, so their immediate parent is the
-    // method invocation.
-    if (arg is NamedExpression) {
-      arg = (arg as NamedExpression).expression;
-    }
-    checkAssignment(arg, expectedType);
-  }
-
-  void checkFunctionApplication(
-      Expression node, Expression f, ArgumentList list) {
-    if (_isDynamicCall(f)) {
-      // If f is Function and this is a method invocation, we should have
-      // gotten an analyzer error, so no need to issue another error.
-      _recordDynamicInvoke(node, f);
-    } else {
-      checkArgumentList(list, _getTypeAsCaller(f));
-    }
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    var target = node.realTarget;
-    if (_isDynamicTarget(target) &&
-        !_isObjectMethod(node, node.methodName)) {
-      _recordDynamicInvoke(node, target);
-
-      // Mark the tear-off as being dynamic, too. This lets us distinguish
-      // cases like:
-      //
-      //     dynamic d;
-      //     d.someMethod(...); // the whole method call must be a dynamic send.
-      //
-      // ... from case like:
-      //
-      //     SomeType s;
-      //     s.someDynamicField(...); // static get, followed by dynamic call.
-      //
-      // The first case is handled here, the second case is handled below when
-      // we call [checkFunctionApplication].
-      DynamicInvoke.set(node.methodName, true);
-    } else {
-      checkFunctionApplication(node, node.methodName, node.argumentList);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    checkFunctionApplication(node, node.function, node.argumentList);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node) {
-    var type = node.staticElement?.type;
-    // TODO(leafp): There's a TODO in visitRedirectingConstructorInvocation
-    // in the element_resolver to handle the case that the element is null
-    // and emit an error.  In the meantime, just be defensive here.
-    if (type != null) {
-      checkArgumentList(node.argumentList, type);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    var element = node.staticElement;
-    if (element != null) {
-      var type = node.staticElement.type;
-      checkArgumentList(node.argumentList, type);
-    }
-    node.visitChildren(this);
-  }
-
-  void _checkReturnOrYield(Expression expression, AstNode node,
-      {bool yieldStar: false}) {
-    var body = node.getAncestor((n) => n is FunctionBody);
-    var type = _getExpectedReturnType(body, yieldStar: yieldStar);
-    if (type == null) {
-      // We have a type mismatch: the async/async*/sync* modifier does
-      // not match the return or yield type.  We should have already gotten an
-      // analyzer error in this case.
-      return;
-    }
-    InterfaceType futureType = typeProvider.futureType;
-    DartType actualType = expression?.staticType;
-    if (body.isAsynchronous &&
-        !body.isGenerator &&
-        actualType is InterfaceType &&
-        actualType.element == futureType.element) {
-      type = futureType.substitute4([type]);
-    }
-    // TODO(vsm): Enforce void or dynamic (to void?) when expression is null.
-    if (expression != null) checkAssignment(expression, type);
-  }
-
-  /// Gets the expected return type of the given function [body], either from
-  /// a normal return/yield, or from a yield*.
-  DartType _getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
-    FunctionType functionType;
-    var parent = body.parent;
-    if (parent is Declaration) {
-      functionType = _elementType(parent.element);
-    } else {
-      assert(parent is FunctionExpression);
-      functionType = parent.staticType ?? DynamicTypeImpl.instance;
-    }
-
-    var type = functionType.returnType;
-
-    InterfaceType expectedType = null;
-    if (body.isAsynchronous) {
-      if (body.isGenerator) {
-        // Stream<T> -> T
-        expectedType = typeProvider.streamType;
-      } else {
-        // Future<T> -> T
-        // TODO(vsm): Revisit with issue #228.
-        expectedType = typeProvider.futureType;
-      }
-    } else {
-      if (body.isGenerator) {
-        // Iterable<T> -> T
-        expectedType = typeProvider.iterableType;
-      } else {
-        // T -> T
-        return type;
-      }
-    }
-    if (yieldStar) {
-      if (type.isDynamic) {
-        // Ensure it's at least a Stream / Iterable.
-        return expectedType.substitute4([typeProvider.dynamicType]);
-      } else {
-        // Analyzer will provide a separate error if expected type
-        // is not compatible with type.
-        return type;
-      }
-    }
-    if (type.isDynamic) {
-      return type;
-    } else if (type is InterfaceType && type.element == expectedType.element) {
-      return type.typeArguments[0];
-    } else {
-      // Malformed type - fallback on analyzer error.
-      return null;
-    }
-  }
-
-  @override
-  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    _checkReturnOrYield(node.expression, node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitReturnStatement(ReturnStatement node) {
-    _checkReturnOrYield(node.expression, node);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitYieldStatement(YieldStatement node) {
-    _checkReturnOrYield(node.expression, node, yieldStar: node.star != null);
-    node.visitChildren(this);
-  }
-
-  void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
-    if ((_isDynamicTarget(target) || field.staticElement == null) &&
-        !_isObjectProperty(target, field)) {
-      _recordDynamicInvoke(node, target);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPropertyAccess(PropertyAccess node) {
-    _checkFieldAccess(node, node.realTarget, node.propertyName);
-  }
-
-  @override
-  void visitPrefixedIdentifier(PrefixedIdentifier node) {
-    _checkFieldAccess(node, node.prefix, node.identifier);
-  }
-
-  @override
-  void visitDefaultFormalParameter(DefaultFormalParameter node) {
-    // Check that defaults have the proper subtype.
-    var parameter = node.parameter;
-    var parameterType = _elementType(parameter.element);
-    assert(parameterType != null);
-    var defaultValue = node.defaultValue;
-    if (defaultValue != null) {
-      checkAssignment(defaultValue, parameterType);
-    }
-
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitFieldFormalParameter(FieldFormalParameter node) {
-    var element = node.element;
-    var typeName = node.type;
-    if (typeName != null) {
-      var type = _elementType(element);
-      var fieldElement =
-          node.identifier.staticElement as FieldFormalParameterElement;
-      var fieldType = _elementType(fieldElement.field);
-      if (!rules.isSubtypeOf(type, fieldType)) {
-        var staticInfo =
-            new InvalidParameterDeclaration(rules, node, fieldType);
-        _recordMessage(staticInfo);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression node) {
-    var arguments = node.argumentList;
-    var element = node.staticElement;
-    if (element != null) {
-      var type = _elementType(node.staticElement);
-      checkArgumentList(arguments, type);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitVariableDeclarationList(VariableDeclarationList node) {
-    TypeName type = node.type;
-    if (type == null) {
-      // No checks are needed when the type is var. Although internally the
-      // typing rules may have inferred a more precise type for the variable
-      // based on the initializer.
-    } else {
-      var dartType = getType(type);
-      for (VariableDeclaration variable in node.variables) {
-        var initializer = variable.initializer;
-        if (initializer != null) {
-          checkAssignment(initializer, dartType);
-        }
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  void _checkRuntimeTypeCheck(AstNode node, TypeName typeName) {
-    var type = getType(typeName);
-    if (!rules.isGroundType(type)) {
-      _recordMessage(new NonGroundTypeCheckInfo(node, type));
-    }
-  }
-
-  @override
-  void visitAsExpression(AsExpression node) {
-    // We could do the same check as the IsExpression below, but that is
-    // potentially too conservative.  Instead, at runtime, we must fail hard
-    // if the Dart as and the DDC as would return different values.
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIsExpression(IsExpression node) {
-    _checkRuntimeTypeCheck(node, node.type);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPrefixExpression(PrefixExpression node) {
-    if (node.operator.type == TokenType.BANG) {
-      checkBoolean(node.operand);
-    } else {
-      _checkUnary(node);
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitPostfixExpression(PostfixExpression node) {
-    _checkUnary(node);
-    node.visitChildren(this);
-  }
-
-  void _checkUnary(/*PrefixExpression|PostfixExpression*/ node) {
-    var op = node.operator;
-    if (op.isUserDefinableOperator ||
-        op.type == TokenType.PLUS_PLUS ||
-        op.type == TokenType.MINUS_MINUS) {
-      if (_isDynamicTarget(node.operand)) {
-        _recordDynamicInvoke(node, node.operand);
-      }
-      // For ++ and --, even if it is not dynamic, we still need to check
-      // that the user defined method accepts an `int` as the RHS.
-      // We assume Analyzer has done this already.
-    }
-  }
-
-  @override
-  void visitBinaryExpression(BinaryExpression node) {
-    var op = node.operator;
-    if (op.isUserDefinableOperator) {
-      if (_isDynamicTarget(node.leftOperand)) {
-        // Dynamic invocation
-        // TODO(vsm): Move this logic to the resolver?
-        if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
-          _recordDynamicInvoke(node, node.leftOperand);
-        }
-      } else {
-        var element = node.staticElement;
-        // Method invocation.
-        if (element is MethodElement) {
-          var type = element.type;
-          // Analyzer should enforce number of parameter types, but check in
-          // case we have erroneous input.
-          if (type.normalParameterTypes.isNotEmpty) {
-            checkArgument(node.rightOperand, type.normalParameterTypes[0]);
-          }
-        } else {
-          // TODO(vsm): Assert that the analyzer found an error here?
-        }
-      }
-    } else {
-      // Non-method operator.
-      switch (op.type) {
-        case TokenType.AMPERSAND_AMPERSAND:
-        case TokenType.BAR_BAR:
-          checkBoolean(node.leftOperand);
-          checkBoolean(node.rightOperand);
-          break;
-        case TokenType.BANG_EQ:
-          break;
-        case TokenType.QUESTION_QUESTION:
-          break;
-        default:
-          assert(false);
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitConditionalExpression(ConditionalExpression node) {
-    checkBoolean(node.condition);
-    node.visitChildren(this);
-  }
-
-  @override
-  void visitIndexExpression(IndexExpression node) {
-    var target = node.realTarget;
-    if (_isDynamicTarget(target)) {
-      _recordDynamicInvoke(node, target);
-    } else {
-      var element = node.staticElement;
-      if (element is MethodElement) {
-        var type = element.type;
-        // Analyzer should enforce number of parameter types, but check in
-        // case we have erroneous input.
-        if (type.normalParameterTypes.isNotEmpty) {
-          checkArgument(node.index, type.normalParameterTypes[0]);
-        }
-      } else {
-        // TODO(vsm): Assert that the analyzer found an error here?
-      }
-    }
-    node.visitChildren(this);
-  }
-
-  DartType getType(TypeName name) {
-    return (name == null) ? DynamicTypeImpl.instance : name.type;
-  }
-
-  /// Analyzer checks boolean conversions, but we need to check too, because
-  /// it uses the default assignability rules that allow `dynamic` and `Object`
-  /// to be assigned to bool with no message.
-  void checkBoolean(Expression expr) =>
-      checkAssignment(expr, typeProvider.boolType);
-
-  void checkAssignment(Expression expr, DartType type) {
-    if (expr is ParenthesizedExpression) {
-      checkAssignment(expr.expression, type);
-    } else {
-      _recordMessage(_checkAssignment(expr, type));
-    }
-  }
-
-  StaticInfo _checkAssignment(Expression expr, DartType toT) {
-    final fromT = expr.staticType ?? DynamicTypeImpl.instance;
-    final Coercion c = _coerceTo(fromT, toT);
-    if (c is Identity) return null;
-    if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
-    var reason = null;
-
-    var errors = <String>[];
-
-    var ok = _inferExpression(expr, toT, errors);
-    if (ok) return InferredType.create(rules, expr, toT);
-    reason = (errors.isNotEmpty) ? errors.first : null;
-
-    if (c is Cast) return DownCast.create(rules, expr, c, reason: reason);
-    assert(false);
-    return null;
-  }
-
-  /// Checks if we can perform downwards inference on [e] tp get type [t].
-  /// If it is not possible, this will add a message to [errors].
-  bool _inferExpression(Expression e, DartType t, List<String> errors) {
-    DartType staticType = e.staticType ?? DynamicTypeImpl.instance;
-    if (rules.isSubtypeOf(staticType, t)) {
-      return true;
-    }
-    errors.add("$e cannot be typed as $t");
-    return false;
-  }
-
-  // Produce a coercion which coerces something of type fromT
-  // to something of type toT.
-  // Returns the error coercion if the types cannot be coerced
-  // according to our current criteria.
-  Coercion _coerceTo(DartType fromT, DartType toT) {
-    // We can use anything as void
-    if (toT.isVoid) return Coercion.identity(toT);
-
-    // fromT <: toT, no coercion needed
-    if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
-
-    // TODO(vsm): We can get rid of the second clause if we disallow
-    // all sideways casts - see TODO below.
-    // -------
-    // Note: a function type is never assignable to a class per the Dart
-    // spec - even if it has a compatible call method.  We disallow as
-    // well for consistency.
-    if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
-        (toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
-      return Coercion.error();
-    }
-
-    // Downcast if toT <: fromT
-    if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
-
-    // TODO(vsm): Once we have generic methods, we should delete this
-    // workaround.  These sideways casts are always ones we warn about
-    // - i.e., we think they are likely to fail at runtime.
-    // -------
-    // Downcast if toT <===> fromT
-    // The intention here is to allow casts that are sideways in the restricted
-    // type system, but allowed in the regular dart type system, since these
-    // are likely to succeed.  The canonical example is List<dynamic> and
-    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
-    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
-    if (fromT.isAssignableTo(toT)) {
-      return Coercion.cast(fromT, toT);
-    }
-
-    return Coercion.error();
-  }
-
-  DartType _specializedBinaryReturnType(
-      TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
-    // This special cases binary return types as per 16.26 and 16.27 of the
-    // Dart language spec.
-    switch (op) {
-      case TokenType.PLUS:
-      case TokenType.MINUS:
-      case TokenType.STAR:
-      case TokenType.TILDE_SLASH:
-      case TokenType.PERCENT:
-      case TokenType.PLUS_EQ:
-      case TokenType.MINUS_EQ:
-      case TokenType.STAR_EQ:
-      case TokenType.TILDE_SLASH_EQ:
-      case TokenType.PERCENT_EQ:
-        if (t1 == typeProvider.intType &&
-            t2 == typeProvider.intType) return t1;
-        if (t1 == typeProvider.doubleType &&
-            t2 == typeProvider.doubleType) return t1;
-        // This particular combo is not spelled out in the spec, but all
-        // implementations and analyzer seem to follow this.
-        if (t1 == typeProvider.doubleType &&
-            t2 == typeProvider.intType) return t1;
-    }
-    return normalReturnType;
-  }
-
-  void _checkCompoundAssignment(AssignmentExpression expr) {
-    var op = expr.operator.type;
-    assert(op.isAssignmentOperator && op != TokenType.EQ);
-    var methodElement = expr.staticElement;
-    if (methodElement == null) {
-      // Dynamic invocation
-      _recordDynamicInvoke(expr, expr.leftHandSide);
-    } else {
-      // Sanity check the operator
-      assert(methodElement.isOperator);
-      var functionType = methodElement.type;
-      var paramTypes = functionType.normalParameterTypes;
-      assert(paramTypes.length == 1);
-      assert(functionType.namedParameterTypes.isEmpty);
-      assert(functionType.optionalParameterTypes.isEmpty);
-
-      // Check the lhs type
-      var staticInfo;
-      var rhsType = _getStaticType(expr.rightHandSide);
-      var lhsType = _getStaticType(expr.leftHandSide);
-      var returnType = _specializedBinaryReturnType(
-          op, lhsType, rhsType, functionType.returnType);
-
-      if (!rules.isSubtypeOf(returnType, lhsType)) {
-        final numType = typeProvider.numType;
-        // Try to fix up the numerical case if possible.
-        if (rules.isSubtypeOf(lhsType, numType) &&
-            rules.isSubtypeOf(lhsType, rhsType)) {
-          // This is also slightly different from spec, but allows us to keep
-          // compound operators in the int += num and num += dynamic cases.
-          staticInfo = DownCast.create(
-              rules, expr.rightHandSide, Coercion.cast(rhsType, lhsType));
-          rhsType = lhsType;
-        } else {
-          // Static type error
-          staticInfo = new StaticTypeError(rules, expr, lhsType);
-        }
-        _recordMessage(staticInfo);
-      }
-
-      // Check the rhs type
-      if (staticInfo is! CoercionInfo) {
-        var paramType = paramTypes.first;
-        staticInfo = _checkAssignment(expr.rightHandSide, paramType);
-        _recordMessage(staticInfo);
-      }
-    }
-  }
-
-  bool _isObjectGetter(Expression target, SimpleIdentifier id) {
-    PropertyAccessorElement element =
-        typeProvider.objectType.element.getGetter(id.name);
-    return (element != null && !element.isStatic);
-  }
-
-  bool _isObjectMethod(Expression target, SimpleIdentifier id) {
-    MethodElement element =
-        typeProvider.objectType.element.getMethod(id.name);
-    return (element != null && !element.isStatic);
-  }
-
-  bool _isObjectProperty(Expression target, SimpleIdentifier id) {
-    return _isObjectGetter(target, id) || _isObjectMethod(target, id);
-  }
-
-  DartType _getStaticType(Expression expr) {
-    return expr.staticType ?? DynamicTypeImpl.instance;
-  }
-
-  void _recordDynamicInvoke(AstNode node, AstNode target) {
-    if (_hints) {
-      reporter.onError(new DynamicInvoke(rules, node).toAnalysisError());
-    }
-    // TODO(jmesserly): we may eventually want to record if the whole operation
-    // (node) was dynamic, rather than the target, but this is an easier fit
-    // with what we used to do.
-    DynamicInvoke.set(target, true);
-  }
-
-  void _recordMessage(StaticInfo info) {
-    if (info == null) return;
-    var error = info.toAnalysisError();
-    var severity = error.errorCode.errorSeverity;
-    if (severity == ErrorSeverity.ERROR) _failure = true;
-    if (severity != ErrorSeverity.INFO || _hints) {
-      reporter.onError(error);
-    }
-
-    if (info is CoercionInfo) {
-      // TODO(jmesserly): if we're run again on the same AST, we'll produce the
-      // same annotations. This should be harmless. This might go away once
-      // CodeChecker is integrated better with analyzer, as it will know that
-      // checking has already been performed.
-      // assert(CoercionInfo.get(info.node) == null);
-      CoercionInfo.set(info.node, info);
-    }
-  }
-
-  bool _isLibraryPrefix(Expression node) =>
-      node is SimpleIdentifier && node.staticElement is PrefixElement;
-
-  /// Returns `true` if the target expression is dynamic.
-  bool _isDynamicTarget(Expression node) {
-    if (node == null) return false;
-
-    if (_isLibraryPrefix(node)) return false;
-
-    // Null type happens when we have unknown identifiers, like a dart: import
-    // that doesn't resolve.
-    var type = node.staticType;
-    return type == null || type.isDynamic;
-  }
-
-  /// Returns `true` if the expression is a dynamic function call or method
-  /// invocation.
-  bool _isDynamicCall(Expression call) {
-    var ft = _getTypeAsCaller(call);
-    // TODO(leafp): This will currently return true if t is Function
-    // This is probably the most correct thing to do for now, since
-    // this code is also used by the back end.  Maybe revisit at some
-    // point?
-    if (ft == null) return true;
-    // Dynamic as the parameter type is treated as bottom.  A function with
-    // a dynamic parameter type requires a dynamic call in general.
-    // However, as an optimization, if we have an original definition, we know
-    // dynamic is reified as Object - in this case a regular call is fine.
-    if (call is SimpleIdentifier) {
-      var element = call.staticElement;
-      if (element is FunctionElement || element is MethodElement) {
-        // An original declaration.
-        return false;
-      }
-    }
-
-    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
-  }
-
-  /// Given an expression, return its type assuming it is
-  /// in the caller position of a call (that is, accounting
-  /// for the possibility of a call method).  Returns null
-  /// if expression is not statically callable.
-  FunctionType _getTypeAsCaller(Expression applicand) {
-    var t = applicand.staticType ?? DynamicTypeImpl.instance;
-    if (t is InterfaceType) {
-      return rules.getCallMethodType(t);
-    }
-    if (t is FunctionType) return t;
-    return null;
-  }
-}
-
-// Return the field on type corresponding to member, or null if none
-// exists or the "field" is actually a getter/setter.
-PropertyInducingElement _getMemberField(
-    InterfaceType type, PropertyAccessorElement member) {
-  String memberName = member.name;
-  PropertyInducingElement field;
-  if (member.isGetter) {
-    // The subclass member is an explicit getter or a field
-    // - lookup the getter on the superclass.
-    var getter = type.getGetter(memberName);
-    if (getter == null || getter.isStatic) return null;
-    field = getter.variable;
-  } else if (!member.isSynthetic) {
-    // The subclass member is an explicit setter
-    // - lookup the setter on the superclass.
-    // Note: an implicit (synthetic) setter would have already been flagged on
-    // the getter above.
-    var setter = type.getSetter(memberName);
-    if (setter == null || setter.isStatic) return null;
-    field = setter.variable;
-  } else {
-    return null;
-  }
-  if (field.isSynthetic) return null;
-  return field;
-}
-
-/// Looks up the declaration that matches [member] in [type] and returns it's
-/// declared type.
-FunctionType _getMemberType(InterfaceType type, ExecutableElement member) =>
-    _memberTypeGetter(member)(type);
-
-typedef FunctionType _MemberTypeGetter(InterfaceType type);
-
-_MemberTypeGetter _memberTypeGetter(ExecutableElement member) {
-  String memberName = member.name;
-  final isGetter = member is PropertyAccessorElement && member.isGetter;
-  final isSetter = member is PropertyAccessorElement && member.isSetter;
-
-  FunctionType f(InterfaceType type) {
-    ExecutableElement baseMethod;
-
-    if (member.isPrivate) {
-      var subtypeLibrary = member.library;
-      var baseLibrary = type.element.library;
-      if (baseLibrary != subtypeLibrary) {
-        return null;
-      }
-    }
-
-    try {
-      if (isGetter) {
-        assert(!isSetter);
-        // Look for getter or field.
-        baseMethod = type.getGetter(memberName);
-      } else if (isSetter) {
-        baseMethod = type.getSetter(memberName);
-      } else {
-        baseMethod = type.getMethod(memberName);
-      }
-    } catch (e) {
-      // TODO(sigmund): remove this try-catch block (see issue #48).
-    }
-    if (baseMethod == null || baseMethod.isStatic) return null;
-    return baseMethod.type;
-  }
-  return f;
-}
-
-
-DartType _elementType(Element e) {
-  if (e == null) {
-    // Malformed code - just return dynamic.
-    return DynamicTypeImpl.instance;
-  }
-  return (e as dynamic).type;
-}
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index 8b37962..cf4f822 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -8,8 +8,10 @@
 // refactored to fit into analyzer.
 library analyzer.src.task.strong.info;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 
@@ -83,8 +85,7 @@
 abstract class DownCast extends CoercionInfo {
   Cast _cast;
 
-  DownCast._internal(
-      TypeSystem rules, Expression expression, this._cast)
+  DownCast._internal(TypeSystem rules, Expression expression, this._cast)
       : super(rules, expression) {
     assert(_cast.toType != baseType &&
         _cast.fromType == baseType &&
@@ -183,8 +184,7 @@
 // A down cast to a non-ground type.  These behave differently from standard
 // Dart and may be more likely to fail at runtime.
 class DownCastComposite extends DownCast {
-  DownCastComposite(
-      TypeSystem rules, Expression expression, Cast cast)
+  DownCastComposite(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
@@ -276,8 +276,7 @@
 
 // An inferred type for a non-literal allocation site.
 class InferredTypeAllocation extends InferredTypeBase {
-  InferredTypeAllocation(
-      TypeSystem rules, Expression expression, DartType type)
+  InferredTypeAllocation(TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -303,8 +302,7 @@
 
 // An inferred type for a closure expression
 class InferredTypeClosure extends InferredTypeBase {
-  InferredTypeClosure(
-      TypeSystem rules, Expression expression, DartType type)
+  InferredTypeClosure(TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -313,8 +311,7 @@
 
 // An inferred type for a literal expression.
 class InferredTypeLiteral extends InferredTypeBase {
-  InferredTypeLiteral(
-      TypeSystem rules, Expression expression, DartType type)
+  InferredTypeLiteral(TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -391,8 +388,8 @@
 class InvalidParameterDeclaration extends StaticError {
   final DartType expectedType;
 
-  InvalidParameterDeclaration(TypeSystem rules,
-      FormalParameter declaration, this.expectedType)
+  InvalidParameterDeclaration(
+      TypeSystem rules, FormalParameter declaration, this.expectedType)
       : super(declaration);
 
   @override List<Object> get arguments => [node, expectedType];
@@ -539,8 +536,7 @@
   final DartType expectedType;
   String reason = null;
 
-  StaticTypeError(
-      TypeSystem rules, Expression expression, this.expectedType,
+  StaticTypeError(TypeSystem rules, Expression expression, this.expectedType,
       {this.reason})
       : baseType = expression.staticType ?? DynamicTypeImpl.instance,
         super(expression);
@@ -548,7 +544,7 @@
   @override List<Object> get arguments => [node, baseType, expectedType];
   @override String get message =>
       'Type check failed: {0} ({1}) is not of type {2}' +
-          ((reason == null) ? '' : ' because $reason');
+      ((reason == null) ? '' : ' because $reason');
 
   @override
   String get name => 'STRONG_MODE_STATIC_TYPE_ERROR';
@@ -565,8 +561,7 @@
 //
 // TODO(vsm,leafp): Remove this.
 class UninferredClosure extends DownCast {
-  UninferredClosure(
-      TypeSystem rules, FunctionExpression expression, Cast cast)
+  UninferredClosure(TypeSystem rules, FunctionExpression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index c3716ad..46b84e0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -6,8 +6,11 @@
 
 import 'dart:collection';
 
+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/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart'
     show TypeProvider, InheritanceManager;
 import 'package:analyzer/src/generated/type_system.dart';
@@ -137,6 +140,14 @@
   }
 
   /**
+   * Return `true` if the list of [elements] contains only methods.
+   */
+  bool _allSameElementKind(
+      ExecutableElement element, List<ExecutableElement> elements) {
+    return elements.every((e) => e.kind == element.kind);
+  }
+
+  /**
    * Compute the best type for the [parameter] at the given [index] that must be
    * compatible with the types of the corresponding parameters of the given
    * [overriddenMethods].
@@ -213,7 +224,7 @@
       matchingParameter = methodParameters.lastWhere(
           (ParameterElement methodParameter) =>
               methodParameter.parameterKind == ParameterKind.NAMED &&
-                  methodParameter.name == parameter.name,
+              methodParameter.name == parameter.name,
           orElse: () => null);
     } else {
       //
@@ -278,51 +289,10 @@
     }
   }
 
-  /**
-   * If the given [fieldElement] represents a non-synthetic instance field for
-   * which no type was provided, infer the type of the field.
-   */
-  void _inferField(FieldElement fieldElement) {
-    if (!fieldElement.isSynthetic &&
-        !fieldElement.isStatic &&
-        fieldElement.hasImplicitType) {
-      //
-      // First look for overridden getters with the same name as the field.
-      //
-      List<ExecutableElement> overriddenGetters = inheritanceManager
-          .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
-      DartType newType = null;
-      if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
-        newType = _computeReturnType(overriddenGetters);
-        List<ExecutableElement> overriddenSetters = inheritanceManager
-            .lookupOverrides(
-                fieldElement.enclosingElement, fieldElement.name + '=');
-        if (!_isCompatible(newType, overriddenSetters)) {
-          newType = null;
-        }
-      }
-      //
-      // If there is no overridden getter or if the overridden getter's type is
-      // dynamic, then we can infer the type from the initialization expression
-      // without breaking subtype rules. We could potentially infer a consistent
-      // return type even if the overridden getter's type was not dynamic, but
-      // choose not to for simplicity. The field is required to be final to
-      // prevent choosing a type that is inconsistent with assignments we cannot
-      // analyze.
-      //
-      if (newType == null || newType.isDynamic) {
-        if (fieldElement.initializer != null &&
-            (fieldElement.isFinal || overriddenGetters.isEmpty)) {
-          newType = fieldElement.initializer.returnType;
-        }
-      }
-      if (newType == null || newType.isBottom) {
-        newType = typeProvider.dynamicType;
-      }
-      (fieldElement as FieldElementImpl).type = newType;
-      setReturnType(fieldElement.getter, newType);
-      if (!fieldElement.isFinal && !fieldElement.isConst) {
-        setParameterType(fieldElement.setter, newType);
+  void _inferConstructorFieldFormals(ConstructorElement element) {
+    for (ParameterElement p in element.parameters) {
+      if (p is FieldFormalParameterElement) {
+        _inferFieldFormalParameter(p);
       }
     }
   }
@@ -377,29 +347,58 @@
   }
 
   /**
-   * If the given [element] is a non-synthetic getter or setter, update its
-   * synthetic variable's type to match the getter's return type, or if no
-   * corresponding getter exists, use the setter's parameter type.
-   *
-   * In general, the type of the synthetic variable should not be used, because
-   * getters and setters are independent methods. But this logic matches what
-   * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
+   * If the given [fieldElement] represents a non-synthetic instance field for
+   * which no type was provided, infer the type of the field.
    */
-  void _updateSyntheticVariableType(PropertyAccessorElement element) {
-    assert(!element.isSynthetic);
-    PropertyAccessorElement getter = element;
-    if (element.isSetter) {
-      // See if we can find any getter.
-      getter = element.correspondingGetter;
+  void _inferField(FieldElement fieldElement) {
+    if (!fieldElement.isSynthetic &&
+        !fieldElement.isStatic &&
+        fieldElement.hasImplicitType) {
+      //
+      // First look for overridden getters with the same name as the field.
+      //
+      List<ExecutableElement> overriddenGetters = inheritanceManager
+          .lookupOverrides(fieldElement.enclosingElement, fieldElement.name);
+      DartType newType = null;
+      if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) {
+        newType = _computeReturnType(overriddenGetters);
+        List<ExecutableElement> overriddenSetters =
+            inheritanceManager.lookupOverrides(
+                fieldElement.enclosingElement, fieldElement.name + '=');
+        if (!_isCompatible(newType, overriddenSetters)) {
+          newType = null;
+        }
+      }
+      //
+      // If there is no overridden getter or if the overridden getter's type is
+      // dynamic, then we can infer the type from the initialization expression
+      // without breaking subtype rules. We could potentially infer a consistent
+      // return type even if the overridden getter's type was not dynamic, but
+      // choose not to for simplicity. The field is required to be final to
+      // prevent choosing a type that is inconsistent with assignments we cannot
+      // analyze.
+      //
+      if (newType == null || newType.isDynamic) {
+        if (fieldElement.initializer != null &&
+            (fieldElement.isFinal || overriddenGetters.isEmpty)) {
+          newType = fieldElement.initializer.returnType;
+        }
+      }
+      if (newType == null || newType.isBottom) {
+        newType = typeProvider.dynamicType;
+      }
+      (fieldElement as FieldElementImpl).type = newType;
+      setReturnType(fieldElement.getter, newType);
+      if (!fieldElement.isFinal && !fieldElement.isConst) {
+        setParameterType(fieldElement.setter, newType);
+      }
     }
-    DartType newType;
-    if (getter != null) {
-      newType = getter.returnType;
-    } else if (element.isSetter && element.parameters.isNotEmpty) {
-      newType = element.parameters[0].type;
-    }
-    if (newType != null) {
-      (element.variable as VariableElementImpl).type = newType;
+  }
+
+  void _inferFieldFormalParameter(FieldFormalParameterElement element) {
+    FieldElement field = element.field;
+    if (field != null && element.hasImplicitType) {
+      (element as FieldFormalParameterElementImpl).type = field.type;
     }
   }
 
@@ -443,25 +442,29 @@
   }
 
   /**
-   * Return `true` if the list of [elements] contains only methods.
+   * If the given [element] is a non-synthetic getter or setter, update its
+   * synthetic variable's type to match the getter's return type, or if no
+   * corresponding getter exists, use the setter's parameter type.
+   *
+   * In general, the type of the synthetic variable should not be used, because
+   * getters and setters are independent methods. But this logic matches what
+   * `TypeResolverVisitor.visitMethodDeclaration` would fill in there.
    */
-  bool _allSameElementKind(
-      ExecutableElement element, List<ExecutableElement> elements) {
-    return elements.every((e) => e.kind == element.kind);
-  }
-
-  void _inferConstructorFieldFormals(ConstructorElement element) {
-    for (ParameterElement p in element.parameters) {
-      if (p is FieldFormalParameterElement) {
-        _inferFieldFormalParameter(p);
-      }
+  void _updateSyntheticVariableType(PropertyAccessorElement element) {
+    assert(!element.isSynthetic);
+    PropertyAccessorElement getter = element;
+    if (element.isSetter) {
+      // See if we can find any getter.
+      getter = element.correspondingGetter;
     }
-  }
-
-  void _inferFieldFormalParameter(FieldFormalParameterElement element) {
-    FieldElement field = element.field;
-    if (field != null && element.hasImplicitType) {
-      (element as FieldFormalParameterElementImpl).type = field.type;
+    DartType newType;
+    if (getter != null) {
+      newType = getter.returnType;
+    } else if (element.isSetter && element.parameters.isNotEmpty) {
+      newType = element.parameters[0].type;
+    }
+    if (newType != null) {
+      (element.variable as VariableElementImpl).type = newType;
     }
   }
 }
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/task/dart.dart
index 45fcb56..27258c3 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/task/dart.dart
@@ -4,8 +4,8 @@
 
 library analyzer.task.dart;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index d0ec89d..c320659 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -211,7 +211,7 @@
     } on AnalysisException catch (exception, stackTrace) {
       caughtException = new CaughtException(exception, stackTrace);
       AnalysisEngine.instance.logger
-          .logError("Task failed: ${description}", caughtException);
+          .logError("Task failed: $description", caughtException);
     }
   }
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index fab059e..7ab2b51 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.0
+version: 0.27.1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/dart/element/element_test.dart b/pkg/analyzer/test/dart/element/element_test.dart
new file mode 100644
index 0000000..ba6d5d1
--- /dev/null
+++ b/pkg/analyzer/test/dart/element/element_test.dart
@@ -0,0 +1,30 @@
+// 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.test.dart.element.element_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(ElementKindTest);
+}
+
+@reflectiveTest
+class ElementKindTest extends EngineTestCase {
+  void test_of_nonNull() {
+    expect(ElementKind.of(ElementFactory.classElement2("A")),
+        same(ElementKind.CLASS));
+  }
+
+  void test_of_null() {
+    expect(ElementKind.of(null), same(ElementKind.ERROR));
+  }
+}
diff --git a/pkg/analyzer/test/dart/element/test_all.dart b/pkg/analyzer/test/dart/element/test_all.dart
new file mode 100644
index 0000000..392c06a
--- /dev/null
+++ b/pkg/analyzer/test/dart/element/test_all.dart
@@ -0,0 +1,18 @@
+// 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.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'element_test.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('generated tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/dart/test_all.dart b/pkg/analyzer/test/dart/test_all.dart
new file mode 100644
index 0000000..669b706
--- /dev/null
+++ b/pkg/analyzer/test/dart/test_all.dart
@@ -0,0 +1,18 @@
+// 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.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../utils.dart';
+import 'element/test_all.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('dart tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 16d8f45..625cf40 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -6,7 +6,7 @@
 
 import 'dart:mirrors';
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 767f2c3..6f3aa5d 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -4,10 +4,12 @@
 
 library analyzer.test.generated.all_the_rest_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -573,19 +575,22 @@
     expect(_findConstants(), contains(field.element));
   }
 
-  void test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
+  void
+      test_visitVariableDeclaration_static_const_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.CONST,
         isStatic: true, hasConstConstructor: true);
     expect(_findConstants(), contains(field.element));
   }
 
-  void test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
+  void
+      test_visitVariableDeclaration_static_final_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
         isStatic: true, hasConstConstructor: true);
     expect(_findConstants(), isNot(contains(field.element)));
   }
 
-  void test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
+  void
+      test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
     VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
         isInitialized: false, hasConstConstructor: true);
     expect(_findConstants(), isNot(contains(field.element)));
@@ -619,8 +624,8 @@
 
   ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
     Keyword constKeyword = isConst ? Keyword.CONST : null;
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             constKeyword,
             null,
             null,
@@ -661,8 +666,8 @@
     classElement.fields = <FieldElement>[fieldElement];
     classDeclaration.name.staticElement = classElement;
     if (hasConstConstructor) {
-      ConstructorDeclaration constructorDeclaration = AstFactory
-          .constructorDeclaration2(
+      ConstructorDeclaration constructorDeclaration =
+          AstFactory.constructorDeclaration2(
               Keyword.CONST,
               null,
               AstFactory.identifier3(className),
@@ -1327,19 +1332,23 @@
     _assertIntField(fields, "k", 13);
   }
 
-  void test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
+  void
+      test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(false, true, true);
   }
 
-  void test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
+  void
+      test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(false, true, false);
   }
 
-  void test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
+  void
+      test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(false, false, true);
   }
 
-  void test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
+  void
+      test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(false, false, false);
   }
 
@@ -1432,19 +1441,23 @@
     _assertIntField(fields, "x", 42);
   }
 
-  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
+  void
+      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(true, true, true);
   }
 
-  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
+  void
+      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(true, true, false);
   }
 
-  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
+  void
+      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
     _checkInstanceCreationOptionalParams(true, false, true);
   }
 
-  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
+  void
+      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
     _checkInstanceCreationOptionalParams(true, false, false);
   }
 
@@ -4851,8 +4864,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4880,8 +4893,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             null,
             Keyword.FACTORY,
             AstFactory.identifier3(className),
@@ -4907,8 +4920,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4940,8 +4953,8 @@
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
     String constructorName = "c";
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -4969,8 +4982,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String className = "A";
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
             null,
             null,
             AstFactory.identifier3(className),
@@ -5050,8 +5063,8 @@
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String parameterName = 'p';
-    DefaultFormalParameter formalParameter = AstFactory
-        .positionalFormalParameter(
+    DefaultFormalParameter formalParameter =
+        AstFactory.positionalFormalParameter(
             AstFactory.simpleFormalParameter3(parameterName),
             AstFactory.integer(0));
     formalParameter.accept(builder);
@@ -6455,7 +6468,8 @@
         (obj) => obj is FunctionElement, FunctionElement, element);
   }
 
-  void test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() {
+  void
+      test_locate_Identifier_annotationClass_namedConstructor_forSimpleFormalParameter() {
     AstNode id = _findNodeIndexedIn(
         "Class",
         2,
@@ -6470,7 +6484,8 @@
         (obj) => obj is ClassElement, ClassElement, element);
   }
 
-  void test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() {
+  void
+      test_locate_Identifier_annotationClass_unnamedConstructor_forSimpleFormalParameter() {
     AstNode id = _findNodeIndexedIn(
         "Class",
         2,
@@ -6577,8 +6592,8 @@
     SimpleIdentifier identifier = AstFactory.identifier3("A");
     PrefixedIdentifier prefixedIdentifier =
         AstFactory.identifier4("pref", identifier);
-    InstanceCreationExpression creation = AstFactory
-        .instanceCreationExpression2(
+    InstanceCreationExpression creation =
+        AstFactory.instanceCreationExpression2(
             Keyword.NEW, AstFactory.typeName3(prefixedIdentifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
@@ -6595,8 +6610,8 @@
   void test_locate_InstanceCreationExpression_type_simpleIdentifier() {
     // prepare: new A()
     SimpleIdentifier identifier = AstFactory.identifier3("A");
-    InstanceCreationExpression creation = AstFactory
-        .instanceCreationExpression2(
+    InstanceCreationExpression creation =
+        AstFactory.instanceCreationExpression2(
             Keyword.NEW, AstFactory.typeName3(identifier));
     // set ClassElement
     ClassElement classElement = ElementFactory.classElement2("A");
@@ -8101,8 +8116,8 @@
       String name, bool isConst) {
     List<ConstructorInitializer> initializers =
         new List<ConstructorInitializer>();
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration(AstFactory.identifier3(name), null,
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration(AstFactory.identifier3(name), null,
             AstFactory.formalParameterList(), initializers);
     if (isConst) {
       constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
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 a30a2cb..5f2abf5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -1968,8 +1968,7 @@
     Source source = addSource("class A extends double {}");
     computeLibrarySourceErrors(source);
     assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
     ]);
     verify([source]);
   }
@@ -1998,8 +1997,7 @@
     Source source = addSource("class A extends num {}");
     computeLibrarySourceErrors(source);
     assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS,
-      CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT
+      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
     ]);
     verify([source]);
   }
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index a3d0b66..5ee43e4 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -4,8 +4,8 @@
 
 library engine.declaration_resolver_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 243f273..a404b92 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -6,11 +6,11 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index b36d31e..ca12036 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4,9 +4,10 @@
 
 library analyzer.test.generated.incremental_resolver_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart' as log;
@@ -4444,8 +4445,10 @@
     CacheEntry cacheEntry = cache.get(target);
     expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(2));
     cacheEntry.setState(VERIFY_ERRORS, CacheState.INVALID);
-    // Don't run tasks, so don't recompute VERIFY_ERRORS before incremental.
-    _updateAndValidate(
+    // Perform incremental resolution.
+    _resetWithIncremental(true);
+    analysisContext2.setContents(
+        source,
         r'''
 main() {
   foo(0);
@@ -4454,10 +4457,12 @@
   foo('bbb');
 }
 foo(int p) {}
-''',
-        runTasksBeforeIncremental: false);
-    // Incremental analysis should have left VERIFY_ERRORS invalid,
-    // so it was correctly recomputed later during the full analysis.
+''');
+    // VERIFY_ERRORS is still invalid.
+    expect(cacheEntry.getState(VERIFY_ERRORS), CacheState.INVALID);
+    // Continue analysis - run tasks, so recompute VERIFY_ERRORS.
+    _runTasks();
+    expect(cacheEntry.getState(VERIFY_ERRORS), CacheState.VALID);
     expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(1));
   }
 
@@ -4523,6 +4528,47 @@
 ''');
   }
 
+  void test_visibleRange() {
+    _resolveUnit(r'''
+class Test {
+  method1(p1) {
+    var v1;
+    f1() {}
+    return 1;
+  }
+  method2(p2) {
+    var v2;
+    f2() {}
+    return 2;
+  }
+  method3(p3) {
+    var v3;
+    f3() {}
+    return 3;
+  }
+}
+''');
+    _updateAndValidate(r'''
+class Test {
+  method1(p1) {
+    var v1;
+    f1() {}
+    return 1;
+  }
+  method2(p2) {
+    var v2;
+    f2() {}
+    return 2222;
+  }
+  method3(p3) {
+    var v3;
+    f3() {}
+    return 3;
+  }
+}
+''');
+  }
+
   void test_whitespace_getElementAt() {
     _resolveUnit(r'''
 class A {}
@@ -4628,6 +4674,7 @@
     // Resolve "newCode" from scratch.
     if (compareWithFull) {
       _resetWithIncremental(false);
+      changeSource(source, '');
       changeSource(source, newCode);
       _runTasks();
       LibraryElement library = resolve2(source);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 24928c2..349cd0a 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -4,8 +4,8 @@
 
 library analyzer.test.generated.non_error_resolver_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -926,10 +926,9 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, "p]");
+      expect(ref.staticElement, new isInstanceOf<ParameterElement>());
     }
   }
 
@@ -948,22 +947,22 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "Samurai]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'Samurai]');
       ClassElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'Samurai');
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "int]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
       ClassElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'int');
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "WITH_SWORD]", (node) => node is SimpleIdentifier);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'WITH_SWORD]');
       PropertyAccessorElement refElement = ref.staticElement;
       expect(refElement, isNotNull);
       expect(refElement.name, 'WITH_SWORD');
@@ -980,10 +979,9 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "p]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ParameterElement, ParameterElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
   }
 
   void test_commentReference_beforeFunction_expressionBody() {
@@ -995,10 +993,42 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "p]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ParameterElement, ParameterElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
+  }
+
+  void test_commentReference_beforeFunctionTypeAlias() {
+    String code = r'''
+/// [p]
+typedef Foo(int p);
+''';
+    Source source = addSource(code);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'p]');
+    expect(ref.staticElement, new isInstanceOf<ParameterElement>());
+  }
+
+  void test_commentReference_beforeGetter() {
+    String code = r'''
+abstract class A {
+  /// [int]
+  get g => null;
+}''';
+    Source source = addSource(code);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    {
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'int]');
+      expect(ref.staticElement, isNotNull);
+    }
   }
 
   void test_commentReference_beforeMethod() {
@@ -1008,24 +1038,27 @@
   ma(int p1) {}
   /// [p2]
   mb(int p2);
+  /// [p3] and [p4]
+  mc(int p3, p4());
+  /// [p5]
+  md(int p5, {int p6});
 }''';
     Source source = addSource(code);
     computeLibrarySourceErrors(source);
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p1]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
+    assertIsParameter(String search) {
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, search);
+      expect(ref.staticElement, new isInstanceOf<ParameterElement>());
     }
-    {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "p2]", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is ParameterElement,
-          ParameterElement, ref.staticElement);
-    }
+    assertIsParameter('p1');
+    assertIsParameter('p2');
+    assertIsParameter('p3');
+    assertIsParameter('p4');
+    assertIsParameter('p5');
+    assertIsParameter('p6');
   }
 
   void test_commentReference_class() {
@@ -1039,10 +1072,9 @@
     assertNoErrors(source);
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
-    SimpleIdentifier ref = EngineTestCase.findNode(
-        unit, code, "foo]", (node) => node is SimpleIdentifier);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is MethodElement, MethodElement, ref.staticElement);
+    SimpleIdentifier ref =
+        EngineTestCase.findSimpleIdentifier(unit, code, 'foo]');
+    expect(ref.staticElement, new isInstanceOf<MethodElement>());
   }
 
   void test_commentReference_setter() {
@@ -1063,16 +1095,14 @@
     verify([source]);
     CompilationUnit unit = _getResolvedLibraryUnit(source);
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "x] in A", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
-          PropertyAccessorElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, "x] in A");
+      expect(ref.staticElement, new isInstanceOf<PropertyAccessorElement>());
     }
     {
-      SimpleIdentifier ref = EngineTestCase.findNode(
-          unit, code, "x] in B", (node) => node is SimpleIdentifier);
-      EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccessorElement,
-          PropertyAccessorElement, ref.staticElement);
+      SimpleIdentifier ref =
+          EngineTestCase.findSimpleIdentifier(unit, code, 'x] in B');
+      expect(ref.staticElement, new isInstanceOf<PropertyAccessorElement>());
     }
   }
 
@@ -1432,6 +1462,19 @@
     verify([source]);
   }
 
+  void test_constWithNonConstantArgument_constField() {
+    Source source = addSource(r'''
+class A {
+  const A(x);
+}
+main() {
+  const A(double.INFINITY);
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_constWithNonConstantArgument_literals() {
     Source source = addSource(r'''
 class A {
@@ -3569,7 +3612,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_getter() {
     Source source = addSource(r'''
 class A {
   int get g => 0;
@@ -3583,7 +3627,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_method() {
     Source source = addSource(r'''
 class A {
   m(p) {}
@@ -3597,7 +3642,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter() {
     Source source = addSource(r'''
 class A {
   set s(v) {}
@@ -3611,7 +3657,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
     // 15979
     Source source = addSource(r'''
 abstract class M {}
@@ -3638,7 +3685,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
     // 15979
     Source source = addSource(r'''
 class M {}
@@ -3736,7 +3784,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_noSuchMethod_superclass() {
     Source source = addSource(r'''
 class A {
   noSuchMethod(v) => '';
@@ -3749,7 +3798,8 @@
     verify([source]);
   }
 
-  void test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() {
+  void
+      test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() {
     Source source = addSource(r'''
 class A {
   String toString([String prefix = '']) => '${prefix}Hello';
@@ -3850,6 +3900,15 @@
     verify([source]);
   }
 
+  void test_nonConstantDefaultValue_constField() {
+    Source source = addSource(r'''
+f([a = double.INFINITY]) {
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstantDefaultValue_function_named() {
     Source source = addSource("f({x : 2 + 3}) {}");
     computeLibrarySourceErrors(source);
@@ -3904,6 +3963,19 @@
     verify([source]);
   }
 
+  void test_nonConstantDefaultValue_typedConstList() {
+    Source source = addSource(r'''
+class A {
+  m([p111 = const <String>[]]) {}
+}
+class B extends A {
+  m([p222 = const <String>[]]) {}
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstantValueInInitializer_namedArgument() {
     Source source = addSource(r'''
 class A {
@@ -3918,7 +3990,23 @@
     verify([source]);
   }
 
-  void test_nonConstCaseExpression() {
+  void test_nonConstCaseExpression_constField() {
+    Source source = addSource(r'''
+f(double p) {
+  switch (p) {
+    case double.INFINITY:
+      return true;
+    default:
+      return false;
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  void test_nonConstCaseExpression_typeLiteral() {
     Source source = addSource(r'''
 f(Type t) {
   switch (t) {
@@ -3934,6 +4022,16 @@
     verify([source]);
   }
 
+  void test_nonConstListElement_constField() {
+    Source source = addSource(r'''
+main() {
+  const [double.INFINITY];
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstMapAsExpressionStatement_const() {
     Source source = addSource(r'''
 f() {
@@ -3964,6 +4062,27 @@
     verify([source]);
   }
 
+  void test_nonConstMapKey_constField() {
+    Source source = addSource(r'''
+main() {
+  const {double.INFINITY: 0};
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  void test_nonConstMapValue_constField() {
+    Source source = addSource(r'''
+main() {
+  const {0: double.INFINITY};
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonConstValueInInitializer_binary_bool() {
     Source source = addSource(r'''
 class A {
@@ -4979,7 +5098,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() {
+  void
+      test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -5016,7 +5136,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 574832b..96a4b3e 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -4,8 +4,10 @@
 
 library analyzer.test.generated.parser_test;
 
+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/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_scanner.dart';
@@ -1070,8 +1072,8 @@
   }
 
   void test_expectedToken_whileMissingInDoStatement() {
-    ParserTestCase.parseStatement(
-        "do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
+    ParserTestCase
+        .parseStatement("do {} (x);", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_expectedTypeName_is() {
@@ -1253,8 +1255,8 @@
   }
 
   void test_getterInFunction_expression_noReturnType() {
-    ParserTestCase.parseStatement(
-        "get x => _x;", [ParserErrorCode.GETTER_IN_FUNCTION]);
+    ParserTestCase
+        .parseStatement("get x => _x;", [ParserErrorCode.GETTER_IN_FUNCTION]);
   }
 
   void test_getterInFunction_expression_returnType() {
@@ -1962,9 +1964,9 @@
         "parseSwitchStatement",
         "switch (a) {default: return 0; default: return 1; default: return 2;}",
         [
-      ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
-      ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
-    ]);
+          ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
+          ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
+        ]);
   }
 
   void test_topLevel_getter() {
@@ -2054,10 +2056,10 @@
 void main() {
   var x = "''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_at_eol() {
@@ -2083,10 +2085,10 @@
 void main() {
   var x = """''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_multiline_at_eof_4_quotes() {
@@ -2098,10 +2100,10 @@
 void main() {
   var x = """"''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_unterminatedString_multiline_at_eof_5_quotes() {
@@ -2113,10 +2115,10 @@
 void main() {
   var x = """""''',
         [
-      ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
-      ParserErrorCode.EXPECTED_TOKEN,
-      ParserErrorCode.EXPECTED_TOKEN
-    ]);
+          ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+          ParserErrorCode.EXPECTED_TOKEN,
+          ParserErrorCode.EXPECTED_TOKEN
+        ]);
   }
 
   void test_useOfUnaryPlusOperator() {
@@ -2133,8 +2135,8 @@
   }
 
   void test_varAndType_topLevelVariable() {
-    ParserTestCase.parseCompilationUnit(
-        "var int x;", [ParserErrorCode.VAR_AND_TYPE]);
+    ParserTestCase
+        .parseCompilationUnit("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
   }
 
   void test_varAsTypeName_as() {
@@ -2142,13 +2144,13 @@
   }
 
   void test_varClass() {
-    ParserTestCase.parseCompilationUnit(
-        "var class C {}", [ParserErrorCode.VAR_CLASS]);
+    ParserTestCase
+        .parseCompilationUnit("var class C {}", [ParserErrorCode.VAR_CLASS]);
   }
 
   void test_varEnum() {
-    ParserTestCase.parseCompilationUnit(
-        "var enum E {ONE}", [ParserErrorCode.VAR_ENUM]);
+    ParserTestCase
+        .parseCompilationUnit("var enum E {ONE}", [ParserErrorCode.VAR_ENUM]);
   }
 
   void test_varReturnType() {
@@ -2177,13 +2179,13 @@
   }
 
   void test_voidVariable_parseCompilationUnit_initializer() {
-    ParserTestCase.parseCompilationUnit(
-        "void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase
+        .parseCompilationUnit("void x = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnit_noInitializer() {
-    ParserTestCase.parseCompilationUnit(
-        "void x;", [ParserErrorCode.VOID_VARIABLE]);
+    ParserTestCase
+        .parseCompilationUnit("void x;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnitMember_initializer() {
@@ -3483,8 +3485,8 @@
   }
 
   void test_incomplete_topLevelVariable() {
-    CompilationUnit unit = ParserTestCase.parseCompilationUnit(
-        "String", [ParserErrorCode.EXPECTED_EXECUTABLE]);
+    CompilationUnit unit = ParserTestCase
+        .parseCompilationUnit("String", [ParserErrorCode.EXPECTED_EXECUTABLE]);
     NodeList<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
     CompilationUnitMember member = declarations[0];
@@ -3633,8 +3635,8 @@
   }
 
   void test_incompleteLocalVariable_atTheEndOfBlock() {
-    Statement statement = ParserTestCase.parseStatement(
-        'String v }', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('String v }', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'String v;');
   }
@@ -3654,15 +3656,15 @@
   }
 
   void test_incompleteLocalVariable_beforeNextBlock() {
-    Statement statement = ParserTestCase.parseStatement(
-        'String v {}', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('String v {}', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'String v;');
   }
 
   void test_incompleteLocalVariable_parameterizedType() {
-    Statement statement = ParserTestCase.parseStatement(
-        'List<String> v {}', [ParserErrorCode.EXPECTED_TOKEN]);
+    Statement statement = ParserTestCase
+        .parseStatement('List<String> v {}', [ParserErrorCode.EXPECTED_TOKEN]);
     expect(statement, new isInstanceOf<VariableDeclarationStatement>());
     expect(statement.toSource(), 'List<String> v;');
   }
@@ -4817,28 +4819,34 @@
     ParserTestCase.parseCompilationUnit("var x = () {};");
   }
 
-  void test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = f(() {}); }");
   }
 
-  void test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = x[() {}]; }");
   }
 
-  void test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = [() {}]; }");
   }
 
-  void test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer() {
     ParserTestCase
         .parseCompilationUnit("class C { C() : a = {'key': () {}}; }");
   }
 
-  void test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = (() {}); }");
   }
 
-  void test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer() {
+  void
+      test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer() {
     ParserTestCase.parseCompilationUnit("class C { C() : a = \"\${(){}}\"; }");
   }
 
@@ -5218,7 +5226,8 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
-  void test_parseAssignableExpression_expression_args_dot_typeParameterComments() {
+  void
+      test_parseAssignableExpression_expression_args_dot_typeParameterComments() {
     enableGenericMethodComments = true;
     PropertyAccess propertyAccess =
         parse("parseAssignableExpression", <Object>[false], "(x)/*<F>*/(y).z");
@@ -5292,7 +5301,8 @@
     expect(propertyAccess.propertyName, isNotNull);
   }
 
-  void test_parseAssignableExpression_identifier_args_dot_typeParameterComments() {
+  void
+      test_parseAssignableExpression_identifier_args_dot_typeParameterComments() {
     enableGenericMethodComments = true;
     PropertyAccess propertyAccess =
         parse("parseAssignableExpression", <Object>[false], "x/*<E>*/(y).z");
@@ -6754,6 +6764,28 @@
     expect(reference.offset, 35);
   }
 
+  void test_parseCommentReferences_skipCodeBlock_4spaces_block() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
+          "/**\n *     a[i]\n * non-code line\n */", 3)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, isEmpty);
+  }
+
+  void test_parseCommentReferences_skipCodeBlock_4spaces_lines() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.SINGLE_LINE_COMMENT, "/// Code block:", 0),
+      new DocumentationCommentToken(
+          TokenType.SINGLE_LINE_COMMENT, "///     a[i] == b[i]", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, isEmpty);
+  }
+
   void test_parseCommentReferences_skipCodeBlock_bracketed() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(
@@ -6768,6 +6800,30 @@
     expect(reference.offset, 24);
   }
 
+  void test_parseCommentReferences_skipCodeBlock_gitHub() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT, "/** `a[i]` and [b] */", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, hasLength(1));
+    CommentReference reference = references[0];
+    expect(reference, isNotNull);
+    expect(reference.identifier, isNotNull);
+    expect(reference.offset, 16);
+  }
+
+  void test_parseCommentReferences_skipCodeBlock_gitHub_notTerminated() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT, "/** `a[i] and [b] */", 0)
+    ];
+    List<CommentReference> references =
+        parse("parseCommentReferences", <Object>[tokens], "");
+    expect(references, hasLength(2));
+  }
+
   void test_parseCommentReferences_skipCodeBlock_spaces() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
@@ -7770,7 +7826,8 @@
     expect(invocation.argumentList, isNotNull);
   }
 
-  void test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
+  void
+      test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
     enableGenericMethodComments = true;
     MethodInvocation invocation =
         parse4("parseExpressionWithoutCascade", "super.m/*<E>*/()");
@@ -7780,7 +7837,8 @@
     expect(invocation.argumentList, isNotNull);
   }
 
-  void test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
+  void
+      test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation invocation =
         parse4("parseExpressionWithoutCascade", "super.m<E>()");
@@ -9630,7 +9688,8 @@
     expect(expression.argumentList, isNotNull);
   }
 
-  void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
+  void
+      test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
     enableGenericMethodComments = true;
     MethodInvocation expression =
         parse4('parsePostfixExpression', 'a?.m/*<E>*/()');
@@ -9641,7 +9700,8 @@
     expect(expression.argumentList, isNotNull);
   }
 
-  void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
+  void
+      test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
     enableGenericMethods = true;
     MethodInvocation expression = parse4('parsePostfixExpression', 'a?.m<E>()');
     expect(expression.target, isNotNull);
@@ -9651,7 +9711,8 @@
     expect(expression.argumentList, isNotNull);
   }
 
-  void test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
+  void
+      test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
     enableGenericMethodComments = true;
     MethodInvocation expression =
         parse4("parsePostfixExpression", "a.m/*<E>*/()");
@@ -10015,7 +10076,8 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
-  void test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+  void
+      test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
     enableGenericMethodComments = true;
     FunctionDeclarationStatement statement =
         parse4("parseStatement", "f/*<E>*/(a, b) {};");
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index c57ca34..8c24fb2 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -6,9 +6,13 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -118,6 +122,10 @@
     coreContext.setContents(coreSource, "");
     coreUnit.librarySource = coreUnit.source = coreSource;
     ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
+    proxyClassElement.constructors = <ConstructorElement>[
+      ElementFactory.constructorElement(proxyClassElement, null, true)
+        ..isCycleFree = true
+    ];
     ClassElement objectClassElement = provider.objectType.element;
     coreUnit.types = <ClassElement>[
       provider.boolType.element,
@@ -193,8 +201,8 @@
         'onValue', futureThenR, [futureElement.typeParameters[0]], null);
 
     DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
-    MethodElementImpl thenMethod = ElementFactory
-        .methodElementWithParameters(futureElement, "then", futureRType, [
+    MethodElementImpl thenMethod = ElementFactory.methodElementWithParameters(
+        futureElement, "then", futureRType, [
       ElementFactory.requiredParameter2("onValue", thenOnValue.type),
       ElementFactory.namedParameter2("onError", provider.functionType)
     ]);
@@ -245,7 +253,8 @@
     asyncUnit.types = <ClassElement>[
       completerElement,
       futureElement,
-      streamElement
+      streamElement,
+      streamSubscriptionElement
     ];
     LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
         coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
@@ -282,8 +291,8 @@
     ClassElementImpl htmlDocumentElement =
         ElementFactory.classElement("HtmlDocument", documentElement.type);
     htmlDocumentElement.methods = <MethodElement>[
-      ElementFactory
-          .methodElement("query", elementType, <DartType>[provider.stringType])
+      ElementFactory.methodElement(
+          "query", elementType, <DartType>[provider.stringType])
     ];
     htmlUnit.types = <ClassElement>[
       ElementFactory.classElement("AnchorElement", elementType),
@@ -303,8 +312,8 @@
       ElementFactory.functionElement3("query", elementElement,
           <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
     ];
-    TopLevelVariableElementImpl document =
-        ElementFactory.topLevelVariableElement3(
+    TopLevelVariableElementImpl document = ElementFactory
+        .topLevelVariableElement3(
             "document", false, true, htmlDocumentElement.type);
     htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
     htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
@@ -1417,6 +1426,47 @@
     _listener.assertNoErrors();
   }
 
+  void test_visitCommentReference_prefixedIdentifier_class_getter() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // set accessors
+    String propName = "p";
+    PropertyAccessorElement getter =
+        ElementFactory.getterElement(propName, false, _typeProvider.intType);
+    PropertyAccessorElement setter =
+        ElementFactory.setterElement(propName, false, _typeProvider.intType);
+    classA.accessors = <PropertyAccessorElement>[getter, setter];
+    // set name scope
+    _visitor.nameScope = new EnclosedScope(null)
+      ..defineNameWithoutChecking('A', classA);
+    // prepare "A.p"
+    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'p');
+    CommentReference commentReference = new CommentReference(null, prefixed);
+    // resolve
+    _resolveNode(commentReference);
+    expect(prefixed.prefix.staticElement, classA);
+    expect(prefixed.identifier.staticElement, getter);
+    _listener.assertNoErrors();
+  }
+
+  void test_visitCommentReference_prefixedIdentifier_class_method() {
+    ClassElementImpl classA = ElementFactory.classElement2("A");
+    // set method
+    MethodElement method =
+        ElementFactory.methodElement("m", _typeProvider.intType);
+    classA.methods = <MethodElement>[method];
+    // set name scope
+    _visitor.nameScope = new EnclosedScope(null)
+      ..defineNameWithoutChecking('A', classA);
+    // prepare "A.m"
+    PrefixedIdentifier prefixed = AstFactory.identifier5('A', 'm');
+    CommentReference commentReference = new CommentReference(null, prefixed);
+    // resolve
+    _resolveNode(commentReference);
+    expect(prefixed.prefix.staticElement, classA);
+    expect(prefixed.identifier.staticElement, method);
+    _listener.assertNoErrors();
+  }
+
   void test_visitConstructorName_named() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String constructorName = "a";
@@ -3643,6 +3693,22 @@
     verify([source]);
   }
 
+  void test_unusedElement_class_isUsed_fieldDeclaration() {
+    enableUnusedElement = true;
+    var src = r'''
+class Foo {
+  _Bar x;
+}
+
+class _Bar {
+}
+''';
+    Source source = addSource(src);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unusedElement_class_isUsed_implements() {
     enableUnusedElement = true;
     Source source = addSource(r'''
@@ -3762,22 +3828,6 @@
     verify([source]);
   }
 
-  void test_unusedElement_class_isUsed_fieldDeclaration() {
-    enableUnusedElement = true;
-    var src = r'''
-class Foo {
-  _Bar x;
-}
-
-class _Bar {
-}
-''';
-    Source source = addSource(src);
-    computeLibrarySourceErrors(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_unusedElement_class_notUsed_variableDeclaration() {
     enableUnusedElement = true;
     Source source = addSource(r'''
@@ -5103,8 +5153,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
+  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I2, I1 {}
@@ -5127,8 +5176,7 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
+  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I1, I2 {}
@@ -5138,8 +5186,8 @@
         ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElement methodM2 = ElementFactory
-        .methodElement(methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM2 = ElementFactory.methodElement(
+        methodName, null, [_typeProvider.stringType]);
     classI2.methods = <MethodElement>[methodM2];
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
@@ -5151,8 +5199,7 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
+  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I1, I2 {}
@@ -5175,8 +5222,7 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
+  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
     // class I1 { dynamic m(int, [int]); }
     // class I2 { dynamic m(int, int, int); }
     // class A implements I1, I2 {}
@@ -5225,15 +5271,14 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
+  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I2, I1 {}
     ClassElementImpl classI1 = ElementFactory.classElement2("I1");
     String methodName = "m";
-    MethodElement methodM1 = ElementFactory
-        .methodElement(methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM1 = ElementFactory.methodElement(
+        methodName, null, [_typeProvider.stringType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
     MethodElement methodM2 =
@@ -5335,8 +5380,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
     // class I1 { int get g; }
     // class I2 { num get g; }
     // class A implements I1, I2 {}
@@ -5360,8 +5404,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
     // class I1 { dynamic m(int); }
     // class I2 { dynamic m(num); }
     // class A implements I1, I2 {}
@@ -5395,8 +5438,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
     // class I1 { set s(int); }
     // class I2 { set s(num); }
     // class A implements I1, I2 {}
@@ -5421,8 +5463,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5461,8 +5502,7 @@
     _assertNoErrors(classD);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5516,8 +5556,7 @@
     _assertNoErrors(classD);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5557,8 +5596,7 @@
     _assertNoErrors(classD);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class A implements I1, I2 {}
@@ -5585,8 +5623,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class I3 { int m([int, int]); }
@@ -5631,8 +5668,7 @@
     _assertNoErrors(classA);
   }
 
-  void
-      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
+  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
     // class I1 { int m(); }
     // class I2 { int m(); }
     // class I3 { int m([int]); }
@@ -9334,9 +9370,7 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0]
-        .name
-        .staticElement;
+        .variables[0].name.staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -9527,9 +9561,7 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0]
-        .name
-        .staticElement;
+        .variables[0].name.staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -11752,17 +11784,17 @@
   TypeAssertions _assertions;
   AsserterBuilder<Element, DartType> _hasElement;
   AsserterBuilder<DartType, DartType> _isType;
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
-      _isFunction2Of;
-  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
-      _isInstantiationOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
+      DartType> _isFunction2Of;
+  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>,
+      DartType> _isInstantiationOf;
   Asserter<DartType> _isInt;
   Asserter<DartType> _isNum;
   Asserter<DartType> _isString;
   Asserter<DartType> _isDynamic;
   AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
-      _isMapOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
+      InterfaceType> _isMapOf;
 
   @override
   void setUp() {
@@ -13993,8 +14025,7 @@
         code, typeProvider.dynamicType, typeProvider.intType);
   }
 
-  void
-      test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
+  void test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
     addNamedSource(
         "/lib.dart",
         r'''
@@ -14213,8 +14244,7 @@
     expect(vParameter.identifier.propagatedType, same(stringType));
   }
 
-  void
-      test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
+  void test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
     String code = r'''
 main() {
   (f(String value)) {} ((v) {
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 48bbfb2..e737b56 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -11,7 +11,6 @@
 import 'ast_test.dart' as ast_test;
 import 'compile_time_error_code_test.dart' as compile_time_error_code_test;
 import 'declaration_resolver_test.dart' as declaration_resolver_test;
-import 'element_test.dart' as element_test;
 import 'engine_test.dart' as engine_test;
 import 'incremental_resolver_test.dart' as incremental_resolver_test;
 import 'incremental_scanner_test.dart' as incremental_scanner_test;
@@ -35,7 +34,6 @@
     ast_test.main();
     compile_time_error_code_test.main();
     declaration_resolver_test.main();
-    element_test.main();
     engine_test.main();
     incremental_resolver_test.main();
     incremental_scanner_test.main();
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index b3e9215..9db703b 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -6,8 +6,10 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/ast.dart' show AstNode, NodeLocator;
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/generated/ast.dart'
+    show AstNode, NodeLocator, SimpleIdentifier;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -132,6 +134,18 @@
     AstNode node = new NodeLocator(offset).searchWithin(root);
     return node.getAncestor(predicate);
   }
+
+  /**
+   * Find the [SimpleIdentifier] with at offset of the "prefix".
+   */
+  static SimpleIdentifier findSimpleIdentifier(
+      AstNode root, String code, String prefix) {
+    int offset = code.indexOf(prefix);
+    if (offset == -1) {
+      throw new IllegalArgumentException("Not found '$prefix'.");
+    }
+    return new NodeLocator(offset).searchWithin(root);
+  }
 }
 
 /**
@@ -409,9 +423,9 @@
    */
   bool _equalErrors(AnalysisError firstError, AnalysisError secondError) =>
       identical(firstError.errorCode, secondError.errorCode) &&
-          firstError.offset == secondError.offset &&
-          firstError.length == secondError.length &&
-          _equalSources(firstError.source, secondError.source);
+      firstError.offset == secondError.offset &&
+      firstError.length == secondError.length &&
+      _equalSources(firstError.source, secondError.source);
 
   /**
    * Return `true` if the two sources are equivalent.
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index cd16dcf..6486b63 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -6,7 +6,10 @@
 
 library analyzer.test.generated.type_system_test;
 
-import 'package:analyzer/src/generated/element.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/resolver.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
@@ -118,14 +121,14 @@
   }
 
   void test_isAssignableTo_fuzzy_arrows() {
-    FunctionType top = TypeBuilder.function(
-        required: <DartType>[dynamicType], result: objectType);
-    FunctionType left = TypeBuilder.function(
-        required: <DartType>[objectType], result: objectType);
-    FunctionType right = TypeBuilder.function(
-        required: <DartType>[dynamicType], result: bottomType);
-    FunctionType bottom = TypeBuilder.function(
-        required: <DartType>[objectType], result: bottomType);
+    FunctionType top = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder
+        .function(required: <DartType>[objectType], result: bottomType);
 
     _checkCrossLattice(top, left, right, bottom);
   }
@@ -175,8 +178,8 @@
         required: <DartType>[],
         named: <String, DartType>{'x': intType},
         result: intType);
-    DartType rr = TypeBuilder.function(
-        required: <DartType>[intType, intType], result: intType);
+    DartType rr = TypeBuilder
+        .function(required: <DartType>[intType, intType], result: intType);
     DartType ro = TypeBuilder.function(
         required: <DartType>[intType],
         optional: <DartType>[intType],
@@ -237,8 +240,8 @@
         TypeBuilder.function(required: <DartType>[intType], result: objectType);
     FunctionType left =
         TypeBuilder.function(required: <DartType>[intType], result: intType);
-    FunctionType right = TypeBuilder.function(
-        required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
     FunctionType bottom =
         TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
@@ -339,8 +342,8 @@
     var tFrom = TypeBuilder.variable('TFrom');
     var tTo =
         TypeBuilder.variable('TTo', bound: iterableType.substitute4([tFrom]));
-    var cast = TypeBuilder.function(
-        types: [tFrom, tTo], required: [tFrom], result: tTo);
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [stringType]), [
       stringType,
       iterableType.substitute4([stringType])
@@ -375,8 +378,8 @@
     // <TFrom, TTo>(TFrom) -> TTo
     var tFrom = TypeBuilder.variable('TFrom');
     var tTo = TypeBuilder.variable('TTo');
-    var cast = TypeBuilder.function(
-        types: [tFrom, tTo], required: [tFrom], result: tTo);
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [intType]), [intType, dynamicType]);
   }
 
@@ -384,8 +387,8 @@
     // <TFrom, TTo extends TFrom>(TFrom) -> TTo
     var tFrom = TypeBuilder.variable('TFrom');
     var tTo = TypeBuilder.variable('TTo', bound: tFrom);
-    var cast = TypeBuilder.function(
-        types: [tFrom, tTo], required: [tFrom], result: tTo);
+    var cast = TypeBuilder
+        .function(types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [intType]), [intType, intType]);
   }
 
@@ -590,14 +593,14 @@
   }
 
   void test_fuzzy_arrows() {
-    FunctionType top = TypeBuilder.function(
-        required: <DartType>[dynamicType], result: objectType);
-    FunctionType left = TypeBuilder.function(
-        required: <DartType>[objectType], result: objectType);
-    FunctionType right = TypeBuilder.function(
-        required: <DartType>[dynamicType], result: bottomType);
-    FunctionType bottom = TypeBuilder.function(
-        required: <DartType>[objectType], result: bottomType);
+    FunctionType top = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder
+        .function(required: <DartType>[objectType], result: bottomType);
 
     _checkLattice(top, left, right, bottom);
   }
@@ -714,8 +717,8 @@
         required: <DartType>[],
         named: <String, DartType>{'x': intType},
         result: intType);
-    DartType rr = TypeBuilder.function(
-        required: <DartType>[intType, intType], result: intType);
+    DartType rr = TypeBuilder
+        .function(required: <DartType>[intType, intType], result: intType);
     DartType ro = TypeBuilder.function(
         required: <DartType>[intType],
         optional: <DartType>[intType],
@@ -782,8 +785,8 @@
         TypeBuilder.function(required: <DartType>[intType], result: objectType);
     FunctionType left =
         TypeBuilder.function(required: <DartType>[intType], result: intType);
-    FunctionType right = TypeBuilder.function(
-        required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder
+        .function(required: <DartType>[objectType], result: objectType);
     FunctionType bottom =
         TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 33f782b..18bde46 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -4,11 +4,11 @@
 
 library analyzer.test.src.context.abstract_context;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index ca87671..41feb593 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -6,13 +6,14 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -240,8 +241,9 @@
     Element declarationElement = declaration.variables.variables[0].element;
     TopLevelVariableDeclaration use =
         partUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element useElement = (use.variables.variables[0].initializer
-        as SimpleIdentifier).staticElement;
+    Element useElement =
+        (use.variables.variables[0].initializer as SimpleIdentifier)
+            .staticElement;
     expect((useElement as PropertyAccessorElement).variable,
         same(declarationElement));
     return pumpEventQueue().then((_) {
@@ -311,7 +313,6 @@
     expect(importedLibraries, hasLength(2));
     context.computeErrors(libA);
     context.computeErrors(libB);
-    expect(context.sourcesNeedingProcessing, hasLength(0));
     context.setContents(libB, null);
     _removeSource(libB);
     List<Source> sources = context.sourcesNeedingProcessing;
@@ -381,7 +382,6 @@
     context.computeLibraryElement(libA);
     context.computeErrors(libA);
     context.computeErrors(libB);
-    expect(context.sourcesNeedingProcessing, hasLength(0));
     ChangeSet changeSet = new ChangeSet();
     SourceContainer removedContainer =
         new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
@@ -604,12 +604,15 @@
       expect(unit, isNotNull);
       completed = true;
     });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
+    return pumpEventQueue()
+        .then((_) {
+          expect(completed, isFalse);
+          _performPendingAnalysisTasks();
+        })
+        .then((_) => pumpEventQueue())
+        .then((_) {
+          expect(completed, isTrue);
+        });
   }
 
   Future test_computeResolvedCompilationUnitAsync_afterDispose() {
@@ -698,12 +701,15 @@
       expect(unit, isNotNull);
       completed = true;
     });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
+    return pumpEventQueue()
+        .then((_) {
+          expect(completed, isFalse);
+          _performPendingAnalysisTasks();
+        })
+        .then((_) => pumpEventQueue())
+        .then((_) {
+          expect(completed, isTrue);
+        });
   }
 
   void test_configurationData() {
@@ -1937,11 +1943,8 @@
     addSource('/test.dart', 'main() {}');
     _analyzeAll_assertFinished();
     // verify
-    expect(libraryElementUris, contains('dart:core'));
     expect(libraryElementUris, contains('file:///test.dart'));
-    expect(parsedUnitUris, contains('dart:core'));
     expect(parsedUnitUris, contains('file:///test.dart'));
-    expect(resolvedUnitUris, contains('dart:core'));
     expect(resolvedUnitUris, contains('file:///test.dart'));
   }
 
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index f9ce626..5cf93dd 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -275,7 +275,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
similarity index 99%
rename from pkg/analyzer/test/generated/element_test.dart
rename to pkg/analyzer/test/src/dart/element/element_test.dart
index 9285b5f..bf01506 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -4,8 +4,11 @@
 
 library analyzer.test.generated.element_test;
 
+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/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/java_core.dart';
@@ -15,14 +18,14 @@
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:unittest/unittest.dart';
 
-import '../reflective_tests.dart';
-import '../utils.dart';
-import 'resolver_test.dart' show TestTypeProvider, AnalysisContextHelper;
-import 'test_support.dart';
+import '../../../generated/resolver_test.dart'
+    show TestTypeProvider, AnalysisContextHelper;
+import '../../../generated/test_support.dart';
+import '../../../reflective_tests.dart';
+import '../../../utils.dart';
 
 main() {
   initializeTestEnvironment();
-  runReflectiveTests(ElementKindTest);
   runReflectiveTests(FieldElementImplTest);
   runReflectiveTests(FunctionTypeImplTest);
   runReflectiveTests(InterfaceTypeImplTest);
@@ -281,8 +284,8 @@
   void test_isEnum() {
     String firstConst = "A";
     String secondConst = "B";
-    ClassElementImpl enumE = ElementFactory.enumElement(
-        new TestTypeProvider(), "E", [firstConst, secondConst]);
+    ClassElementImpl enumE = ElementFactory
+        .enumElement(new TestTypeProvider(), "E", [firstConst, secondConst]);
 
     // E is an enum
     expect(enumE.isEnum, true);
@@ -633,7 +636,8 @@
     expect(classB.lookUpInheritedConcreteMethod(methodName, library), isNull);
   }
 
-  void test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween() {
+  void
+      test_lookUpInheritedConcreteMethod_declaredAndInheritedWithAbstractBetween() {
     // class A {
     //   m() {}
     // }
@@ -1163,18 +1167,6 @@
 }
 
 @reflectiveTest
-class ElementKindTest extends EngineTestCase {
-  void test_of_nonNull() {
-    expect(ElementKind.of(ElementFactory.classElement2("A")),
-        same(ElementKind.CLASS));
-  }
-
-  void test_of_null() {
-    expect(ElementKind.of(null), same(ElementKind.ERROR));
-  }
-}
-
-@reflectiveTest
 class ElementLocationImplTest extends EngineTestCase {
   void test_create_encoding() {
     String encoding = "a;b;c";
@@ -1904,8 +1896,8 @@
     FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
     InterfaceTypeImpl argumentType = new InterfaceTypeImpl(
         new ClassElementImpl.forNode(AstFactory.identifier3("D")));
-    FunctionType result = functionType.substitute2(
-        <DartType>[argumentType], <DartType>[parameterType]);
+    FunctionType result = functionType
+        .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
     expect(result.returnType, argumentType);
     List<DartType> normalParameters = result.normalParameterTypes;
     expect(normalParameters, hasLength(1));
@@ -1941,8 +1933,8 @@
         new ClassElementImpl.forNode(AstFactory.identifier3("D")));
     TypeParameterTypeImpl parameterType = new TypeParameterTypeImpl(
         new TypeParameterElementImpl.forNode(AstFactory.identifier3("E")));
-    FunctionType result = functionType.substitute2(
-        <DartType>[argumentType], <DartType>[parameterType]);
+    FunctionType result = functionType
+        .substitute2(<DartType>[argumentType], <DartType>[parameterType]);
     expect(result.returnType, returnType);
     List<DartType> normalParameters = result.normalParameterTypes;
     expect(normalParameters, hasLength(1));
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
new file mode 100644
index 0000000..c401919
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -0,0 +1,18 @@
+// 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.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'element_test.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('element tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
new file mode 100644
index 0000000..f0c4598
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/test_all.dart
@@ -0,0 +1,18 @@
+// 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.test.generated.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'element/test_all.dart' as element;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('dart tests', () {
+    element.main();
+  });
+}
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index 4641b07..b08e293 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -251,7 +251,7 @@
       }
       if (filePath.startsWith("$libraryPath/")) {
         String pathInLibrary = filePath.substring(libraryPath.length + 1);
-        String path = '${library.shortName}/${pathInLibrary}';
+        String path = '${library.shortName}/$pathInLibrary';
         try {
           resource.File file = provider.getResource(uri.path);
           Uri dartUri = new Uri(scheme: 'dart', path: path);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
new file mode 100644
index 0000000..cffd7d9
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -0,0 +1,1040 @@
+// 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 test.src.serialization.elements_test;
+
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/builder.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ResynthTest);
+}
+
+@reflectiveTest
+class ResynthTest extends ResolverTestCase {
+  Set<Source> otherLibrarySources = new Set<Source>();
+
+  void addLibrary(String uri) {
+    otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri));
+  }
+
+  void addLibrarySource(String filePath, String contents) {
+    otherLibrarySources.add(addNamedSource(filePath, contents));
+  }
+
+  void checkLibrary(String text, {bool allowErrors: false}) {
+    Source source = addSource(text);
+    LibraryElementImpl original = resolve2(source);
+    LibraryElementImpl resynthesized =
+        resynthesizeLibrary(source, original, allowErrors);
+    checkLibraryElements(original, resynthesized);
+  }
+
+  void checkLibraryElements(
+      LibraryElementImpl original, LibraryElementImpl resynthesized) {
+    compareElements(resynthesized, original, '(library)');
+    expect(resynthesized.displayName, original.displayName);
+    expect(original.enclosingElement, isNull);
+    expect(resynthesized.enclosingElement, isNull);
+    compareCompilationUnitElements(resynthesized.definingCompilationUnit,
+        original.definingCompilationUnit);
+    expect(resynthesized.parts.length, original.parts.length);
+    for (int i = 0; i < resynthesized.parts.length; i++) {
+      compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]);
+    }
+    expect(resynthesized.imports.length, original.imports.length);
+    for (int i = 0; i < resynthesized.imports.length; i++) {
+      compareImportElements(resynthesized.imports[i], original.imports[i],
+          'import ${original.imports[i].name}');
+    }
+    expect(resynthesized.exports.length, original.exports.length);
+    for (int i = 0; i < resynthesized.exports.length; i++) {
+      compareExportElements(resynthesized.exports[i], original.exports[i],
+          'export ${original.exports[i].name}');
+    }
+    // TODO(paulberry): test entryPoint, exportNamespace, publicNamespace,
+    // and metadata.
+  }
+
+  void compareClassElements(
+      ClassElementImpl resynthesized, ClassElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.fields.length, original.fields.length,
+        reason: '$desc fields.length');
+    for (int i = 0; i < resynthesized.fields.length; i++) {
+      String name = original.fields[i].name;
+      compareFieldElements(resynthesized.getField(name), original.fields[i],
+          '$desc.field $name');
+    }
+    compareTypes(
+        resynthesized.supertype, original.supertype, '$desc supertype');
+    expect(resynthesized.interfaces.length, original.interfaces.length);
+    for (int i = 0; i < resynthesized.interfaces.length; i++) {
+      compareTypes(resynthesized.interfaces[i], original.interfaces[i],
+          '$desc interface ${original.interfaces[i].name}');
+    }
+    expect(resynthesized.mixins.length, original.mixins.length);
+    for (int i = 0; i < resynthesized.mixins.length; i++) {
+      compareTypes(resynthesized.mixins[i], original.mixins[i],
+          '$desc mixin ${original.mixins[i].name}');
+    }
+    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}');
+    }
+    expect(resynthesized.constructors.length, original.constructors.length,
+        reason: '$desc constructors.length');
+    for (int i = 0; i < resynthesized.constructors.length; i++) {
+      compareConstructorElements(
+          resynthesized.constructors[i],
+          original.constructors[i],
+          '$desc constructor ${original.constructors[i].name}');
+    }
+    expect(resynthesized.accessors.length, original.accessors.length);
+    for (int i = 0; i < resynthesized.accessors.length; i++) {
+      String name = original.accessors[i].name;
+      if (name.endsWith('=')) {
+        comparePropertyAccessorElements(resynthesized.getSetter(name),
+            original.accessors[i], '$desc.${original.accessors[i].name}=');
+      } else {
+        comparePropertyAccessorElements(resynthesized.getGetter(name),
+            original.accessors[i], '$desc.${original.accessors[i].name}');
+      }
+    }
+    expect(resynthesized.methods.length, original.methods.length);
+    for (int i = 0; i < resynthesized.methods.length; i++) {
+      compareMethodElements(resynthesized.methods[i], original.methods[i],
+          '$desc.${original.methods[i].name}');
+    }
+    compareTypes(resynthesized.type, original.type, desc);
+  }
+
+  void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
+      CompilationUnitElementImpl original) {
+    compareUriReferencedElements(resynthesized, original, '(compilation unit)');
+    expect(resynthesized.source, original.source);
+    expect(resynthesized.librarySource, original.librarySource);
+    expect(resynthesized.types.length, original.types.length);
+    for (int i = 0; i < resynthesized.types.length; i++) {
+      compareClassElements(
+          resynthesized.types[i], original.types[i], original.types[i].name);
+    }
+    expect(resynthesized.topLevelVariables.length,
+        original.topLevelVariables.length);
+    for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
+      compareTopLevelVariableElements(resynthesized.topLevelVariables[i],
+          original.topLevelVariables[i], original.topLevelVariables[i].name);
+    }
+    expect(resynthesized.functions.length, original.functions.length);
+    for (int i = 0; i < resynthesized.functions.length; i++) {
+      compareFunctionElements(resynthesized.functions[i], original.functions[i],
+          original.functions[i].name);
+    }
+    expect(resynthesized.functionTypeAliases.length,
+        original.functionTypeAliases.length);
+    for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) {
+      compareFunctionTypeAliasElements(
+          resynthesized.functionTypeAliases[i],
+          original.functionTypeAliases[i],
+          original.functionTypeAliases[i].name);
+    }
+    expect(resynthesized.enums.length, original.enums.length);
+    for (int i = 0; i < resynthesized.enums.length; i++) {
+      compareClassElements(
+          resynthesized.enums[i], original.enums[i], original.enums[i].name);
+    }
+    expect(resynthesized.accessors.length, original.accessors.length);
+    for (int i = 0; i < resynthesized.accessors.length; i++) {
+      comparePropertyAccessorElements(resynthesized.accessors[i],
+          original.accessors[i], original.accessors[i].name);
+    }
+    // TODO(paulberry): test metadata and offsetToElementMap.
+  }
+
+  void compareConstructorElements(ConstructorElementImpl resynthesized,
+      ConstructorElementImpl original, String desc) {
+    compareExecutableElements(resynthesized, original, desc);
+    // TODO(paulberry): test redirectedConstructor and constantInitializers
+  }
+
+  void compareElements(
+      ElementImpl resynthesized, ElementImpl original, String desc) {
+    expect(resynthesized, isNotNull);
+    expect(resynthesized.kind, original.kind);
+    expect(resynthesized.location, original.location, reason: desc);
+    expect(resynthesized.name, original.name);
+    for (Modifier modifier in Modifier.values) {
+      if (modifier == Modifier.MIXIN) {
+        // Skipping for now.  TODO(paulberry): fix.
+        continue;
+      }
+      bool got = resynthesized.hasModifier(modifier);
+      bool want = original.hasModifier(modifier);
+      expect(got, want,
+          reason: 'Mismatch in $desc.$modifier: got $got, want $want');
+    }
+  }
+
+  void compareExecutableElements(ExecutableElementImpl resynthesized,
+      ExecutableElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    compareTypes(
+        resynthesized.returnType, original.returnType, '$desc return type');
+    compareTypes(resynthesized.type, original.type, desc);
+  }
+
+  void compareExportElements(ExportElementImpl resynthesized,
+      ExportElementImpl original, String desc) {
+    compareUriReferencedElements(resynthesized, original, desc);
+    expect(resynthesized.exportedLibrary.location,
+        original.exportedLibrary.location);
+    expect(resynthesized.combinators.length, original.combinators.length);
+    for (int i = 0; i < resynthesized.combinators.length; i++) {
+      compareNamespaceCombinators(
+          resynthesized.combinators[i], original.combinators[i]);
+    }
+  }
+
+  void compareFieldElements(
+      FieldElementImpl resynthesized, FieldElementImpl original, String desc) {
+    comparePropertyInducingElements(resynthesized, original, desc);
+    // TODO(paulberry): test evaluationResult
+  }
+
+  void compareFunctionElements(FunctionElementImpl resynthesized,
+      FunctionElementImpl original, String desc) {
+    compareExecutableElements(resynthesized, original, desc);
+  }
+
+  void compareFunctionTypeAliasElements(
+      FunctionTypeAliasElementImpl resynthesized,
+      FunctionTypeAliasElementImpl original,
+      String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    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 compareImportElements(ImportElementImpl resynthesized,
+      ImportElementImpl original, String desc) {
+    compareUriReferencedElements(resynthesized, original, desc);
+    expect(resynthesized.importedLibrary.location,
+        original.importedLibrary.location);
+    if (original.prefix == null) {
+      expect(resynthesized.prefix, isNull);
+    } else {
+      comparePrefixElements(
+          resynthesized.prefix, original.prefix, original.prefix.name);
+    }
+    expect(resynthesized.combinators.length, original.combinators.length);
+    for (int i = 0; i < resynthesized.combinators.length; i++) {
+      compareNamespaceCombinators(
+          resynthesized.combinators[i], original.combinators[i]);
+    }
+  }
+
+  void compareMethodElements(MethodElementImpl resynthesized,
+      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);
+  }
+
+  void compareNamespaceCombinators(
+      NamespaceCombinator resynthesized, NamespaceCombinator original) {
+    if (original is ShowElementCombinatorImpl &&
+        resynthesized is ShowElementCombinatorImpl) {
+      expect(resynthesized.shownNames, original.shownNames);
+    } else if (original is HideElementCombinatorImpl &&
+        resynthesized is HideElementCombinatorImpl) {
+      expect(resynthesized.hiddenNames, original.hiddenNames);
+    } else if (resynthesized.runtimeType != original.runtimeType) {
+      fail(
+          'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
+    } else {
+      fail('Unimplemented comparison for ${original.runtimeType}');
+    }
+  }
+
+  void compareParameterElements(ParameterElementImpl resynthesized,
+      ParameterElementImpl original, String desc) {
+    compareVariableElements(resynthesized, original, desc);
+    expect(resynthesized.parameters.length, original.parameters.length);
+    for (int i = 0; i < resynthesized.parameters.length; i++) {
+      compareParameterElements(
+          resynthesized.parameters[i],
+          original.parameters[i],
+          '$desc parameter ${original.parameters[i].name}');
+    }
+    expect(resynthesized.parameterKind, original.parameterKind);
+  }
+
+  void comparePrefixElements(PrefixElementImpl resynthesized,
+      PrefixElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    // TODO(paulberry): test _importedLibraries.
+  }
+
+  void comparePropertyAccessorElements(
+      PropertyAccessorElementImpl resynthesized,
+      PropertyAccessorElementImpl original,
+      String desc) {
+    // TODO(paulberry): do I need to worry about
+    // MultiplyInheritedPropertyAccessorElementImpl?
+    compareExecutableElements(resynthesized, original, desc);
+    expect(resynthesized.variable, isNotNull);
+    expect(resynthesized.variable.location, original.variable.location);
+  }
+
+  void comparePropertyInducingElements(
+      PropertyInducingElementImpl resynthesized,
+      PropertyInducingElementImpl original,
+      String desc) {
+    compareVariableElements(resynthesized, original, desc);
+    if (original.getter == null) {
+      expect(resynthesized.getter, isNull);
+    } else {
+      expect(resynthesized.getter, isNotNull);
+      expect(resynthesized.getter.location, original.getter.location);
+    }
+    if (original.setter == null) {
+      expect(resynthesized.setter, isNull);
+    } else {
+      expect(resynthesized.setter, isNotNull);
+      expect(resynthesized.setter.location, original.setter.location);
+    }
+  }
+
+  void compareTopLevelVariableElements(
+      TopLevelVariableElementImpl resynthesized,
+      TopLevelVariableElementImpl original,
+      String desc) {
+    comparePropertyInducingElements(resynthesized, original, desc);
+    // TODO(paulberry): test evaluationResult
+  }
+
+  void compareTypeImpls(TypeImpl resynthesized, TypeImpl original) {
+    expect(resynthesized.element.location, original.element.location);
+    expect(resynthesized.name, original.name);
+  }
+
+  void compareTypeParameterElements(TypeParameterElementImpl resynthesized,
+      TypeParameterElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    compareTypes(resynthesized.type, original.type, desc);
+    compareTypes(resynthesized.bound, original.bound, '$desc bound');
+  }
+
+  void compareTypes(DartType resynthesized, DartType original, String desc) {
+    if (original == null) {
+      expect(resynthesized, isNull, reason: desc);
+    } else if (resynthesized is InterfaceTypeImpl &&
+        original is InterfaceTypeImpl) {
+      compareTypeImpls(resynthesized, original);
+      expect(resynthesized.typeArguments.length, original.typeArguments.length);
+      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
+        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
+            '$desc type argument ${original.typeArguments[i].name}');
+      }
+    } else if (resynthesized is TypeParameterTypeImpl &&
+        original is TypeParameterTypeImpl) {
+      compareTypeImpls(resynthesized, original);
+    } else if (resynthesized is DynamicTypeImpl &&
+        original is DynamicTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized is UndefinedTypeImpl &&
+        original is UndefinedTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized is FunctionTypeImpl &&
+        original is FunctionTypeImpl) {
+      compareTypeImpls(resynthesized, original);
+      if (original.element.isSynthetic &&
+          original.element is FunctionTypeAliasElementImpl &&
+          resynthesized.element is FunctionTypeAliasElementImpl) {
+        compareFunctionTypeAliasElements(
+            resynthesized.element, original.element, desc);
+      }
+      for (int i = 0; i < resynthesized.typeArguments.length; i++) {
+        compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
+            '$desc type argument ${original.typeArguments[i].name}');
+      }
+    } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) {
+      expect(resynthesized, same(original));
+    } else if (resynthesized.runtimeType != original.runtimeType) {
+      fail(
+          'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
+    } else {
+      fail('Unimplemented comparison for ${original.runtimeType}');
+    }
+  }
+
+  void compareUriReferencedElements(UriReferencedElementImpl resynthesized,
+      UriReferencedElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    expect(resynthesized.uri, original.uri);
+  }
+
+  void compareVariableElements(VariableElementImpl resynthesized,
+      VariableElementImpl original, String desc) {
+    compareElements(resynthesized, original, desc);
+    compareTypes(resynthesized.type, original.type, desc);
+    // TODO(paulberry): test initializer
+  }
+
+  LibraryElementImpl resynthesizeLibrary(
+      Source source, LibraryElementImpl original, bool allowErrors) {
+    if (!allowErrors) {
+      assertNoErrors(source);
+    }
+    String uri = source.uri.toString();
+    addLibrary('dart:core');
+    return resynthesizeLibraryElement(uri, original);
+  }
+
+  LibraryElementImpl resynthesizeLibraryElement(
+      String uri, LibraryElementImpl original) {
+    Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
+    PrelinkedLibrary getPrelinkedSummaryFor(LibraryElement lib) {
+      BuilderContext ctx = new BuilderContext();
+      LibrarySerializationResult serialized =
+          serializeLibrary(ctx, lib, typeProvider);
+      for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
+        unlinkedSummaries[serialized.unitUris[i]] =
+            new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
+      }
+      return new PrelinkedLibrary.fromBuffer(serialized.prelinked.toBuffer());
+    }
+    Map<String, PrelinkedLibrary> prelinkedSummaries =
+        <String, PrelinkedLibrary>{uri: getPrelinkedSummaryFor(original)};
+    for (Source source in otherLibrarySources) {
+      LibraryElement original = resolve2(source);
+      String uri = source.uri.toString();
+      prelinkedSummaries[uri] = getPrelinkedSummaryFor(original);
+    }
+    PrelinkedLibrary getPrelinkedSummary(String uri) {
+      PrelinkedLibrary serializedLibrary = prelinkedSummaries[uri];
+      if (serializedLibrary == null) {
+        fail('Unexpectedly tried to get prelinked summary for $uri');
+      }
+      return serializedLibrary;
+    }
+    UnlinkedUnit getUnlinkedSummary(String uri) {
+      UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
+      if (serializedUnit == null) {
+        fail('Unexpectedly tried to get unlinked summary for $uri');
+      }
+      return serializedUnit;
+    }
+    SummaryResynthesizer resynthesizer = new SummaryResynthesizer(
+        analysisContext,
+        getPrelinkedSummary,
+        getUnlinkedSummary,
+        analysisContext.sourceFactory);
+    LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 1);
+    return resynthesized;
+  }
+
+  test_class_alias() {
+    checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
+  }
+
+  test_class_alias_with_forwarding_constructors() {
+    addLibrarySource(
+        '/a.dart',
+        '''
+class Base {
+  Base._priv();
+  Base();
+  Base.noArgs();
+  Base.requiredArg(x);
+  Base.positionalArg([x]);
+  Base.namedArg({x});
+  factory Base.fact() => null;
+  factory Base.fact2() = Base.noArgs;
+}
+''');
+    checkLibrary('''
+import "a.dart";
+class M {}
+class MixinApp = Base with M;
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution() {
+    checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp = Base with M;
+''');
+  }
+
+  test_class_alias_with_forwarding_constructors_type_substitution_complex() {
+    checkLibrary('''
+class Base<T> {
+  Base.ctor(T t, List<T> l);
+}
+class M {}
+class MixinApp<U> = Base<List<U>> with M;
+''');
+  }
+
+  test_class_alias_with_mixin_members() {
+    checkLibrary('''
+class C = D with E;
+class D {}
+class E {
+  int get a => null;
+  void set b(int i) {}
+  void f() {}
+  int x;
+}''');
+  }
+
+  test_class_constructor_const() {
+    checkLibrary('class C { const C(); }');
+  }
+
+  test_class_constructor_const_external() {
+    checkLibrary('class C { external const C(); }');
+  }
+
+  test_class_constructor_explicit_named() {
+    checkLibrary('class C { C.foo(); }');
+  }
+
+  test_class_constructor_explicit_type_params() {
+    checkLibrary('class C<T, U> { C(); }');
+  }
+
+  test_class_constructor_explicit_unnamed() {
+    checkLibrary('class C { C(); }');
+  }
+
+  test_class_constructor_external() {
+    checkLibrary('class C { external C(); }');
+  }
+
+  test_class_constructor_factory() {
+    checkLibrary('class C { factory C() => null; }');
+  }
+
+  test_class_constructor_implicit() {
+    checkLibrary('class C {}');
+  }
+
+  test_class_constructor_implicit_type_params() {
+    checkLibrary('class C<T, U> {}');
+  }
+
+  test_class_constructor_params() {
+    checkLibrary('class C { C(x, y); }');
+  }
+
+  test_class_constructors() {
+    checkLibrary('class C { C.foo(); C.bar(); }');
+  }
+
+  test_class_field_const() {
+    checkLibrary('class C { static const int i = 0; }');
+  }
+
+  test_class_field_static() {
+    checkLibrary('class C { static int i; }');
+  }
+
+  test_class_fields() {
+    checkLibrary('class C { int i; int j; }');
+  }
+
+  test_class_getter_external() {
+    checkLibrary('class C { external int get x; }');
+  }
+
+  test_class_getter_static() {
+    checkLibrary('class C { static int get x => null; }');
+  }
+
+  test_class_getters() {
+    checkLibrary('class C { int get x => null; get y => null; }');
+  }
+
+  test_class_interfaces() {
+    checkLibrary('class C implements D, E {} class D {} class E {}');
+  }
+
+  test_class_method_external() {
+    checkLibrary('class C { external f(); }');
+  }
+
+  test_class_method_params() {
+    checkLibrary('class C { f(x, y) {} }');
+  }
+
+  test_class_method_static() {
+    checkLibrary('class C { static f() {} }');
+  }
+
+  test_class_methods() {
+    checkLibrary('class C { f() {} g() {} }');
+  }
+
+  test_class_mixins() {
+    checkLibrary('class C extends Object with D, E {} class D {} class E {}');
+  }
+
+  test_class_setter_external() {
+    checkLibrary('class C { external void set x(int value); }');
+  }
+
+  test_class_setter_static() {
+    checkLibrary('class C { static void set x(int value) {} }');
+  }
+
+  test_class_setters() {
+    checkLibrary('class C { void set x(int value) {} set y(value) {} }');
+  }
+
+  test_class_supertype() {
+    checkLibrary('class C extends D {} class D {}');
+  }
+
+  test_class_type_parameters() {
+    checkLibrary('class C<T, U> {}');
+  }
+
+  test_class_type_parameters_bound() {
+    checkLibrary('class C<T extends Object, U extends D> {} class D {}');
+  }
+
+  test_class_type_parameters_f_bound_complex() {
+    checkLibrary('class C<T extends List<U>, U> {}');
+  }
+
+  test_class_type_parameters_f_bound_simple() {
+    checkLibrary('class C<T extends U, U> {}');
+  }
+
+  test_classes() {
+    checkLibrary('class C {} class D {}');
+  }
+
+  test_core() {
+    String uri = 'dart:core';
+    LibraryElementImpl original =
+        resolve2(analysisContext2.sourceFactory.forUri(uri));
+    LibraryElementImpl resynthesized =
+        resynthesizeLibraryElement(uri, original);
+    checkLibraryElements(original, resynthesized);
+  }
+
+  test_enum_values() {
+    checkLibrary('enum E { v1, v2 }');
+  }
+
+  test_enums() {
+    checkLibrary('enum E1 { v1 } enum E2 { v2 }');
+  }
+
+  test_export_hide() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" hide Stream, Future;');
+  }
+
+  test_export_multiple_combinators() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" hide Stream show Future;');
+  }
+
+  test_export_show() {
+    addLibrary('dart:async');
+    checkLibrary('export "dart:async" show Future, Stream;');
+  }
+
+  test_exports() {
+    addLibrarySource('/a.dart', 'library a;');
+    addLibrarySource('/b.dart', 'library b;');
+    checkLibrary('export "a.dart"; export "b.dart";');
+  }
+
+  test_function_external() {
+    checkLibrary('external f();');
+  }
+
+  test_function_parameter_kind_named() {
+    // TODO(paulberry): also test default value.
+    checkLibrary('f({x}) {}');
+  }
+
+  test_function_parameter_kind_positional() {
+    // TODO(paulberry): also test default value.
+    checkLibrary('f([x]) {}');
+  }
+
+  test_function_parameter_kind_required() {
+    checkLibrary('f(x) {}');
+  }
+
+  test_function_parameter_parameters() {
+    checkLibrary('f(g(x, y)) {}');
+  }
+
+  test_function_parameter_return_type() {
+    checkLibrary('f(int g()) {}');
+  }
+
+  test_function_parameter_return_type_void() {
+    checkLibrary('f(void g()) {}');
+  }
+
+  test_function_parameter_type() {
+    checkLibrary('f(int i) {}');
+  }
+
+  test_function_parameters() {
+    checkLibrary('f(x, y) {}');
+  }
+
+  test_function_return_type() {
+    checkLibrary('int f() => null;');
+  }
+
+  test_function_return_type_implicit() {
+    checkLibrary('f() => null;');
+  }
+
+  test_function_return_type_void() {
+    checkLibrary('void f() {}');
+  }
+
+  test_functions() {
+    checkLibrary('f() {} g() {}');
+  }
+
+  test_getter_external() {
+    checkLibrary('external int get x;');
+  }
+
+  test_getters() {
+    checkLibrary('int get x => null; get y => null;');
+  }
+
+  test_import_hide() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
+  }
+
+  test_import_multiple_combinators() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" hide Stream show Future; Future f;');
+  }
+
+  test_import_prefixed() {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    checkLibrary('import "a.dart" as a; a.C c;');
+  }
+
+  test_import_show() {
+    addLibrary('dart:async');
+    checkLibrary('import "dart:async" show Future, Stream; Future f;');
+  }
+
+  test_imports() {
+    addLibrarySource('/a.dart', 'library a; class C {}');
+    addLibrarySource('/b.dart', 'library b; class D {}');
+    checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
+  }
+
+  test_library() {
+    checkLibrary('');
+  }
+
+  test_library_named() {
+    checkLibrary('library foo.bar;');
+  }
+
+  test_method_parameter_parameters() {
+    checkLibrary('class C { f(g(x, y)) {} }');
+  }
+
+  test_method_parameter_return_type() {
+    checkLibrary('class C { f(int g()) {} }');
+  }
+
+  test_method_parameter_return_type_void() {
+    checkLibrary('class C { f(void g()) {} }');
+  }
+
+  test_operator() {
+    checkLibrary('class C { C operator+(C other) => null; }');
+  }
+
+  test_operator_equal() {
+    checkLibrary('class C { bool operator==(C other) => false; }');
+  }
+
+  test_operator_external() {
+    checkLibrary('class C { external C operator+(C other); }');
+  }
+
+  test_operator_greater_equal() {
+    checkLibrary('class C { bool operator>=(C other) => false; }');
+  }
+
+  test_operator_index() {
+    checkLibrary('class C { bool operator[](int i) => null; }');
+  }
+
+  test_operator_index_set() {
+    checkLibrary('class C { void operator[]=(int i, bool v) {} }');
+  }
+
+  test_operator_less_equal() {
+    checkLibrary('class C { bool operator<=(C other) => false; }');
+  }
+
+  test_parts() {
+    addNamedSource('/a.dart', 'part of my.lib;');
+    addNamedSource('/b.dart', 'part of my.lib;');
+    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+  }
+
+  test_setter_external() {
+    checkLibrary('external void set x(int value);');
+  }
+
+  test_setters() {
+    checkLibrary('void set x(int value) {} set y(value) {}');
+  }
+
+  test_type_arguments_explicit() {
+    checkLibrary('Map<String, int> m;');
+  }
+
+  test_type_arguments_implicit() {
+    checkLibrary('Map m;');
+  }
+
+  test_type_dynamic() {
+    checkLibrary('dynamic d;');
+  }
+
+  test_type_reference_lib_to_lib() {
+    checkLibrary('class C {} enum E { v } typedef F(); C c; E e; F f;');
+  }
+
+  test_type_reference_lib_to_part() {
+    addNamedSource(
+        '/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('library l; part "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_part_to_lib() {
+    addNamedSource('/a.dart', 'part of l; C c; E e; F f;');
+    checkLibrary(
+        'library l; part "a.dart"; class C {} enum E { v } typedef F();');
+  }
+
+  test_type_reference_part_to_other_part() {
+    addNamedSource(
+        '/a.dart', 'part of l; class C {} enum E { v } typedef F();');
+    addNamedSource('/b.dart', 'part of l; C c; E e; F f;');
+    checkLibrary('library l; part "a.dart"; part "b.dart";');
+  }
+
+  test_type_reference_part_to_part() {
+    addNamedSource('/a.dart',
+        'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
+    checkLibrary('library l; part "a.dart";');
+  }
+
+  test_type_reference_to_class() {
+    checkLibrary('class C {} C c;');
+  }
+
+  test_type_reference_to_class_with_type_arguments() {
+    checkLibrary('class C<T, U> {} C<int, String> c;');
+  }
+
+  test_type_reference_to_class_with_type_arguments_implicit() {
+    checkLibrary('class C<T, U> {} C c;');
+  }
+
+  test_type_reference_to_enum() {
+    checkLibrary('enum E { v } E e;');
+  }
+
+  test_type_reference_to_import() {
+    addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export() {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_export() {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'export "c.dart";');
+    addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_export_in_subdirs() {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
+    addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_export_in_subdirs() {
+    addLibrarySource('/a/a.dart', 'export "b/b.dart";');
+    addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_part() {
+    addLibrarySource('/a.dart', 'library l; part "b.dart";');
+    addNamedSource(
+        '/b.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_part_in_subdir() {
+    addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
+    addNamedSource(
+        '/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
+    checkLibrary('import "a/b.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_import_relative() {
+    addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
+    checkLibrary('import "a.dart"; C c; E e; F f;');
+  }
+
+  test_type_reference_to_typedef() {
+    checkLibrary('typedef F(); F f;');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments() {
+    checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
+  }
+
+  test_type_reference_to_typedef_with_type_arguments_implicit() {
+    checkLibrary('typedef U F<T, U>(T t); F f;');
+  }
+
+  test_type_unresolved() {
+    checkLibrary('C c;', allowErrors: true);
+  }
+
+  test_type_unresolved_prefixed() {
+    checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true);
+  }
+
+  test_typedef_parameter_parameters() {
+    checkLibrary('typedef F(g(x, y));');
+  }
+
+  test_typedef_parameter_return_type() {
+    checkLibrary('typedef F(int g());');
+  }
+
+  test_typedef_parameter_type() {
+    checkLibrary('typedef F(int i);');
+  }
+
+  test_typedef_parameter_type_generic() {
+    checkLibrary('typedef F<T>(T t);');
+  }
+
+  test_typedef_parameters() {
+    checkLibrary('typedef F(x, y);');
+  }
+
+  test_typedef_return_type() {
+    checkLibrary('typedef int F();');
+  }
+
+  test_typedef_return_type_generic() {
+    checkLibrary('typedef T F<T>();');
+  }
+
+  test_typedef_return_type_implicit() {
+    checkLibrary('typedef F();');
+  }
+
+  test_typedef_return_type_void() {
+    checkLibrary('typedef void F();');
+  }
+
+  test_typedef_type_parameters() {
+    checkLibrary('typedef U F<T, U>(T t);');
+  }
+
+  test_typedef_type_parameters_bound() {
+    checkLibrary('typedef U F<T extends Object, U extends D>(T t); class D {}');
+  }
+
+  test_typedef_type_parameters_f_bound_complex() {
+    checkLibrary('typedef U F<T extends List<U>, U>(T t);');
+  }
+
+  test_typedef_type_parameters_f_bound_simple() {
+    checkLibrary('typedef U F<T extends U, U>(T t);');
+  }
+
+  test_typedefs() {
+    checkLibrary('f() {} g() {}');
+  }
+
+  test_variable_const() {
+    checkLibrary('const int i = 0;');
+  }
+
+  test_variables() {
+    checkLibrary('int i; int j;');
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
index e6107e4..a658d2b 100644
--- a/pkg/analyzer/test/src/summary/summary_test.dart
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -4,9 +4,7 @@
 
 library analyzer.test.src.summary.summary_test;
 
-import 'dart:typed_data';
-
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -47,10 +45,15 @@
    */
   void serializeLibraryElement(LibraryElement library) {
     BuilderContext builderContext = new BuilderContext();
-    PrelinkedLibraryBuilder serializedLib = summarize_elements.serializeLibrary(
-        builderContext, library, typeProvider);
-    List<int> encodedLib = serializedLib.toBuffer();
-    lib = new PrelinkedLibrary.fromBuffer(encodedLib);
+    summarize_elements.LibrarySerializationResult serializedLib =
+        summarize_elements.serializeLibrary(
+            builderContext, library, typeProvider);
+    prelinked =
+        new PrelinkedLibrary.fromBuffer(serializedLib.prelinked.toBuffer());
+    unlinkedUnits = serializedLib.unlinkedUnits
+        .map((UnlinkedUnitBuilder b) =>
+            new UnlinkedUnit.fromBuffer(b.toBuffer()))
+        .toList();
   }
 
   @override
@@ -61,8 +64,13 @@
       assertNoErrors(source);
     }
     serializeLibraryElement(library);
-    expect(unlinked.imports.length, lib.importDependencies.length);
-    expect(unlinked.references.length, lib.references.length);
+    expect(
+        unlinkedUnits[0].imports.length, prelinked.importDependencies.length);
+    expect(prelinked.units.length, unlinkedUnits.length);
+    for (int i = 0; i < prelinked.units.length; i++) {
+      expect(unlinkedUnits[i].references.length,
+          prelinked.units[i].references.length);
+    }
   }
 
   @override
@@ -76,6 +84,7 @@
   test_class_no_superclass() {
     UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
     expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isTrue);
   }
 }
 
@@ -87,9 +96,16 @@
  */
 abstract class SummaryTest {
   /**
-   * The result of serializing and then deserializing the library under test.
+   * Prelinked summary that results from serializing and then deserializing the
+   * library under test.
    */
-  PrelinkedLibrary lib;
+  PrelinkedLibrary prelinked;
+
+  /**
+   * Unlinked compilation unit summaries that result from serializing and
+   * deserializing the library under test.
+   */
+  List<UnlinkedUnit> unlinkedUnits;
 
   /**
    * `true` if the summary was created directly from the AST (and hence
@@ -100,9 +116,9 @@
   bool get checkAstDerivedData;
 
   /**
-   * Get access to the "unlinked" section of the summary.
+   * Get access to the prelinked defining compilation unit.
    */
-  UnlinkedLibrary get unlinked => lib.unlinked;
+  PrelinkedUnit get definingUnit => prelinked.units[0];
 
   /**
    * Convert [path] to a suitably formatted absolute path URI for the current
@@ -140,7 +156,7 @@
       relativeUri = absoluteUri;
     }
     expect(dependency, new isInstanceOf<int>());
-    expect(lib.dependencies[dependency].uri, relativeUri);
+    expect(prelinked.dependencies[dependency].uri, relativeUri);
   }
 
   /**
@@ -161,7 +177,7 @@
       // TODO(paulberry): fix this.
       relativeUri = absoluteUri;
     }
-    for (PrelinkedDependency dep in lib.dependencies) {
+    for (PrelinkedDependency dep in prelinked.dependencies) {
       if (dep.uri == relativeUri) {
         return;
       }
@@ -180,7 +196,7 @@
       // TODO(paulberry): fix this.
       relativeUri = absoluteUri;
     }
-    for (PrelinkedDependency dep in lib.dependencies) {
+    for (PrelinkedDependency dep in prelinked.dependencies) {
       if (dep.uri == relativeUri) {
         fail('Unexpected dependency found: $relativeUri');
       }
@@ -199,24 +215,53 @@
   }
 
   /**
+   * Verify that [prefixReference] is a valid reference to a prefix having the
+   * given [name].
+   */
+  void checkPrefix(int prefixReference, String name) {
+    expect(prefixReference, isNot(0));
+    expect(unlinkedUnits[0].references[prefixReference].prefixReference, 0);
+    expect(unlinkedUnits[0].references[prefixReference].name, name);
+    expect(definingUnit.references[prefixReference].dependency, 0);
+    expect(definingUnit.references[prefixReference].kind,
+        PrelinkedReferenceKind.prefix);
+    expect(definingUnit.references[prefixReference].unit, 0);
+  }
+
+  /**
    * 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.
+   * object referenced.  [prelinkedSourceUnit] 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.
    */
   void checkTypeRef(UnlinkedTypeRef typeRef, String absoluteUri,
       String relativeUri, String expectedName,
       {String expectedPrefix,
       bool allowTypeParameters: false,
       PrelinkedReferenceKind expectedKind: PrelinkedReferenceKind.classOrEnum,
-      int expectedUnit: 0}) {
+      int expectedTargetUnit: 0,
+      PrelinkedUnit prelinkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit}) {
+    prelinkedSourceUnit ??= definingUnit;
+    unlinkedSourceUnit ??= unlinkedUnits[0];
     expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
     expect(typeRef.paramReference, 0);
     int index = typeRef.reference;
-    UnlinkedReference reference = unlinked.references[index];
-    PrelinkedReference referenceResolution = lib.references[index];
+    UnlinkedReference reference = unlinkedSourceUnit.references[index];
+    PrelinkedReference referenceResolution =
+        prelinkedSourceUnit.references[index];
+    if (index == 0) {
+      // Index 0 is reserved for "dynamic".
+      expect(reference.name, isEmpty);
+      expect(reference.prefixReference, 0);
+    }
     if (absoluteUri == null) {
       expect(referenceResolution.dependency, 0);
     } else {
@@ -232,15 +277,13 @@
     }
     if (checkAstDerivedData) {
       if (expectedPrefix == null) {
-        expect(reference.prefix, 0);
-        expect(unlinked.prefixes[reference.prefix].name, isEmpty);
+        expect(reference.prefixReference, 0);
       } else {
-        expect(reference.prefix, isNot(0));
-        expect(unlinked.prefixes[reference.prefix].name, expectedPrefix);
+        checkPrefix(reference.prefixReference, expectedPrefix);
       }
     }
     expect(referenceResolution.kind, expectedKind);
-    expect(referenceResolution.unit, expectedUnit);
+    expect(referenceResolution.unit, expectedTargetUnit);
   }
 
   /**
@@ -263,17 +306,21 @@
     // dependency tracking.
     serializeLibraryText('import "foo.dart";', allowErrors: true);
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    checkDependency(lib.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(
+        prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
   }
 
   /**
    * Find the class with the given [className] in the summary, and return its
-   * [UnlinkedClass] data structure.
+   * [UnlinkedClass] data structure.  If [unit] is not given, the class is
+   * looked for in the defining compilation unit.
    */
-  UnlinkedClass findClass(String className, {bool failIfAbsent: false}) {
+  UnlinkedClass findClass(String className,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
     UnlinkedClass result;
-    for (UnlinkedClass cls in unlinked.classes) {
+    for (UnlinkedClass cls in unit.classes) {
       if (cls.name == className) {
         if (result != null) {
           fail('Duplicate class $className');
@@ -289,11 +336,14 @@
 
   /**
    * Find the enum with the given [enumName] in the summary, and return its
-   * [UnlinkedEnum] data structure.
+   * [UnlinkedEnum] data structure.  If [unit] is not given, the enum is looked
+   * for in the defining compilation unit.
    */
-  UnlinkedEnum findEnum(String enumName, {bool failIfAbsent: false}) {
+  UnlinkedEnum findEnum(String enumName,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
     UnlinkedEnum result;
-    for (UnlinkedEnum e in unlinked.enums) {
+    for (UnlinkedEnum e in unit.enums) {
       if (e.name == enumName) {
         if (result != null) {
           fail('Duplicate enum $enumName');
@@ -309,16 +359,13 @@
 
   /**
    * Find the executable with the given [executableName] in the summary, and
-   * return its [UnlinkedExecutable] data structure.
+   * return its [UnlinkedExecutable] data structure.  If [executables] is not
+   * given, then the executable is searched for in the defining compilation
+   * unit.
    */
   UnlinkedExecutable findExecutable(String executableName,
-      {UnlinkedClass cls, bool failIfAbsent: false}) {
-    List<UnlinkedExecutable> executables;
-    if (cls == null) {
-      executables = unlinked.executables;
-    } else {
-      executables = cls.executables;
-    }
+      {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
+    executables ??= unlinkedUnits[0].executables;
     UnlinkedExecutable result;
     for (UnlinkedExecutable executable in executables) {
       if (executable.name == executableName) {
@@ -336,11 +383,14 @@
 
   /**
    * Find the typedef with the given [typedefName] in the summary, and return
-   * its [UnlinkedTypedef] data structure.
+   * its [UnlinkedTypedef] data structure.  If [unit] is not given, the typedef
+   * is looked for in the defining compilation unit.
    */
-  UnlinkedTypedef findTypedef(String typedefName, {bool failIfAbsent: false}) {
+  UnlinkedTypedef findTypedef(String typedefName,
+      {bool failIfAbsent: false, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
     UnlinkedTypedef result;
-    for (UnlinkedTypedef type in unlinked.typedefs) {
+    for (UnlinkedTypedef type in unit.typedefs) {
       if (type.name == typedefName) {
         if (result != null) {
           fail('Duplicate typedef $typedefName');
@@ -356,16 +406,12 @@
 
   /**
    * Find the top level variable with the given [variableName] in the summary,
-   * and return its [UnlinkedVariable] data structure.
+   * and return its [UnlinkedVariable] data structure.  If [variables] is not
+   * specified, the variable is looked for in the defining compilation unit.
    */
   UnlinkedVariable findVariable(String variableName,
-      {UnlinkedClass cls, bool failIfAbsent: false}) {
-    List<UnlinkedVariable> variables;
-    if (cls == null) {
-      variables = unlinked.variables;
-    } else {
-      variables = cls.fields;
-    }
+      {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
+    variables ??= unlinkedUnits[0].variables;
     UnlinkedVariable result;
     for (UnlinkedVariable variable in variables) {
       if (variable.name == variableName) {
@@ -423,7 +469,8 @@
       [String executableName = 'f']) {
     serializeLibraryText('class C { $text }');
     return findExecutable(executableName,
-        cls: findClass('C', failIfAbsent: true), failIfAbsent: true);
+        executables: findClass('C', failIfAbsent: true).executables,
+        failIfAbsent: true);
   }
 
   /**
@@ -637,6 +684,7 @@
     UnlinkedClass cls =
         serializeClassText('class C = D with E; class D {} class E {}');
     checkTypeRef(cls.supertype, null, null, 'D');
+    expect(cls.hasNoSupertype, isFalse);
   }
 
   test_class_concrete() {
@@ -688,7 +736,6 @@
     var classText = 'class C {}';
     UnlinkedClass cls = serializeClassText(classText);
     expect(cls.name, 'C');
-    expect(cls.unit, 0);
   }
 
   test_class_no_flags() {
@@ -720,12 +767,14 @@
   test_class_superclass() {
     UnlinkedClass cls = serializeClassText('class C {}');
     expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isFalse);
   }
 
   test_class_superclass_explicit() {
     UnlinkedClass cls = serializeClassText('class C extends D {} class D {}');
     expect(cls.supertype, isNotNull);
     checkTypeRef(cls.supertype, null, null, 'D');
+    expect(cls.hasNoSupertype, isFalse);
   }
 
   test_class_type_param_bound() {
@@ -757,88 +806,121 @@
   }
 
   test_constructor() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
     expect(executable.kind, UnlinkedExecutableKind.constructor);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
   }
 
   test_constructor_anonymous() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
     expect(executable.name, isEmpty);
   }
 
   test_constructor_const() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { const C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { const C(); }').executables);
     expect(executable.isConst, isTrue);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_constructor_const_external() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { external const C(); }').executables);
+    expect(executable.isConst, isTrue);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_constructor_external() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { external C(); }').executables);
+    expect(executable.isExternal, isTrue);
   }
 
   test_constructor_factory() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { factory C() => null; }'));
+        executables:
+            serializeClassText('class C { factory C() => null; }').executables);
     expect(executable.isFactory, isTrue);
   }
 
   test_constructor_implicit() {
     // Implicit constructors are not serialized.
     UnlinkedExecutable executable = findExecutable(null,
-        cls: serializeClassText('class C { C(); }'), failIfAbsent: false);
+        executables: serializeClassText('class C { C(); }').executables,
+        failIfAbsent: false);
     expect(executable, isNull);
   }
 
   test_constructor_initializing_formal() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x); final x; }'));
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.isInitializingFormal, isTrue);
   }
 
   test_constructor_initializing_formal_explicit_type() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(int this.x); final x; }'));
+        executables: serializeClassText('class C { C(int this.x); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
   }
 
   test_constructor_initializing_formal_function_typed() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x()); final x; }'));
+        executables: serializeClassText('class C { C(this.x()); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.isFunctionTyped, isTrue);
   }
 
   test_constructor_initializing_formal_function_typed_explicit_return_type() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(int this.x()); Function x; }'));
+        executables:
+            serializeClassText('class C { C(int this.x()); Function x; }')
+                .executables);
     UnlinkedParam parameter = executable.parameters[0];
     checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
   }
 
   test_constructor_initializing_formal_function_typed_implicit_return_type() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x()); Function x; }'));
+        executables: serializeClassText('class C { C(this.x()); Function x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
+    // Since the parameter is function-typed it is considered to have an
+    // explicit type, even though that explicit type itself has an implicit
+    // return type.
+    expect(parameter.hasImplicitType, isFalse);
     checkDynamicTypeRef(parameter.type);
   }
 
   test_constructor_initializing_formal_function_typed_no_prameters() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x()); final x; }'));
+        executables: serializeClassText('class C { C(this.x()); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.parameters, isEmpty);
   }
 
   test_constructor_initializing_formal_function_typed_prameter() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x(a)); final x; }'));
+        executables: serializeClassText('class C { C(this.x(a)); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.parameters, hasLength(1));
   }
 
   test_constructor_initializing_formal_function_typed_prameter_order() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x(a, b)); final x; }'));
+        executables: serializeClassText('class C { C(this.x(a, b)); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.parameters, hasLength(2));
     expect(parameter.parameters[0].name, 'a');
@@ -849,14 +931,17 @@
     // Note: the implicit type of an initializing formal is the type of the
     // field.
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x); int x; }'));
+        executables:
+            serializeClassText('class C { C(this.x); int x; }').executables);
     UnlinkedParam parameter = executable.parameters[0];
     checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
+    expect(parameter.hasImplicitType, isTrue);
   }
 
   test_constructor_initializing_formal_name() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x); final x; }'));
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.name, 'x');
   }
@@ -864,14 +949,16 @@
   test_constructor_initializing_formal_named() {
     // TODO(paulberry): also test default value
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C({this.x}); final x; }'));
+        executables: serializeClassText('class C { C({this.x}); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.named);
   }
 
   test_constructor_initializing_formal_non_function_typed() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x); final x; }'));
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.isFunctionTyped, isFalse);
   }
@@ -879,45 +966,47 @@
   test_constructor_initializing_formal_positional() {
     // TODO(paulberry): also test default value
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C([this.x]); final x; }'));
+        executables: serializeClassText('class C { C([this.x]); final x; }')
+            .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.positional);
   }
 
   test_constructor_initializing_formal_required() {
     UnlinkedExecutable executable = findExecutable('',
-        cls: serializeClassText('class C { C(this.x); final x; }'));
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.required);
   }
 
   test_constructor_named() {
-    UnlinkedExecutable executable =
-        findExecutable('foo', cls: serializeClassText('class C { C.foo(); }'));
+    UnlinkedExecutable executable = findExecutable('foo',
+        executables: serializeClassText('class C { C.foo(); }').executables);
     expect(executable.name, 'foo');
   }
 
   test_constructor_non_const() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
     expect(executable.isConst, isFalse);
   }
 
   test_constructor_non_factory() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
     expect(executable.isFactory, isFalse);
   }
 
   test_constructor_return_type() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
     checkTypeRef(executable.returnType, null, null, 'C');
   }
 
   test_constructor_return_type_parameterized() {
-    UnlinkedExecutable executable =
-        findExecutable('', cls: serializeClassText('class C<T, U> { C(); }'));
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C<T, U> { C(); }').executables);
     checkTypeRef(executable.returnType, null, null, 'C',
         allowTypeParameters: true);
     expect(executable.returnType.typeArguments, hasLength(2));
@@ -1027,11 +1116,12 @@
 typedef F();
 ''');
     serializeLibraryText('library my.lib; part "part1.dart";');
-    expect(findClass('C', failIfAbsent: true).unit, 1);
-    expect(findEnum('E', failIfAbsent: true).unit, 1);
-    expect(findVariable('v', failIfAbsent: true).unit, 1);
-    expect(findExecutable('f', failIfAbsent: true).unit, 1);
-    expect(findTypedef('F', failIfAbsent: true).unit, 1);
+    UnlinkedUnit unit = unlinkedUnits[1];
+    expect(findClass('C', unit: unit), isNotNull);
+    expect(findEnum('E', unit: unit), isNotNull);
+    expect(findVariable('v', variables: unit.variables), isNotNull);
+    expect(findExecutable('f', executables: unit.executables), isNotNull);
+    expect(findTypedef('F', unit: unit), isNotNull);
   }
 
   test_enum() {
@@ -1039,7 +1129,6 @@
     expect(e.name, 'E');
     expect(e.values, hasLength(1));
     expect(e.values[0].name, 'v1');
-    expect(e.unit, 0);
   }
 
   test_enum_order() {
@@ -1064,16 +1153,38 @@
   test_executable_function() {
     UnlinkedExecutable executable = serializeExecutableText('f() {}');
     expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.unit, 0);
+    expect(executable.hasImplicitReturnType, isTrue);
+    checkDynamicTypeRef(executable.returnType);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_executable_function_explicit_return() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('dynamic f() => null;');
+    expect(executable.hasImplicitReturnType, isFalse);
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_function_external() {
+    UnlinkedExecutable executable = serializeExecutableText('external f();');
+    expect(executable.isExternal, isTrue);
   }
 
   test_executable_getter() {
     UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
     expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
     expect(findVariable('f'), isNull);
     expect(findExecutable('f='), isNull);
   }
 
+  test_executable_getter_external() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('external int get f;');
+    expect(executable.isExternal, isTrue);
+  }
+
   test_executable_getter_type() {
     UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
     checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
@@ -1083,31 +1194,76 @@
   test_executable_getter_type_implicit() {
     UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
     checkDynamicTypeRef(executable.returnType);
+    expect(executable.hasImplicitReturnType, isTrue);
     expect(executable.parameters, isEmpty);
   }
 
   test_executable_member_function() {
-    UnlinkedExecutable executable =
-        findExecutable('f', cls: serializeClassText('class C { f() {} }'));
+    UnlinkedExecutable executable = findExecutable('f',
+        executables: serializeClassText('class C { f() {} }').executables);
     expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.hasImplicitReturnType, isTrue);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_executable_member_function_explicit_return() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables:
+            serializeClassText('class C { dynamic f() => null; }').executables);
+    expect(executable.hasImplicitReturnType, isFalse);
+  }
+
+  test_executable_member_function_external() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables:
+            serializeClassText('class C { external f(); }').executables);
+    expect(executable.isExternal, isTrue);
   }
 
   test_executable_member_getter() {
     UnlinkedClass cls = serializeClassText('class C { int get f => 1; }');
     UnlinkedExecutable executable =
-        findExecutable('f', cls: cls, failIfAbsent: true);
+        findExecutable('f', executables: cls.executables, failIfAbsent: true);
     expect(executable.kind, UnlinkedExecutableKind.getter);
-    expect(findVariable('f', cls: cls), isNull);
-    expect(findExecutable('f=', cls: cls), isNull);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(findVariable('f', variables: cls.fields), isNull);
+    expect(findExecutable('f=', executables: cls.executables), isNull);
+  }
+
+  test_executable_member_getter_external() {
+    UnlinkedClass cls = serializeClassText('class C { external int get f; }');
+    UnlinkedExecutable executable =
+        findExecutable('f', executables: cls.executables, failIfAbsent: true);
+    expect(executable.isExternal, isTrue);
   }
 
   test_executable_member_setter() {
     UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
     UnlinkedExecutable executable =
-        findExecutable('f=', cls: cls, failIfAbsent: true);
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
     expect(executable.kind, UnlinkedExecutableKind.setter);
-    expect(findVariable('f', cls: cls), isNull);
-    expect(findExecutable('f', cls: cls), isNull);
+    // For setters, hasImplicitReturnType is always false.
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
+    expect(findVariable('f', variables: cls.fields), isNull);
+    expect(findExecutable('f', executables: cls.executables), isNull);
+  }
+
+  test_executable_member_setter_external() {
+    UnlinkedClass cls =
+        serializeClassText('class C { external void set f(value); }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_member_setter_implicit_return() {
+    UnlinkedClass cls = serializeClassText('class C { set f(value) {} }');
+    UnlinkedExecutable executable =
+        findExecutable('f=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.hasImplicitReturnType, isFalse);
+    checkDynamicTypeRef(executable.returnType);
   }
 
   test_executable_name() {
@@ -1135,9 +1291,95 @@
     expect(executable.isStatic, isFalse);
   }
 
+  test_executable_operator() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { C operator+(C c) => null; }').executables[
+            0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '+');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(1));
+    checkTypeRef(executable.returnType, null, null, 'C');
+    expect(executable.typeParameters, isEmpty);
+    expect(executable.isExternal, false);
+  }
+
+  test_executable_operator_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator==(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '==');
+  }
+
+  test_executable_operator_external() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { external C operator+(C c); }')
+            .executables[0];
+    expect(executable.isExternal, true);
+  }
+
+  test_executable_operator_greater_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator>=(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '>=');
+  }
+
+  test_executable_operator_index() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator[](int i) => null; }')
+            .executables[0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '[]');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(1));
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool');
+    expect(executable.typeParameters, isEmpty);
+  }
+
+  test_executable_operator_index_set() {
+    UnlinkedExecutable executable = serializeClassText(
+        'class C { void operator[]=(int i, bool v) => null; }').executables[0];
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.name, '[]=');
+    expect(executable.hasImplicitReturnType, false);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(2));
+    expect(executable.returnType, isNull);
+    expect(executable.typeParameters, isEmpty);
+  }
+
+  test_executable_operator_less_equal() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { bool operator<=(C other) => false; }')
+            .executables[0];
+    expect(executable.name, '<=');
+  }
+
   test_executable_param_function_typed() {
     UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
     expect(executable.parameters[0].isFunctionTyped, isTrue);
+    // Since the parameter is function-typed it is considered to have an
+    // explicit type, even though that explicit type itself has an implicit
+    // return type.
+    expect(executable.parameters[0].hasImplicitType, isFalse);
+  }
+
+  test_executable_param_function_typed_explicit_return_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('f(dynamic g()) {}');
+    expect(executable.parameters[0].hasImplicitType, isFalse);
   }
 
   test_executable_param_function_typed_param() {
@@ -1217,19 +1459,28 @@
     expect(executable.parameters[1].name, 'y');
   }
 
+  test_executable_param_type_explicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+    expect(executable.parameters[0].hasImplicitType, isFalse);
+  }
+
   test_executable_param_type_implicit() {
     UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
     checkDynamicTypeRef(executable.parameters[0].type);
+    expect(executable.parameters[0].hasImplicitType, isTrue);
   }
 
   test_executable_return_type() {
     UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
     checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+    expect(executable.hasImplicitReturnType, isFalse);
   }
 
   test_executable_return_type_implicit() {
     UnlinkedExecutable executable = serializeExecutableText('f() {}');
     checkDynamicTypeRef(executable.returnType);
+    expect(executable.hasImplicitReturnType, isTrue);
   }
 
   test_executable_return_type_void() {
@@ -1241,10 +1492,26 @@
     UnlinkedExecutable executable =
         serializeExecutableText('void set f(value) {}', 'f=');
     expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(executable.hasImplicitReturnType, isFalse);
+    expect(executable.isExternal, isFalse);
     expect(findVariable('f'), isNull);
     expect(findExecutable('f'), isNull);
   }
 
+  test_executable_setter_external() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('external void set f(value);', 'f=');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_setter_implicit_return() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('set f(value) {}', 'f=');
+    // For setters, hasImplicitReturnType is always false.
+    expect(executable.hasImplicitReturnType, isFalse);
+    checkDynamicTypeRef(executable.returnType);
+  }
+
   test_executable_setter_type() {
     UnlinkedExecutable executable =
         serializeExecutableText('void set f(int value) {}', 'f=');
@@ -1291,28 +1558,32 @@
 
   test_export_hide_order() {
     serializeLibraryText('export "dart:async" hide Future, Stream;');
-    expect(unlinked.exports, hasLength(1));
-    expect(unlinked.exports[0].combinators, hasLength(1));
-    expect(unlinked.exports[0].combinators[0].shows, isEmpty);
-    expect(unlinked.exports[0].combinators[0].hides, hasLength(2));
-    checkCombinatorName(unlinked.exports[0].combinators[0].hides[0], 'Future');
-    checkCombinatorName(unlinked.exports[0].combinators[0].hides[1], 'Stream');
+    expect(unlinkedUnits[0].exports, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].combinators[0].shows, isEmpty);
+    expect(unlinkedUnits[0].exports[0].combinators[0].hides, hasLength(2));
+    checkCombinatorName(
+        unlinkedUnits[0].exports[0].combinators[0].hides[0], 'Future');
+    checkCombinatorName(
+        unlinkedUnits[0].exports[0].combinators[0].hides[1], 'Stream');
   }
 
   test_export_no_combinators() {
     serializeLibraryText('export "dart:async";');
-    expect(unlinked.exports, hasLength(1));
-    expect(unlinked.exports[0].combinators, isEmpty);
+    expect(unlinkedUnits[0].exports, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].combinators, isEmpty);
   }
 
   test_export_show_order() {
     serializeLibraryText('export "dart:async" show Future, Stream;');
-    expect(unlinked.exports, hasLength(1));
-    expect(unlinked.exports[0].combinators, hasLength(1));
-    expect(unlinked.exports[0].combinators[0].shows, hasLength(2));
-    expect(unlinked.exports[0].combinators[0].hides, isEmpty);
-    checkCombinatorName(unlinked.exports[0].combinators[0].shows[0], 'Future');
-    checkCombinatorName(unlinked.exports[0].combinators[0].shows[1], 'Stream');
+    expect(unlinkedUnits[0].exports, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].combinators[0].shows, hasLength(2));
+    expect(unlinkedUnits[0].exports[0].combinators[0].hides, isEmpty);
+    checkCombinatorName(
+        unlinkedUnits[0].exports[0].combinators[0].shows[0], 'Future');
+    checkCombinatorName(
+        unlinkedUnits[0].exports[0].combinators[0].shows[1], 'Stream');
   }
 
   test_export_uri() {
@@ -1320,15 +1591,25 @@
     String uriString = '"a.dart"';
     String libraryText = 'export $uriString;';
     serializeLibraryText(libraryText);
-    expect(unlinked.exports, hasLength(1));
-    expect(unlinked.exports[0].uri, 'a.dart');
+    expect(unlinkedUnits[0].exports, hasLength(1));
+    expect(unlinkedUnits[0].exports[0].uri, 'a.dart');
   }
 
   test_field() {
     UnlinkedClass cls = serializeClassText('class C { int i; }');
-    expect(findVariable('i', cls: cls), isNotNull);
-    expect(findExecutable('i', cls: cls), isNull);
-    expect(findExecutable('i=', cls: cls), isNull);
+    UnlinkedVariable variable = findVariable('i', variables: cls.fields);
+    expect(variable, isNotNull);
+    expect(variable.isConst, isFalse);
+    expect(variable.isStatic, isFalse);
+    expect(variable.isFinal, isFalse);
+    expect(findExecutable('i', executables: cls.executables), isNull);
+    expect(findExecutable('i=', executables: cls.executables), isNull);
+  }
+
+  test_field_const() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static const int i = 0; }').fields[0];
+    expect(variable.isConst, isTrue);
   }
 
   test_field_final() {
@@ -1337,10 +1618,10 @@
     expect(variable.isFinal, isTrue);
   }
 
-  test_field_non_final() {
+  test_field_static() {
     UnlinkedVariable variable =
-        serializeClassText('class C { int i; }').fields[0];
-    expect(variable.isFinal, isFalse);
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
   }
 
   test_generic_method_in_generic_class() {
@@ -1356,62 +1637,65 @@
   test_import_deferred() {
     serializeLibraryText(
         'import "dart:async" deferred as a; main() { print(a.Future); }');
-    expect(unlinked.imports[0].isDeferred, isTrue);
+    expect(unlinkedUnits[0].imports[0].isDeferred, isTrue);
   }
 
   test_import_dependency() {
     serializeLibraryText('import "dart:async"; Future x;');
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    checkDependency(lib.importDependencies[0], 'dart:async', 'dart:async');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(
+        prelinked.importDependencies[0], 'dart:async', 'dart:async');
   }
 
   test_import_explicit() {
     serializeLibraryText('import "dart:core"; int i;');
-    expect(unlinked.imports, hasLength(1));
-    expect(unlinked.imports[0].isImplicit, isFalse);
+    expect(unlinkedUnits[0].imports, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
   }
 
   test_import_hide_order() {
     serializeLibraryText(
         'import "dart:async" hide Future, Stream; Completer c;');
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].combinators, hasLength(1));
-    expect(unlinked.imports[0].combinators[0].shows, isEmpty);
-    expect(unlinked.imports[0].combinators[0].hides, hasLength(2));
-    checkCombinatorName(unlinked.imports[0].combinators[0].hides[0], 'Future');
-    checkCombinatorName(unlinked.imports[0].combinators[0].hides[1], 'Stream');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows, isEmpty);
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
+    checkCombinatorName(
+        unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
+    checkCombinatorName(
+        unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
   }
 
   test_import_implicit() {
     // The implicit import of dart:core is represented in the model.
     serializeLibraryText('');
-    expect(unlinked.imports, hasLength(1));
-    checkDependency(lib.importDependencies[0], 'dart:core', 'dart:core');
-    expect(unlinked.imports[0].uri, isEmpty);
-    expect(unlinked.imports[0].prefix, 0);
-    expect(unlinked.imports[0].combinators, isEmpty);
-    expect(unlinked.imports[0].isImplicit, isTrue);
+    expect(unlinkedUnits[0].imports, hasLength(1));
+    checkDependency(prelinked.importDependencies[0], 'dart:core', 'dart:core');
+    expect(unlinkedUnits[0].imports[0].uri, isEmpty);
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
+    expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
   }
 
   test_import_no_combinators() {
     serializeLibraryText('import "dart:async"; Future x;');
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].combinators, isEmpty);
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
   }
 
   test_import_no_flags() {
     serializeLibraryText('import "dart:async"; Future x;');
-    expect(unlinked.imports[0].isImplicit, isFalse);
-    expect(unlinked.imports[0].isDeferred, isFalse);
+    expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
+    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
   }
 
   test_import_non_deferred() {
     serializeLibraryText(
         'import "dart:async" as a; main() { print(a.Future); }');
-    expect(unlinked.imports[0].isDeferred, isFalse);
+    expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
   }
 
   test_import_of_file_with_missing_part() {
@@ -1433,24 +1717,22 @@
   test_import_offset() {
     String libraryText = '    import "dart:async"; Future x;';
     serializeLibraryText(libraryText);
-    expect(unlinked.imports[0].offset, libraryText.indexOf('import'));
+    expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
   }
 
   test_import_prefix_name() {
     String libraryText = 'import "dart:async" as a; a.Future x;';
     serializeLibraryText(libraryText);
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].prefix, isNot(0));
-    expect(unlinked.prefixes[unlinked.imports[0].prefix].name, 'a');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
   }
 
   test_import_prefix_none() {
     serializeLibraryText('import "dart:async"; Future x;');
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].prefix, 0);
-    expect(unlinked.prefixes[unlinked.imports[0].prefix].name, isEmpty);
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
   }
 
   test_import_prefix_reference() {
@@ -1497,12 +1779,14 @@
         'import "dart:async" show Future, Stream; Future x; Stream y;';
     serializeLibraryText(libraryText);
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].combinators, hasLength(1));
-    expect(unlinked.imports[0].combinators[0].shows, hasLength(2));
-    expect(unlinked.imports[0].combinators[0].hides, isEmpty);
-    checkCombinatorName(unlinked.imports[0].combinators[0].shows[0], 'Future');
-    checkCombinatorName(unlinked.imports[0].combinators[0].shows[1], 'Stream');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty);
+    checkCombinatorName(
+        unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
+    checkCombinatorName(
+        unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
   }
 
   test_import_uri() {
@@ -1510,42 +1794,25 @@
     String libraryText = 'import $uriString; Future x;';
     serializeLibraryText(libraryText);
     // Second import is the implicit import of dart:core
-    expect(unlinked.imports, hasLength(2));
-    expect(unlinked.imports[0].uri, 'dart:async');
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
   }
 
   test_library_named() {
     String text = 'library foo.bar;';
     serializeLibraryText(text);
-    expect(unlinked.name, 'foo.bar');
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
   }
 
   test_library_unnamed() {
     serializeLibraryText('');
-    expect(unlinked.name, isEmpty);
-  }
-
-  test_nested_elements_have_no_part() {
-    addNamedSource(
-        '/part1.dart',
-        '''
-part of my.lib;
-
-class C {
-  var v;
-  f() {}
-}
-''');
-    serializeLibraryText('library my.lib; part "part1.dart";');
-    UnlinkedClass cls = findClass('C');
-    expect(findVariable('v', cls: cls).unit, 0);
-    expect(findExecutable('f', cls: cls).unit, 0);
+    expect(unlinkedUnits[0].libraryName, isEmpty);
   }
 
   test_parts_defining_compilation_unit() {
     serializeLibraryText('');
-    expect(unlinked.units, hasLength(1));
-    expect(unlinked.units[0].uri, isEmpty);
+    expect(prelinked.units, hasLength(1));
+    expect(unlinkedUnits[0].parts, isEmpty);
   }
 
   test_parts_included() {
@@ -1553,8 +1820,9 @@
     String partString = '"part1.dart"';
     String libraryText = 'library my.lib; part $partString;';
     serializeLibraryText(libraryText);
-    expect(unlinked.units, hasLength(2));
-    expect(unlinked.units[1].uri, 'part1.dart');
+    expect(prelinked.units, hasLength(2));
+    expect(unlinkedUnits[0].parts, hasLength(1));
+    expect(unlinkedUnits[0].parts[0].uri, 'part1.dart');
   }
 
   test_type_arguments_explicit() {
@@ -1620,16 +1888,26 @@
     checkDynamicTypeRef(serializeTypeText('dynamic'));
   }
 
+  test_type_reference_from_part() {
+    addNamedSource('/a.dart', 'part of foo; C v;');
+    serializeLibraryText('library foo; part "a.dart"; class C {}');
+    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
+        null, null, 'C',
+        expectedKind: PrelinkedReferenceKind.classOrEnum,
+        prelinkedSourceUnit: prelinked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
   test_type_reference_to_class_argument() {
     UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
     {
       UnlinkedTypeRef typeRef =
-          findVariable('t', cls: cls, failIfAbsent: true).type;
+          findVariable('t', variables: cls.fields, failIfAbsent: true).type;
       checkParamTypeRef(typeRef, 2);
     }
     {
       UnlinkedTypeRef typeRef =
-          findVariable('u', cls: cls, failIfAbsent: true).type;
+          findVariable('u', variables: cls.fields, failIfAbsent: true).type;
       checkParamTypeRef(typeRef, 1);
     }
   }
@@ -1661,7 +1939,7 @@
         absUri('/a.dart'),
         'a.dart',
         'C',
-        expectedUnit: 1);
+        expectedTargetUnit: 1);
   }
 
   test_type_reference_to_imported_part_with_prefix() {
@@ -1674,7 +1952,7 @@
         'a.dart',
         'C',
         expectedPrefix: 'p',
-        expectedUnit: 1);
+        expectedTargetUnit: 1);
   }
 
   test_type_reference_to_internal_class() {
@@ -1704,7 +1982,7 @@
         null,
         null,
         'C',
-        expectedUnit: 1);
+        expectedTargetUnit: 1);
   }
 
   test_type_reference_to_nonexistent_file_via_prefix() {
@@ -1713,6 +1991,18 @@
     checkUnresolvedTypeRef(typeRef, 'p', 'C');
   }
 
+  test_type_reference_to_part() {
+    addNamedSource('/a.dart', 'part of foo; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library foo; part "a.dart";'),
+        null,
+        null,
+        'C',
+        expectedKind: PrelinkedReferenceKind.classOrEnum,
+        expectedTargetUnit: 1);
+  }
+
   test_type_reference_to_typedef() {
     checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
         null, null, 'F',
@@ -1728,7 +2018,8 @@
     // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is
     // b.dart.  a.dart and b.dart are counted even though nothing is imported
     // from them.
-    checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C', expectedUnit: 2);
+    checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C',
+        expectedTargetUnit: 2);
   }
 
   test_type_unresolved() {
@@ -1739,7 +2030,6 @@
   test_typedef_name() {
     UnlinkedTypedef type = serializeTypedefText('typedef F();');
     expect(type.name, 'F');
-    expect(type.unit, 0);
   }
 
   test_typedef_param_none() {
@@ -1793,6 +2083,12 @@
     expect(variable.isConst, isTrue);
   }
 
+  test_variable_explicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('dynamic v;');
+    checkDynamicTypeRef(variable.type);
+    expect(variable.hasImplicitType, isFalse);
+  }
+
   test_variable_final_top_level() {
     UnlinkedVariable variable =
         serializeVariableText('final int i = 0;', variableName: 'i');
@@ -1802,13 +2098,13 @@
   test_variable_implicit_dynamic() {
     UnlinkedVariable variable = serializeVariableText('var v;');
     checkDynamicTypeRef(variable.type);
+    expect(variable.hasImplicitType, isTrue);
   }
 
   test_variable_name() {
     UnlinkedVariable variable =
         serializeVariableText('int i;', variableName: 'i');
     expect(variable.name, 'i');
-    expect(variable.unit, 0);
   }
 
   test_variable_no_flags() {
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 09d71ad..fd4fee2 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4,10 +4,12 @@
 
 library analyzer.test.src.task.dart_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisOptionsImpl, CacheState;
 import 'package:analyzer/src/generated/error.dart';
@@ -62,6 +64,7 @@
   runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
   runReflectiveTests(PropagateVariableTypeTaskTest);
   runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
+  runReflectiveTests(ResolveLibraryTaskTest);
   runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
   runReflectiveTests(ResolveUnitTaskTest);
   runReflectiveTests(ResolveUnitTypeNamesTaskTest);
@@ -124,6 +127,7 @@
     new isInstanceOf<PropagateVariableTypesInUnitTask>();
 isInstanceOf isPropagateVariableTypeTask =
     new isInstanceOf<PropagateVariableTypeTask>();
+isInstanceOf isResolveLibraryTask = new isInstanceOf<ResolveLibraryTask>();
 isInstanceOf isResolveLibraryTypeNamesTask =
     new isInstanceOf<ResolveLibraryTypeNamesTask>();
 isInstanceOf isResolveUnitTask = new isInstanceOf<ResolveUnitTask>();
@@ -1427,62 +1431,6 @@
     expect(outputs[LIBRARY_CYCLE], hasLength(1));
   }
 
-  void test_library_cycle_override_inference_incremental() {
-    enableStrongMode();
-    Source lib1Source = newSource(
-        '/my_lib1.dart',
-        '''
-library my_lib1;
-import 'my_lib3.dart';
-''');
-    Source lib2Source = newSource(
-        '/my_lib2.dart',
-        '''
-library my_lib2;
-import 'my_lib1.dart';
-''');
-    Source lib3Source = newSource(
-        '/my_lib3.dart',
-        '''
-library my_lib3;
-import 'my_lib2.dart';
-
-class A {
-  int foo(int x) => null;
-}
-class B extends A {
-  foo(x) => null;
-}
-''');
-    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
-    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
-    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
-
-    computeResult(lib1Target, RESOLVED_UNIT);
-    computeResult(lib2Target, RESOLVED_UNIT);
-    computeResult(lib3Target, RESOLVED_UNIT);
-    CompilationUnit unit = outputs[RESOLVED_UNIT];
-    ClassElement b = unit.declarations[1].element;
-    expect(b.getMethod('foo').returnType.toString(), 'int');
-
-    // add a dummy edit.
-    context.setContents(
-        lib1Source,
-        '''
-library my_lib1;
-import 'my_lib3.dart';
-var foo = 123;
-''');
-
-    computeResult(lib1Target, RESOLVED_UNIT);
-    computeResult(lib2Target, RESOLVED_UNIT);
-    computeResult(lib3Target, RESOLVED_UNIT);
-    unit = outputs[RESOLVED_UNIT];
-    b = unit.declarations[1].element;
-    expect(b.getMethod('foo').returnType.toString(), 'int',
-        reason: 'edit should not affect member inference');
-  }
-
   void test_library_cycle_incremental_partial() {
     enableStrongMode();
     Source lib1Source = newSource(
@@ -1592,6 +1540,62 @@
     expect(dep2, hasLength(1)); // dart:core
   }
 
+  void test_library_cycle_override_inference_incremental() {
+    enableStrongMode();
+    Source lib1Source = newSource(
+        '/my_lib1.dart',
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+''');
+    Source lib2Source = newSource(
+        '/my_lib2.dart',
+        '''
+library my_lib2;
+import 'my_lib1.dart';
+''');
+    Source lib3Source = newSource(
+        '/my_lib3.dart',
+        '''
+library my_lib3;
+import 'my_lib2.dart';
+
+class A {
+  int foo(int x) => null;
+}
+class B extends A {
+  foo(x) => null;
+}
+''');
+    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
+    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
+    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    CompilationUnit unit = outputs[RESOLVED_UNIT];
+    ClassElement b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int');
+
+    // add a dummy edit.
+    context.setContents(
+        lib1Source,
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+var foo = 123;
+''');
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    unit = outputs[RESOLVED_UNIT];
+    b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int',
+        reason: 'edit should not affect member inference');
+  }
+
   void test_library_cycle_self_loop() {
     List<Source> sources = newSources({
       '/a.dart': '''
@@ -3542,6 +3546,32 @@
 }
 
 @reflectiveTest
+class ResolveLibraryTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source sourceLib = newSource(
+        '/my_lib.dart',
+        '''
+library my_lib;
+const a = new A();
+class A {
+  const A();
+}
+@a
+class C {}
+''');
+    computeResult(sourceLib, LIBRARY_ELEMENT, matcher: isResolveLibraryTask);
+    // validate
+    LibraryElement library = outputs[LIBRARY_ELEMENT];
+    ClassElement classC = library.getType('C');
+    List<ElementAnnotation> metadata = classC.metadata;
+    expect(metadata, hasLength(1));
+    ElementAnnotation annotation = metadata[0];
+    expect(annotation, isNotNull);
+    expect((annotation as ElementAnnotationImpl).evaluationResult, isNotNull);
+  }
+}
+
+@reflectiveTest
 class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
   test_perform() {
     Source sourceLib = newSource(
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index e135d99..b0f8181 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -344,7 +344,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, value: 42);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     bool streamNotified = false;
     analysisDriver.onResultComputed(result).listen((event) {
@@ -368,7 +368,7 @@
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target,
         descriptor: descriptor, exception: exception);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -383,7 +383,7 @@
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', (context, target) => task, (target) => {}, [result]);
     task = new TestAnalysisTask(context, target, descriptor: descriptor);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
 
     analysisDriver.performWorkItem(item);
     CacheEntry targetEntry = context.getCacheEntry(item.target);
@@ -401,7 +401,7 @@
         [result]);
     CaughtException exception =
         new CaughtException(new AnalysisException(), null);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     item.exception = exception;
 
     analysisDriver.performWorkItem(item);
@@ -418,7 +418,7 @@
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
     analysisDriver.currentWorkOrder = new WorkOrder(
-        taskManager, new WorkItem(null, null, descriptor, null, null));
+        taskManager, new WorkItem(null, null, descriptor, null, 0, null));
 
     analysisDriver.reset();
     expect(analysisDriver.currentWorkOrder, isNull);
@@ -616,7 +616,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     AnalysisTask task = item.buildTask();
     expect(task, isNotNull);
   }
@@ -633,7 +633,7 @@
             new TestAnalysisTask(context, target, results: outputResults),
         (target) => {'one': inputResult.of(target)},
         outputResults);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     expect(() => item.buildTask(), throwsStateError);
   }
 
@@ -641,7 +641,7 @@
     AnalysisTarget target = new TestSource();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (target) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     expect(item, isNotNull);
     expect(item.context, context);
     expect(item.descriptor, descriptor);
@@ -655,7 +655,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNull);
@@ -680,7 +680,7 @@
     taskManager.addTaskDescriptor(task1);
     taskManager.addTaskDescriptor(task2);
     // gather inputs
-    WorkItem item = new WorkItem(context, target, task2, null, null);
+    WorkItem item = new WorkItem(context, target, task2, null, 0, null);
     WorkItem inputItem = item.gatherInputs(taskManager, []);
     expect(inputItem, isNotNull);
   }
@@ -693,7 +693,7 @@
         (context, target) => new TestAnalysisTask(context, target),
         (target) => {'one': inputResult.of(target)},
         [new ResultDescriptor('output', null)]);
-    WorkItem item = new WorkItem(context, target, descriptor, null, null);
+    WorkItem item = new WorkItem(context, target, descriptor, null, 0, null);
     WorkItem result = item.gatherInputs(taskManager, []);
     expect(result, isNull);
     expect(item.exception, isNotNull);
@@ -707,7 +707,7 @@
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
     WorkOrder order = new WorkOrder(
-        manager, new WorkItem(null, null, descriptor, null, null));
+        manager, new WorkItem(null, null, descriptor, null, 0, null));
     expect(order, isNotNull);
     expect(order.currentItems, isNull);
     expect(order.current, isNull);
@@ -717,7 +717,7 @@
     TaskManager manager = new TaskManager();
     TaskDescriptor descriptor = new TaskDescriptor(
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
-    WorkItem workItem = new WorkItem(null, null, descriptor, null, null);
+    WorkItem workItem = new WorkItem(null, null, descriptor, null, 0, null);
     WorkOrder order = new WorkOrder(manager, workItem);
     // "item" has no child items
     expect(order.moveNext(), isTrue);
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index a331255..114a452 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -4,8 +4,8 @@
 
 library analyzer.test.src.task.incremental_element_builder_test;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/incremental_element_builder.dart';
 import 'package:unittest/unittest.dart';
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 b325909c..0141e38 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -6,11 +6,11 @@
 // package:dev_compiler's tests
 library analyzer.test.src.task.strong.strong_test_helper;
 
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/context.dart' show SdkAnalysisContext;
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -240,8 +240,8 @@
         context.resolveCompilationUnit2(mainSource, mainSource);
 
     var collector = new _ErrorCollector();
-    var checker = new CodeChecker(context.typeProvider,
-        new StrongTypeSystemImpl(), collector,
+    var checker = new CodeChecker(
+        context.typeProvider, new StrongTypeSystemImpl(), collector,
         hints: true);
 
     // Extract expectations from the comments in the test files, and
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index 64db1a5..6859d48 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -4,8 +4,9 @@
 
 library analyzer.test.src.task.strong_mode_test;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:unittest/unittest.dart';
@@ -338,6 +339,29 @@
     expect(getterB.returnType, getterA.returnType);
   }
 
+  void test_inferCompilationUnit_fieldFormal() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String fieldName = 'f';
+    CompilationUnitElement unit = resolve('''
+class A {
+  final $fieldName = 0;
+  A([this.$fieldName = 'hello']);
+}
+''');
+    ClassElement classA = unit.getType('A');
+    FieldElement fieldA = classA.getField(fieldName);
+    FieldFormalParameterElement paramA =
+        classA.unnamedConstructor.parameters[0];
+    expect(fieldA.type.isDynamic, isTrue);
+    expect(paramA.type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    DartType intType = inferrer.typeProvider.intType;
+    expect(fieldA.type, intType);
+    expect(paramA.type, intType);
+  }
+
   void test_inferCompilationUnit_getter_multiple_different() {
     InstanceMemberInferrer inferrer = createInferrer;
     String getterName = 'g';
@@ -498,87 +522,6 @@
     expect(getterB.returnType, getterA.returnType);
   }
 
-  void test_inferCompilationUnit_setter_single() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String setterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A {
-  set $setterName(int x) {}
-}
-class B extends A {
-  set $setterName(x) {}
-}
-''');
-    ClassElement classA = unit.getType('A');
-    FieldElement fieldA = classA.getField(setterName);
-    PropertyAccessorElement setterA = classA.getSetter(setterName);
-    ClassElement classB = unit.getType('B');
-    FieldElement fieldB = classB.getField(setterName);
-    PropertyAccessorElement setterB = classB.getSetter(setterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    expect(fieldB.type, fieldA.type);
-    expect(setterB.parameters[0].type, setterA.parameters[0].type);
-  }
-
-  void test_inferCompilationUnit_setter_single_generic() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String setterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A<E> {
-  set $setterName(E x) {}
-}
-class B<E> extends A<E> {
-  set $setterName(x) {}
-}
-''');
-    ClassElement classB = unit.getType('B');
-    DartType typeBE = classB.typeParameters[0].type;
-    FieldElement fieldB = classB.getField(setterName);
-    PropertyAccessorElement setterB = classB.getSetter(setterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    expect(fieldB.type, typeBE);
-    expect(setterB.parameters[0].type, typeBE);
-  }
-
-  void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
-    InstanceMemberInferrer inferrer = createInferrer;
-    String getterName = 'g';
-    CompilationUnitElement unit = resolve('''
-class A {
-  int get $getterName => 0;
-  set $getterName(String value) {}
-}
-class B extends A {
-  set $getterName(x) {}
-}
-''');
-    ClassElement classA = unit.getType('A');
-    PropertyAccessorElement setterA = classA.getSetter(getterName);
-    ClassElement classB = unit.getType('B');
-    FieldElement fieldB = classB.getField(getterName);
-    PropertyAccessorElement setterB = classB.getSetter(getterName);
-    expect(fieldB.type.isDynamic, isTrue);
-    expect(setterB.parameters[0].type.isDynamic, isTrue);
-
-    inferrer.inferCompilationUnit(unit);
-
-    // Expected behavior is that the getter is inferred: getters and setters
-    // are treated as independent methods.
-    expect(setterB.parameters[0].type, setterA.parameters[0].type);
-
-    // Note that B's synthetic field type will be String. This matches what
-    // resolver would do if we explicitly typed the parameter as 'String'
-    expect(fieldB.type, setterB.parameters[0].type);
-  }
-
   void test_inferCompilationUnit_invalid_inheritanceCycle() {
     InstanceMemberInferrer inferrer = createInferrer;
     CompilationUnitElement unit = resolve('''
@@ -689,7 +632,8 @@
     expect(parameterC.type.isDynamic, isTrue);
   }
 
-  void test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
+  void
+      test_inferCompilationUnit_method_parameter_multiple_optionalAndRequired() {
     InstanceMemberInferrer inferrer = createInferrer;
     String methodName = 'm';
     CompilationUnitElement unit = resolve('''
@@ -955,27 +899,85 @@
         reason: 'function type should still have type arguments');
   }
 
-  void test_inferCompilationUnit_fieldFormal() {
+  void test_inferCompilationUnit_setter_single() {
     InstanceMemberInferrer inferrer = createInferrer;
-    String fieldName = 'f';
+    String setterName = 'g';
     CompilationUnitElement unit = resolve('''
 class A {
-  final $fieldName = 0;
-  A([this.$fieldName = 'hello']);
+  set $setterName(int x) {}
+}
+class B extends A {
+  set $setterName(x) {}
 }
 ''');
     ClassElement classA = unit.getType('A');
-    FieldElement fieldA = classA.getField(fieldName);
-    FieldFormalParameterElement paramA =
-        classA.unnamedConstructor.parameters[0];
-    expect(fieldA.type.isDynamic, isTrue);
-    expect(paramA.type.isDynamic, isTrue);
+    FieldElement fieldA = classA.getField(setterName);
+    PropertyAccessorElement setterA = classA.getSetter(setterName);
+    ClassElement classB = unit.getType('B');
+    FieldElement fieldB = classB.getField(setterName);
+    PropertyAccessorElement setterB = classB.getSetter(setterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
 
     inferrer.inferCompilationUnit(unit);
 
-    DartType intType = inferrer.typeProvider.intType;
-    expect(fieldA.type, intType);
-    expect(paramA.type, intType);
+    expect(fieldB.type, fieldA.type);
+    expect(setterB.parameters[0].type, setterA.parameters[0].type);
+  }
+
+  void test_inferCompilationUnit_setter_single_generic() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String setterName = 'g';
+    CompilationUnitElement unit = resolve('''
+class A<E> {
+  set $setterName(E x) {}
+}
+class B<E> extends A<E> {
+  set $setterName(x) {}
+}
+''');
+    ClassElement classB = unit.getType('B');
+    DartType typeBE = classB.typeParameters[0].type;
+    FieldElement fieldB = classB.getField(setterName);
+    PropertyAccessorElement setterB = classB.getSetter(setterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    expect(fieldB.type, typeBE);
+    expect(setterB.parameters[0].type, typeBE);
+  }
+
+  void test_inferCompilationUnit_setter_single_inconsistentAccessors() {
+    InstanceMemberInferrer inferrer = createInferrer;
+    String getterName = 'g';
+    CompilationUnitElement unit = resolve('''
+class A {
+  int get $getterName => 0;
+  set $getterName(String value) {}
+}
+class B extends A {
+  set $getterName(x) {}
+}
+''');
+    ClassElement classA = unit.getType('A');
+    PropertyAccessorElement setterA = classA.getSetter(getterName);
+    ClassElement classB = unit.getType('B');
+    FieldElement fieldB = classB.getField(getterName);
+    PropertyAccessorElement setterB = classB.getSetter(getterName);
+    expect(fieldB.type.isDynamic, isTrue);
+    expect(setterB.parameters[0].type.isDynamic, isTrue);
+
+    inferrer.inferCompilationUnit(unit);
+
+    // Expected behavior is that the getter is inferred: getters and setters
+    // are treated as independent methods.
+    expect(setterB.parameters[0].type, setterA.parameters[0].type);
+
+    // Note that B's synthetic field type will be String. This matches what
+    // resolver would do if we explicitly typed the parameter as 'String'
+    expect(fieldB.type, setterB.parameters[0].type);
   }
 }
 
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index d5d2879..e162219 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -4,8 +4,9 @@
 
 library analyzer.test.utils;
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:path/path.dart' as path;
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 186a101..03593db 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -307,6 +307,8 @@
       indent(() {
         out('final Map _json = {};');
         out();
+        out('bool _finished = false;');
+        out();
         out('${name}Builder(builder.BuilderContext context);');
         cls.fields.forEach((String fieldName, idlModel.FieldType type) {
           out();
@@ -328,6 +330,7 @@
           builderParams.add('${encodedType(type)} $fieldName');
           out('void set $fieldName(${encodedType(type)} _value) {');
           indent(() {
+            out('assert(!_finished);');
             out('assert(!_json.containsKey(${quoted(fieldName)}));');
             out('if (_value != null$condition) {');
             indent(() {
@@ -342,7 +345,13 @@
           out('List<int> toBuffer() => UTF8.encode(JSON.encode(finish()));');
         }
         out();
-        out('Map finish() => _json;');
+        out('Map finish() {');
+        indent(() {
+          out('assert(!_finished);');
+          out('_finished = true;');
+          out('return _json;');
+        });
+        out('}');
       });
       out('}');
       out();
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index fa71eec..117dfe4 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -79,9 +79,12 @@
 @topLevel
 class PrelinkedLibrary {
   /**
-   * The unlinked library summary.
+   * The pre-linked summary of all the compilation units constituting the
+   * library.  The summary of the defining compilation unit is listed first,
+   * followed by the summary of each part, in the order of the `part`
+   * declarations in the defining compilation unit.
    */
-  UnlinkedLibrary unlinked;
+  List<PrelinkedUnit> units;
 
   /**
    * The libraries that this library depends on (either via an explicit import
@@ -102,12 +105,6 @@
    * well, since there will effectively be a one-to-one mapping.
    */
   List<int> importDependencies;
-
-  /**
-   * For each reference in [UnlinkedLibrary.references], information about how
-   * that reference is resolved.
-   */
-  List<PrelinkedReference> references;
 }
 
 /**
@@ -115,20 +112,20 @@
  */
 class PrelinkedReference {
   /**
-   * Index into [UnlinkedLibrary.dependencies] indicating which imported library
+   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
    */
   int dependency;
 
   /**
    * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
-   * the kind if [PrelinkedReferenceKind.classOrEnum].
+   * the kind is [PrelinkedReferenceKind.classOrEnum].
    */
   PrelinkedReferenceKind kind;
 
   /**
    * Integer index indicating which unit in the imported library contains the
-   * definition of the entity.  As with indices into [UnlinkedLibrary.units],
+   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
    */
@@ -156,12 +153,28 @@
   other,
 
   /**
+   * The entity is a prefix.
+   */
+  prefix,
+
+  /**
    * The entity being referred to does not exist.
    */
   unresolved
 }
 
 /**
+ * Pre-linked summary of a compilation unit.
+ */
+class PrelinkedUnit {
+  /**
+   * For each reference in [UnlinkedUnit.references], information about how
+   * that reference is resolved.
+   */
+  List<PrelinkedReference> references;
+}
+
+/**
  * Unlinked summary information about a class declaration.
  */
 class UnlinkedClass {
@@ -171,13 +184,6 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * class is declared in.
-   */
-  @informative
-  int unit;
-
-  /**
    * Type parameters of the class, if any.
    */
   List<UnlinkedTypeParam> typeParameters;
@@ -190,7 +196,7 @@
   UnlinkedTypeRef supertype;
 
   /**
-   * Mixins appering in a `with` clause, if any.
+   * Mixins appearing in a `with` clause, if any.
    */
   List<UnlinkedTypeRef> mixins;
 
@@ -218,6 +224,12 @@
    * Indicates whether the class is declared using mixin application syntax.
    */
   bool isMixinApplication;
+
+  /**
+   * Indicates whether this class is the core "Object" class (and hence has no
+   * supertype)
+   */
+  bool hasNoSupertype;
 }
 
 /**
@@ -260,13 +272,6 @@
    * Values listed in the enum declaration, in declaration order.
    */
   List<UnlinkedEnumValue> values;
-
-  /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * enum is declared in.
-   */
-  @informative
-  int unit;
 }
 
 /**
@@ -293,14 +298,6 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * executable is declared in.  Zero for executables which are nested inside
-   * another declaration (i.e. local functions and method declarations).
-   */
-  @informative
-  int unit;
-
-  /**
    * Type parameters of the executable, if any.  Empty if support for generic
    * method syntax is disabled.
    */
@@ -349,6 +346,17 @@
    * Indicates whether the executable is declared using the `factory` keyword.
    */
   bool isFactory;
+
+  /**
+   * Indicates whether the executable lacks an explicit return type
+   * declaration.  False for constructors and setters.
+   */
+  bool hasImplicitReturnType;
+
+  /**
+   * Indicates whether the executable is declared using the `external` keyword.
+   */
+  bool isExternal;
 }
 
 /**
@@ -408,12 +416,12 @@
   int offset;
 
   /**
-   * Index into [UnlinkedLibrary.prefixes] of the prefix declared by this
+   * Index into [UnlinkedUnit.references] of the prefix declared by this
    * import declaration, or zero if this import declaration declares no prefix.
    *
    * Note that multiple imports can declare the same prefix.
    */
-  int prefix;
+  int prefixReference;
 
   /**
    * Combinators contained in this import declaration.
@@ -432,70 +440,6 @@
 }
 
 /**
- * Unlinked summary of an entire library.
- */
-class UnlinkedLibrary {
-  /**
-   * Top level and prefixed names referred to by this library.
-   */
-  List<UnlinkedReference> references;
-
-  /**
-   * Information about the units constituting this library.  The first unit
-   * listed is always the defining compilation unit.  The remaining units are
-   * listed in the order of their corresponding `part` declarations.
-   */
-  List<UnlinkedUnit> units;
-
-  /**
-   * Name of the library (from a "library" declaration, if present).
-   */
-  String name;
-
-  /**
-   * Classes declared in the library.
-   */
-  List<UnlinkedClass> classes;
-
-  /**
-   * Enums declared in the library.
-   */
-  List<UnlinkedEnum> enums;
-
-  /**
-   * Top level executable objects (functions, getters, and setters) declared in
-   * the library.
-   */
-  List<UnlinkedExecutable> executables;
-
-  /**
-   * Export declarations in the library.
-   */
-  List<UnlinkedExport> exports;
-
-  /**
-   * Import declarations in the library.
-   */
-  List<UnlinkedImport> imports;
-
-  /**
-   * Typedefs declared in the library.
-   */
-  List<UnlinkedTypedef> typedefs;
-
-  /**
-   * Top level variables declared in the library.
-   */
-  List<UnlinkedVariable> variables;
-
-  /**
-   * Prefixes introduced by import declarations.  The first element in this
-   * array is a pseudo-prefix used by references made with no prefix.
-   */
-  List<UnlinkedPrefix> prefixes;
-}
-
-/**
  * Unlinked summary information about a function parameter.
  */
 class UnlinkedParam {
@@ -533,6 +477,12 @@
    * declared using `this.` syntax).
    */
   bool isInitializingFormal;
+
+  /**
+   * Indicates whether this parameter lacks an explicit type declaration.
+   * Always false for a function-typed parameter.
+   */
+  bool hasImplicitType;
 }
 
 /**
@@ -555,12 +505,14 @@
   named
 }
 
-class UnlinkedPrefix {
+/**
+ * Unlinked summary information about a part declaration.
+ */
+class UnlinkedPart {
   /**
-   * The name of the prefix, or the empty string in the case of the
-   * pseudo-prefix which represents "no prefix".
+   * String used in the compilation unit to refer to the part file.
    */
-  String name;
+  String uri;
 }
 
 /**
@@ -575,10 +527,10 @@
   String name;
 
   /**
-   * Prefix used to refer to the entity.  This is an index into
-   * [UnlinkedLibrary.prefixes].
+   * Prefix used to refer to the entity, or zero if no prefix is used.  This is
+   * an index into [UnlinkedUnit.references].
    */
-  int prefix;
+  int prefixReference;
 }
 
 /**
@@ -591,13 +543,6 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * typedef is declared in.
-   */
-  @informative
-  int unit;
-
-  /**
    * Type parameters of the typedef, if any.
    */
   List<UnlinkedTypeParam> typeParameters;
@@ -634,11 +579,11 @@
  */
 class UnlinkedTypeRef {
   /**
-   * Index into [UnlinkedLibrary.references] for the type being referred to, or
+   * Index into [UnlinkedUnit.references] for the type being referred to, or
    * zero if this is a reference to a type parameter.
    *
    * Note that since zero is also a valid index into
-   * [UnlinkedLibrary.references], we cannot distinguish between references to
+   * [UnlinkedUnit.references], we cannot distinguish between references to
    * type parameters and references to types by checking [reference] against
    * zero.  To distinguish between references to type parameters and references
    * to types, check whether [paramReference] is zero.
@@ -674,18 +619,62 @@
 }
 
 /**
- * Unlinked summary information about a compilation unit ("part file").  Note
- * that since a declaration can be moved from one part file to another without
- * changing semantics, the declarations themselves aren't stored here; they are
- * stored in [UnlinkedLibrary] and they refer to [UnlinkedUnit]s via an index
- * into [UnlinkedLibrary.units].
+ * Unlinked summary information about a compilation unit ("part file").
  */
+@topLevel
 class UnlinkedUnit {
   /**
-   * String used in the defining compilation unit to reference the part file.
-   * Empty for the defining compilation unit itself.
+   * Name of the library (from a "library" declaration, if present).
    */
-  String uri;
+  String libraryName;
+
+  /**
+   * Top level and prefixed names referred to by this compilation unit.  The
+   * zeroth element of this array is always populated and always represents a
+   * reference to the pseudo-type "dynamic".
+   */
+  List<UnlinkedReference> references;
+
+  /**
+   * Classes declared in the compilation unit.
+   */
+  List<UnlinkedClass> classes;
+
+  /**
+   * Enums declared in the compilation unit.
+   */
+  List<UnlinkedEnum> enums;
+
+  /**
+   * Top level executable objects (functions, getters, and setters) declared in
+   * the compilation unit.
+   */
+  List<UnlinkedExecutable> executables;
+
+  /**
+   * Export declarations in the compilation unit.
+   */
+  List<UnlinkedExport> exports;
+
+  /**
+   * Import declarations in the compilation unit.
+   */
+  List<UnlinkedImport> imports;
+
+  /**
+   * Part declarations in the compilation unit.
+   */
+  List<UnlinkedPart> parts;
+
+  /**
+   * Typedefs declared in the compilation unit.
+   */
+  List<UnlinkedTypedef> typedefs;
+
+  /**
+   * Top level variables declared in the compilation unit.
+   */
+  List<UnlinkedVariable> variables;
 }
 
 /**
@@ -699,14 +688,6 @@
   String name;
 
   /**
-   * Index into [UnlinkedLibrary.units] indicating which compilation unit the
-   * variable is declared in.  Zero for variables which are nested inside
-   * another declaration (i.e. local variables and fields).
-   */
-  @informative
-  int unit;
-
-  /**
    * Declared type of the variable.  Note that when strong mode is enabled, the
    * actual type of the variable may be different due to type inference.
    */
@@ -730,4 +711,9 @@
    * Indicates whether the variable is declared using the `const` keyword.
    */
   bool isConst;
+
+  /**
+   * Indicates whether this variable lacks an explicit type declaration.
+   */
+  bool hasImplicitType;
 }
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index 2886352..91560b2 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -21,11 +21,12 @@
 import 'dart:io' as io;
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/codegen/tools.dart';
 import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -127,7 +128,8 @@
     context = AnalysisEngine.instance.createAnalysisContext();
     String packageRootPath;
     if (Platform.packageRoot.isNotEmpty) {
-      packageRootPath = Platform.packageRoot;
+      Uri packageRootUri = Uri.parse(Platform.packageRoot);
+      packageRootPath = packageRootUri.toFilePath();
     } else {
       packageRootPath = path.join(rootDir, 'packages');
     }
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 7afcf76..baacc31 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -31,6 +31,8 @@
   COMPILATION_UNIT_ELEMENT [shape=box]
   CONSTANT_DEPENDENCIES -> ComputeConstantValueTask
   CONSTANT_DEPENDENCIES [shape=box]
+  CONSTANT_EXPRESSIONS_DEPENDENCIES -> EvaluateUnitConstantsTask
+  CONSTANT_EXPRESSIONS_DEPENDENCIES [shape=box]
   CONSTANT_VALUE -> ComputeConstantValueTask
   CONSTANT_VALUE -> EvaluateUnitConstantsTask
   CONSTANT_VALUE [shape=box]
@@ -58,7 +60,6 @@
   EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
   EXPORTED_LIBRARIES -> ReadyResolvedUnit10Task
   EXPORTED_LIBRARIES -> ReadyResolvedUnit11Task
-  EXPORTED_LIBRARIES -> ReadyResolvedUnitTask
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
   EXPORT_SOURCE_CLOSURE [shape=box]
@@ -75,7 +76,6 @@
   IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
   IMPORTED_LIBRARIES -> ReadyResolvedUnit10Task
   IMPORTED_LIBRARIES -> ReadyResolvedUnit11Task
-  IMPORTED_LIBRARIES -> ReadyResolvedUnitTask
   IMPORTED_LIBRARIES -> ResolveUnitTypeNamesTask
   IMPORTED_LIBRARIES [shape=box]
   INCLUDED_PARTS -> BuildLibraryElementTask
@@ -101,7 +101,7 @@
   LIBRARY_CYCLE_UNITS -> ResolveInstanceFieldsInUnitTask
   LIBRARY_CYCLE_UNITS -> ResolveUnitTask
   LIBRARY_CYCLE_UNITS [shape=box]
-  LIBRARY_ELEMENT -> EvaluateUnitConstantsTask
+  LIBRARY_ELEMENT -> LibraryErrorsReadyTask
   LIBRARY_ELEMENT [shape=box]
   LIBRARY_ELEMENT1 -> BuildDirectiveElementsTask
   LIBRARY_ELEMENT1 -> ResolveVariableReferencesTask
@@ -121,13 +121,16 @@
   LIBRARY_ELEMENT5 -> PropagateVariableTypesInLibraryTask
   LIBRARY_ELEMENT5 -> ReadyLibraryElement5Task
   LIBRARY_ELEMENT5 -> ResolveInstanceFieldsInUnitTask
-  LIBRARY_ELEMENT5 -> ResolveLibraryReferencesTask
   LIBRARY_ELEMENT5 [shape=box]
   LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
   LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
   LIBRARY_ELEMENT6 [shape=box]
+  LIBRARY_ELEMENT7 -> ResolveLibraryReferencesTask
   LIBRARY_ELEMENT7 -> ResolveUnitTask
   LIBRARY_ELEMENT7 [shape=box]
+  LIBRARY_ELEMENT8 -> EvaluateUnitConstantsTask
+  LIBRARY_ELEMENT8 -> ResolveLibraryTask
+  LIBRARY_ELEMENT8 [shape=box]
   LIBRARY_ERRORS_READY [shape=box]
   LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
   LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
@@ -183,14 +186,12 @@
   READY_LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryClosureTask
   READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement6Task
   READY_LIBRARY_ELEMENT6 [shape=box]
-  READY_RESOLVED_UNIT -> ReadyResolvedUnitTask
+  READY_RESOLVED_UNIT -> ResolveLibraryTask
   READY_RESOLVED_UNIT -> VerifyUnitTask
   READY_RESOLVED_UNIT [shape=box]
   READY_RESOLVED_UNIT10 -> ReadyResolvedUnit10Task
-  READY_RESOLVED_UNIT10 -> ResolveLibraryReferencesTask
   READY_RESOLVED_UNIT10 [shape=box]
   READY_RESOLVED_UNIT11 -> ReadyResolvedUnit11Task
-  READY_RESOLVED_UNIT11 -> StrongModeVerifyUnitTask
   READY_RESOLVED_UNIT11 [shape=box]
   REFERENCED_NAMES [shape=box]
   RESOLVED_UNIT -> GenerateHintsTask
@@ -249,9 +250,11 @@
   ReadyResolvedUnit11Task -> READY_RESOLVED_UNIT11
   ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
   ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT8
-  ResolveLibraryReferencesTask -> LIBRARY_ELEMENT
+  ResolveLibraryReferencesTask -> LIBRARY_ELEMENT8
   ResolveLibraryReferencesTask -> REFERENCED_NAMES
+  ResolveLibraryTask -> LIBRARY_ELEMENT
   ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT5
+  ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
   ResolveUnitTask -> RESOLVED_UNIT10
   ResolveUnitTask -> RESOLVE_UNIT_ERRORS
   ResolveUnitTypeNamesTask -> RESOLVED_UNIT3
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index e48d78c..75cbe52 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -7,7 +7,8 @@
 import 'dart:collection';
 import 'dart:io';
 
-import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -29,10 +30,16 @@
 
 /// Analyzes single library [File].
 class AnalyzerImpl {
+  static final PerformanceTag _prepareErrorsTag =
+      new PerformanceTag("AnalyzerImpl.prepareErrors");
+  static final PerformanceTag _resolveLibraryTag =
+      new PerformanceTag("AnalyzerImpl._resolveLibrary");
+
   final CommandLineOptions options;
   final int startTime;
 
   final AnalysisContext context;
+
   final Source librarySource;
 
   /// All [Source]s references by the analyzed library.
@@ -59,7 +66,7 @@
     var status = ErrorSeverity.NONE;
     for (AnalysisErrorInfo errorInfo in errorInfos) {
       for (AnalysisError error in errorInfo.errors) {
-        if (!_isDesiredError(error)) {
+        if (_processError(error) == null) {
           continue;
         }
         var severity = computeSeverity(error, options);
@@ -121,11 +128,12 @@
 
   /// Fills [errorInfos] using [sources].
   void prepareErrors() {
-    for (Source source in sources) {
-      context.computeErrors(source);
-
-      errorInfos.add(context.getErrors(source));
-    }
+    return _prepareErrorsTag.makeCurrentWhile(() {
+      for (Source source in sources) {
+        context.computeErrors(source);
+        errorInfos.add(context.getErrors(source));
+      }
+    });
   }
 
   /// Fills [sources].
@@ -154,15 +162,13 @@
           "${librarySource.fullName} is a part and can not be analyzed.");
       return ErrorSeverity.ERROR;
     }
-    // Resolve library.
-    var libraryElement = context.computeLibraryElement(librarySource);
-    // Prepare source and errors.
+    var libraryElement = _resolveLibrary();
     prepareSources(libraryElement);
     prepareErrors();
 
     // Print errors and performance numbers.
     if (printMode == 1) {
-      _printErrorsAndPerf();
+      _printErrors();
     } else if (printMode == 2) {
       _printColdPerf();
     }
@@ -175,17 +181,6 @@
     return status;
   }
 
-  bool _isDesiredError(AnalysisError error) {
-    if (error.errorCode.type == ErrorType.TODO) {
-      return false;
-    }
-    if (computeSeverity(error, options) == ErrorSeverity.INFO &&
-        options.disableHints) {
-      return false;
-    }
-    return true;
-  }
-
   /// Determine whether the given URI refers to a package other than the package
   /// being analyzed.
   bool _isOtherPackage(Uri uri) {
@@ -215,7 +210,7 @@
     outSink.writeln("total-cold:$totalTime");
   }
 
-  _printErrorsAndPerf() {
+  _printErrors() {
     // The following is a hack. We currently print out to stderr to ensure that
     // when in batch mode we print to stderr, this is because the prints from
     // batch are made to stderr. The reason that options.shouldBatch isn't used
@@ -225,24 +220,70 @@
     StringSink sink = options.machineFormat ? errorSink : outSink;
 
     // Print errors.
-    ErrorFormatter formatter =
-        new ErrorFormatter(sink, options, _isDesiredError);
+    ErrorFormatter formatter = new ErrorFormatter(sink, options, _processError);
     formatter.formatErrors(errorInfos);
   }
 
+  /// Check various configuration options to get a desired severity for this
+  /// [error] (or `null` if it's to be suppressed).
+  ProcessedSeverity _processError(AnalysisError error) {
+    ErrorSeverity severity = computeSeverity(error, options, context);
+    bool isOverridden = false;
+
+    // First check for a filter.
+    if (severity == null) {
+      // Null severity means the error has been explicitly ignored.
+      return null;
+    } else {
+      isOverridden = true;
+    }
+
+    // If not overridden, some "natural" severities get globally filtered.
+    if (!isOverridden) {
+      // Check for global hint filtering.
+      if (severity == ErrorSeverity.INFO && options.disableHints) {
+        return null;
+      }
+
+      // Skip TODOs.
+      if (severity == ErrorType.TODO) {
+        return null;
+      }
+    }
+
+    return new ProcessedSeverity(severity, isOverridden);
+  }
+
+  LibraryElement _resolveLibrary() {
+    return _resolveLibraryTag.makeCurrentWhile(() {
+      return context.computeLibraryElement(librarySource);
+    });
+  }
+
   /// Compute the severity of the error; however:
   ///   * if [options.enableTypeChecks] is false, then de-escalate checked-mode
   ///   compile time errors to a severity of [ErrorSeverity.INFO].
   ///   * if [options.hintsAreFatal] is true, escalate hints to errors.
   static ErrorSeverity computeSeverity(
-      AnalysisError error, CommandLineOptions options) {
+      AnalysisError error, CommandLineOptions options,
+      [AnalysisContext context]) {
+    if (context != null) {
+      ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
+      // If there is a processor for this error, defer to it.
+      if (processor != null) {
+        return processor.severity;
+      }
+    }
+
     if (!options.enableTypeChecks &&
         error.errorCode.type == ErrorType.CHECKED_MODE_COMPILE_TIME_ERROR) {
       return ErrorSeverity.INFO;
     }
+
     if (options.hintsAreFatal && error.errorCode is HintCode) {
       return ErrorSeverity.ERROR;
     }
+
     return error.errorCode.errorSeverity;
   }
 
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index f69e935..0b6ae40 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -25,10 +25,13 @@
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_general.dart'
+    show PerformanceTag;
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/options.dart';
 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:linter/src/plugin/linter_plugin.dart';
 import 'package:package_config/discovery.dart' as pkgDiscovery;
 import 'package:package_config/packages.dart' show Packages;
@@ -39,10 +42,6 @@
 import 'package:plugin/plugin.dart';
 import 'package:yaml/yaml.dart';
 
-/// The maximum number of sources for which AST structures should be kept in the
-/// cache.
-const int _maxCacheSize = 512;
-
 /// Shared IO sink for standard error reporting.
 ///
 /// *Visible for testing.*
@@ -62,6 +61,9 @@
 typedef ErrorSeverity _BatchRunnerHandler(List<String> args);
 
 class Driver {
+  static final PerformanceTag _analyzeAllTag =
+      new PerformanceTag("Driver._analyzeAll");
+
   /// The plugins that are defined outside the `analyzer_cli` package.
   List<Plugin> _userDefinedPlugins = <Plugin>[];
 
@@ -88,6 +90,8 @@
 
   /// Use the given command-line [args] to start this analysis driver.
   void start(List<String> args) {
+    int startTime = new DateTime.now().millisecondsSinceEpoch;
+
     StringUtilities.INTERNER = new MappedInterner();
 
     _processPlugins();
@@ -111,10 +115,21 @@
         exitCode = severity.ordinal;
       }
     }
+
+    if (options.perfReport != null) {
+      String json = makePerfReport(startTime, currentTimeMillis(), options);
+      new File(options.perfReport).writeAsStringSync(json);
+    }
+  }
+
+  ErrorSeverity _analyzeAll(CommandLineOptions options) {
+    return _analyzeAllTag.makeCurrentWhile(() {
+      return _analyzeAllImpl(options);
+    });
   }
 
   /// Perform analysis according to the given [options].
-  ErrorSeverity _analyzeAll(CommandLineOptions options) {
+  ErrorSeverity _analyzeAllImpl(CommandLineOptions options) {
     if (!options.machineFormat) {
       outSink.writeln("Analyzing ${options.sourceFiles}...");
     }
@@ -410,7 +425,6 @@
 
     // Set context options.
     AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
-    contextOptions.cacheSize = _maxCacheSize;
     contextOptions.hint = !options.disableHints;
     contextOptions.enableStrictCallChecks = options.enableStrictCallChecks;
     contextOptions.enableSuperMixins = options.enableSuperMixins;
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index fe0f00f..0154d73 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -7,34 +7,45 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/options.dart';
 
-/// Allows any [AnalysisError].
-bool _anyError(AnalysisError error) => true;
+/// Returns the given error's severity.
+ProcessedSeverity _identity(AnalysisError error) =>
+    new ProcessedSeverity(error.errorCode.errorSeverity);
 
-/// Returns `true` if [AnalysisError] should be printed.
-typedef bool _ErrorFilter(AnalysisError error);
+/// Returns desired severity for the given [error] (or `null` if it's to be
+/// suppressed).
+typedef ProcessedSeverity _SeverityProcessor(AnalysisError error);
 
 /// Helper for formatting [AnalysisError]s.
-/// The two format options are a user consumable format and a machine consumable format.
+/// The two format options are a user consumable format and a machine consumable
+/// format.
 class ErrorFormatter {
   final StringSink out;
   final CommandLineOptions options;
-  final _ErrorFilter errorFilter;
+  final _SeverityProcessor processSeverity;
 
-  ErrorFormatter(this.out, this.options, [this.errorFilter = _anyError]);
+  ErrorFormatter(this.out, this.options, [this.processSeverity = _identity]);
+
+  /// Compute the severity for this [error] or `null` if this error should be
+  /// filtered.
+  ErrorSeverity computeSeverity(AnalysisError error) =>
+      processSeverity(error)?.severity;
 
   void formatError(
       Map<AnalysisError, LineInfo> errorToLine, AnalysisError error) {
     Source source = error.source;
     LineInfo_Location location = errorToLine[error].getLocation(error.offset);
     int length = error.length;
-    ErrorSeverity severity =
-        AnalyzerImpl.computeSeverity(error, options);
+
+    ProcessedSeverity processedSeverity = processSeverity(error);
+    ErrorSeverity severity = processedSeverity.severity;
+
     if (options.machineFormat) {
-      if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) {
-        severity = ErrorSeverity.ERROR;
+      if (!processedSeverity.overridden) {
+        if (severity == ErrorSeverity.WARNING && options.warningsAreFatal) {
+          severity = ErrorSeverity.ERROR;
+        }
       }
       out.write(severity);
       out.write('|');
@@ -52,11 +63,17 @@
       out.write('|');
       out.write(escapePipe(error.message));
     } else {
+      // Get display name.
       String errorType = severity.displayName;
-      if (error.errorCode.type == ErrorType.HINT ||
-          error.errorCode.type == ErrorType.LINT) {
-        errorType = error.errorCode.type.displayName;
+
+      // Translate INFOs into LINTS and HINTS.
+      if (severity == ErrorSeverity.INFO) {
+        if (error.errorCode.type == ErrorType.HINT ||
+            error.errorCode.type == ErrorType.LINT) {
+          errorType = error.errorCode.type.displayName;
+        }
       }
+
       // [warning] 'foo' is not a... (/Users/.../tmp/foo.dart, line 1, col 2)
       out.write('[$errorType] ${error.message} ');
       out.write('(${source.fullName}');
@@ -70,7 +87,7 @@
     var errorToLine = new Map<AnalysisError, LineInfo>();
     for (AnalysisErrorInfo errorInfo in errorInfos) {
       for (AnalysisError error in errorInfo.errors) {
-        if (errorFilter(error)) {
+        if (computeSeverity(error) != null) {
           errors.add(error);
           errorToLine[error] = errorInfo.lineInfo;
         }
@@ -79,10 +96,8 @@
     // Sort errors.
     errors.sort((AnalysisError error1, AnalysisError error2) {
       // Severity.
-      ErrorSeverity severity1 =
-          AnalyzerImpl.computeSeverity(error1, options);
-      ErrorSeverity severity2 =
-          AnalyzerImpl.computeSeverity(error2, options);
+      ErrorSeverity severity1 = computeSeverity(error1);
+      ErrorSeverity severity2 = computeSeverity(error2);
       int compare = severity2.compareTo(severity1);
       if (compare != 0) {
         return compare;
@@ -102,12 +117,14 @@
     int hintCount = 0;
     int lintCount = 0;
     for (AnalysisError error in errors) {
-      ErrorSeverity severity =
-          AnalyzerImpl.computeSeverity(error, options);
+      ProcessedSeverity processedSeverity = processSeverity(error);
+      ErrorSeverity severity = processedSeverity.severity;
       if (severity == ErrorSeverity.ERROR) {
         errorCount++;
       } else if (severity == ErrorSeverity.WARNING) {
-        if (options.warningsAreFatal) {
+        /// Only treat a warning as an error if it's not been set by a
+        /// proccesser.
+        if (!processedSeverity.overridden && options.warningsAreFatal) {
           errorCount++;
         } else {
           warnCount++;
@@ -194,3 +211,10 @@
     }
   }
 }
+
+/// A severity with awareness of whether it was overriden by a processor.
+class ProcessedSeverity {
+  ErrorSeverity severity;
+  bool overridden;
+  ProcessedSeverity(this.severity, [this.overridden = false]);
+}
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index ee683e2..2bc48b9 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -17,7 +17,7 @@
 /// *Visible for testing.*
 ExitHandler exitHandler = exit;
 
-/// Print the given message to stderr and exit with the given [exitCode]
+/// Print the given [message] to stderr and exit with the given [exitCode].
 void printAndFail(String message, {int exitCode: 15}) {
   errorSink.writeln(message);
   exitHandler(exitCode);
@@ -80,6 +80,10 @@
   /// The path to a `.packages` configuration file
   final String packageConfigPath;
 
+  /// The path to a file to write a performance log.
+  /// (Or null if not enabled.)
+  final String perfReport;
+
   /// Batch mode (for unit testing)
   final bool shouldBatch;
 
@@ -117,6 +121,7 @@
         machineFormat = args['machine'] || args['format'] == 'machine',
         packageConfigPath = args['packages'],
         packageRootPath = args['package-root'],
+        perfReport = args['x-perf-report'],
         shouldBatch = args['batch'],
         showPackageWarnings =
             args['show-package-warnings'] || args['package-warnings'],
@@ -146,10 +151,12 @@
       // Check that SDK is specified.
       if (sdkPath == null) {
         printAndFail('No Dart SDK found.');
+        return null; // Only reachable in testing.
       }
       // Check that SDK is existing directory.
       if (!(new Directory(sdkPath)).existsSync()) {
         printAndFail('Invalid Dart SDK path: $sdkPath');
+        return null; // Only reachable in testing.
       }
     }
 
@@ -158,13 +165,15 @@
       if (options.packageRootPath != null &&
           options.packageConfigPath != null) {
         printAndFail("Cannot specify both '--package-root' and '--packages.");
+        return null; // Only reachable in testing.
       }
     }
 
     // OK.  Report deprecated options.
     if (options.enableNullAwareOperators) {
-      stderr.writeln(
-          "Info: Option '--enable-null-aware-operators' is no longer needed. Null aware operators are supported by default.");
+      errorSink.writeln(
+          "Info: Option '--enable-null-aware-operators' is no longer needed. "
+          "Null aware operators are supported by default.");
     }
 
     return options;
@@ -194,11 +203,13 @@
       ..addOption('dart-sdk', help: 'The path to the Dart SDK.')
       ..addOption('packages',
           help:
-              'Path to the package resolution configuration file, which supplies a mapping of package names to paths.  This option cannot be used with --package-root.')
+              'Path to the package resolution configuration file, which supplies '
+              'a mapping of package names to paths.  This option cannot be '
+              'used with --package-root.')
       ..addOption('package-root',
           abbr: 'p',
-          help:
-              'Path to a package root directory (deprecated). This option cannot be used with --packages.')
+          help: 'Path to a package root directory (deprecated). This option '
+              'cannot be used with --packages.')
       ..addOption('options', help: 'Path to an analysis options file.')
       ..addOption('format',
           help: 'Specifies the format in which errors are displayed.')
@@ -242,6 +253,8 @@
           help: 'Show warnings from SDK imports (deprecated).',
           defaultsTo: false,
           negatable: false)
+      ..addOption('x-perf-report',
+          help: 'Writes a performance report to the given file (experimental).')
       ..addFlag('help',
           abbr: 'h',
           help: 'Display this help message.',
@@ -308,45 +321,50 @@
       // Help requests.
       if (results['help']) {
         _showUsage(parser);
-        exit(0);
+        exitHandler(0);
+        return null; // Only reachable in testing.
       }
       // Batch mode and input files.
       if (results['batch']) {
         if (results.rest.isNotEmpty) {
-          stderr.writeln('No source files expected in the batch mode.');
+          errorSink.writeln('No source files expected in the batch mode.');
           _showUsage(parser);
-          exit(15);
+          exitHandler(15);
+          return null; // Only reachable in testing.
         }
       } else if (results['version']) {
-        print('$_binaryName version ${_getVersion()}');
-        exit(0);
+        outSink.write('$_binaryName version ${_getVersion()}');
+        exitHandler(0);
+        return null; // Only reachable in testing.
       } else {
         if (results.rest.isEmpty) {
           _showUsage(parser);
-          exit(15);
+          exitHandler(15);
+          return null; // Only reachable in testing.
         }
       }
       return new CommandLineOptions._fromArgs(results, definedVariables);
     } on FormatException catch (e) {
-      stderr.writeln(e.message);
+      errorSink.writeln(e.message);
       _showUsage(parser);
-      exit(15);
+      exitHandler(15);
+      return null; // Only reachable in testing.
     }
   }
 
   static _showUsage(parser) {
-    stderr
+    errorSink
         .writeln('Usage: $_binaryName [options...] <libraries to analyze...>');
-    stderr.writeln(parser.getUsage());
-    stderr.writeln('');
-    stderr.writeln(
+    errorSink.writeln(parser.getUsage());
+    errorSink.writeln('');
+    errorSink.writeln(
         'For more information, see http://www.dartlang.org/tools/analyzer.');
   }
 }
 
 /// Commandline argument parser.
 ///
-/// TODO(pquitslund): when the args package supports ignoring unrecognized
+/// TODO(pq): when the args package supports ignoring unrecognized
 /// options/flags, this class can be replaced with a simple [ArgParser]
 /// instance.
 class CommandLineParser {
diff --git a/pkg/analyzer_cli/lib/src/perf_report.dart b/pkg/analyzer_cli/lib/src/perf_report.dart
new file mode 100644
index 0000000..03791d8
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/perf_report.dart
@@ -0,0 +1,82 @@
+// 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_cli.src.perf_report;
+
+import 'dart:convert' show JsonEncoder;
+import 'dart:io' show File, Platform;
+
+import 'package:analyzer/src/generated/utilities_general.dart'
+    show PerformanceTag;
+import 'package:analyzer_cli/src/options.dart' show CommandLineOptions;
+
+const _JSON = const JsonEncoder.withIndent("  ");
+
+bool _isCheckedMode = () {
+  bool x = true;
+  try {
+    // Trigger an exception if we're in checked mode.
+    x = "" as dynamic;
+    return x != ""; // return false; suppress unused variable warning
+  } catch (e) {
+    return true;
+  }
+}();
+
+String _osType = () {
+  if (Platform.isLinux) {
+    return "linux";
+  } else if (Platform.isMacOS) {
+    return "mac";
+  } else if (Platform.isWindows) {
+    return "windows";
+  } else if (Platform.isAndroid) {
+    return "android";
+  } else {
+    return "unknown";
+  }
+}();
+
+String makePerfReport(int startTime, int endTime, CommandLineOptions options) {
+  int totalTime = endTime - startTime;
+  int otherTime = totalTime;
+
+  var platformJson = <String, dynamic>{
+    'osType': _osType,
+    'dartSdkVersion': Platform.version,
+    'checkedMode': _isCheckedMode,
+  };
+
+  var optionsJson = <String, dynamic>{
+    'dartSdkPath': options.dartSdkPath,
+    'strongMode': options.strongMode,
+    'showPackageWarnings': options.showPackageWarnings,
+    'showSdkWarnings': options.showSdkWarnings,
+    'definedVariables': options.definedVariables,
+    'packageRootPath': options.packageRootPath,
+    'packageConfigPath': options.packageConfigPath,
+    'sourceFiles': options.sourceFiles,
+  };
+
+  // Convert performance tags to JSON representation.
+  var perfTagsJson = <String, dynamic>{};
+  for (PerformanceTag tag in PerformanceTag.all) {
+    if (tag != PerformanceTag.UNKNOWN) {
+      int tagTime = tag.elapsedMs;
+      perfTagsJson[tag.label] = tagTime;
+      otherTime -= tagTime;
+    }
+  }
+  perfTagsJson['other'] = otherTime;
+
+  var json = <String, dynamic>{
+    'perfReportVersion': 0,
+    'platform': platformJson,
+    'options': optionsJson,
+    'totalElapsedTime': totalTime,
+    'performanceTags': perfTagsJson
+  };
+
+  return _JSON.convert(json);
+}
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index bc255ee..0fe04f6 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -6,10 +6,10 @@
 environment:
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
-  analyzer: ^0.26.1+17
+  analyzer: ^0.27.0
   args: ^0.13.0
   cli_util: ^0.0.1
-  linter: ^0.1.3+4
+  linter: ^0.1.10
   package_config: ^0.1.1
   plugin: ^0.1.0
   yaml: ^2.1.2
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index 03f1b14..ea55810 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -2,23 +2,25 @@
 // 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 'driver_test.dart' as driver;
 import 'error_test.dart' as error;
 import 'options_test.dart' as options;
+import 'perf_report_test.dart' as perf;
 import 'plugin_manager_test.dart' as plugin_manager;
 import 'reporter_test.dart' as reporter;
 import 'super_mixin_test.dart' as super_mixin;
-//import 'driver_test.dart' as driver;
 //import 'sdk_ext_test.dart' as sdk_ext;
 //import 'strong_mode_test.dart' as strong_mode;
 
 main() {
+  driver.main();
   // TODO(pq): fix tests to run safely on the bots
   // https://github.com/dart-lang/sdk/issues/25001
-  //driver.main();
   //sdk_ext.main();
   //strong_mode.main();
   error.main();
   options.main();
+  perf.main();
   plugin_manager.main();
   reporter.main();
   super_mixin.main();
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
index ebd4e64..1d2a841 100644
--- a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
+++ b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
@@ -1,5 +1,7 @@
 analyzer:
   errors:
     unused_local_variable: ignore
+    missing_return: error
+    undefined_function: warning
   language:
     enableSuperMixins: true
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart b/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart
index e8f168b..2bccf65 100644
--- a/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart
+++ b/pkg/analyzer_cli/test/data/options_tests_project/test_file.dart
@@ -4,4 +4,10 @@
 
 library analyzer_cli.test.data.options_test_project.test_file;
 
-class a {}
+
+int foo() {
+
+  baz(); // Undefined function.
+
+  // Missing return
+}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index e6bd812..d85b818 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -8,6 +8,7 @@
 
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -21,37 +22,39 @@
 import 'package:unittest/unittest.dart';
 import 'package:yaml/src/yaml_node.dart';
 
-// TODO(pq): fix tests to run safely on the bots
-// https://github.com/dart-lang/sdk/issues/25001
-main() {}
-const emptyOptionsFile = 'test/data/empty_options.yaml';
+import 'utils.dart';
 
-/// Start a driver for the given [source], optionally providing additional
-/// [args] and an [options] file path.  The value of [options] defaults to
-/// an empty options file to avoid unwanted configuration from an otherwise
-/// discovered options file.
-void drive(String source,
-        {String options: emptyOptionsFile,
-        List<String> args: const <String>[]}) =>
-    new Driver().start(['--options', options, source]..addAll(args));
+main() {
+  StringSink savedOutSink, savedErrorSink;
+  int savedExitCode;
+  ExitHandler savedExitHandler;
 
-not_main() {
+  /// Base setup.
+  _setUp() {
+    savedOutSink = outSink;
+    savedErrorSink = errorSink;
+    savedExitHandler = exitHandler;
+    savedExitCode = exitCode;
+    exitHandler = (code) => exitCode = code;
+    outSink = new StringBuffer();
+    errorSink = new StringBuffer();
+  }
+
+  /// Base teardown.
+  _tearDown() {
+    outSink = savedOutSink;
+    errorSink = savedErrorSink;
+    exitCode = savedExitCode;
+    exitHandler = savedExitHandler;
+  }
+
+  setUp(() => _setUp());
+
+  tearDown(() => _tearDown());
+
+  initializeTestEnvironment();
+
   group('Driver', () {
-    StringSink savedOutSink, savedErrorSink;
-    int savedExitCode;
-    setUp(() {
-      savedOutSink = outSink;
-      savedErrorSink = errorSink;
-      savedExitCode = exitCode;
-      outSink = new StringBuffer();
-      errorSink = new StringBuffer();
-    });
-    tearDown(() {
-      outSink = savedOutSink;
-      errorSink = savedErrorSink;
-      exitCode = savedExitCode;
-    });
-
     group('options', () {
       test('custom processor', () {
         Driver driver = new Driver();
@@ -59,8 +62,8 @@
         driver.userDefinedPlugins = [new TestPlugin(processor)];
         driver.start([
           '--options',
-          'test/data/test_options.yaml',
-          'test/data/test_file.dart'
+          path.join(testDirectory, 'data/test_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
         ]);
         expect(processor.options['test_plugin'], isNotNull);
         expect(processor.exception, isNull);
@@ -68,70 +71,51 @@
     });
 
     group('exit codes', () {
-      StringSink savedOutSink, savedErrorSink;
-      int savedExitCode;
-      ExitHandler savedExitHandler;
-      setUp(() {
-        savedOutSink = outSink;
-        savedErrorSink = errorSink;
-        savedExitCode = exitCode;
-        savedExitHandler = exitHandler;
-        exitHandler = (code) => exitCode = code;
-        outSink = new StringBuffer();
-        errorSink = new StringBuffer();
-      });
-      tearDown(() {
-        outSink = savedOutSink;
-        errorSink = savedErrorSink;
-        exitCode = savedExitCode;
-        exitHandler = savedExitHandler;
-      });
-
       test('fatal hints', () {
-        drive('test/data/file_with_hint.dart', args: ['--fatal-hints']);
+        drive('data/file_with_hint.dart', args: ['--fatal-hints']);
         expect(exitCode, 3);
       });
 
       test('not fatal hints', () {
-        drive('test/data/file_with_hint.dart');
+        drive('data/file_with_hint.dart');
         expect(exitCode, 0);
       });
 
       test('fatal errors', () {
-        drive('test/data/file_with_error.dart');
+        drive('data/file_with_error.dart');
         expect(exitCode, 3);
       });
 
       test('not fatal warnings', () {
-        drive('test/data/file_with_warning.dart');
+        drive('data/file_with_warning.dart');
         expect(exitCode, 0);
       });
 
       test('fatal warnings', () {
-        drive('test/data/file_with_warning.dart', args: ['--fatal-warnings']);
+        drive('data/file_with_warning.dart', args: ['--fatal-warnings']);
         expect(exitCode, 3);
       });
 
       test('missing options file', () {
-        drive('test/data/test_file.dart', options: 'test/data/NO_OPTIONS_HERE');
+        drive('data/test_file.dart', options: 'data/NO_OPTIONS_HERE');
         expect(exitCode, 3);
       });
 
       test('missing dart file', () {
-        drive('test/data/NO_DART_FILE_HERE.dart');
+        drive('data/NO_DART_FILE_HERE.dart');
         expect(exitCode, 3);
       });
 
       test('part file', () {
-        drive('test/data/library_and_parts/part2.dart');
+        drive('data/library_and_parts/part2.dart');
         expect(exitCode, 3);
       });
 
       test('non-dangling part file', () {
         Driver driver = new Driver();
         driver.start([
-          'test/data/library_and_parts/lib.dart',
-          'test/data/library_and_parts/part1.dart',
+          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part1.dart')
         ]);
         expect(exitCode, 0);
       });
@@ -139,9 +123,9 @@
       test('extra part file', () {
         Driver driver = new Driver();
         driver.start([
-          'test/data/library_and_parts/lib.dart',
-          'test/data/library_and_parts/part1.dart',
-          'test/data/library_and_parts/part2.dart',
+          path.join(testDirectory, 'data/library_and_parts/lib.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part1.dart'),
+          path.join(testDirectory, 'data/library_and_parts/part2.dart')
         ]);
         expect(exitCode, 3);
       });
@@ -149,26 +133,14 @@
 
     group('linter', () {
       group('lints in options', () {
-        StringSink savedOutSink;
-        Driver driver;
-
-        setUp(() {
-          savedOutSink = outSink;
-          outSink = new StringBuffer();
-
-          driver = new Driver();
-          driver.start([
-            '--options',
-            'test/data/linter_project/.analysis_options',
-            '--lints',
-            'test/data/linter_project/test_file.dart'
-          ]);
-        });
-        tearDown(() {
-          outSink = savedOutSink;
-        });
+        // Shared lint command.
+        var runLinter = () => drive('data/linter_project/test_file.dart',
+            options: 'data/linter_project/.analysis_options',
+            args: ['--lints']);
 
         test('gets analysis options', () {
+          runLinter();
+
           /// Lints should be enabled.
           expect(driver.context.analysisOptions.lint, isTrue);
 
@@ -178,32 +150,21 @@
         });
 
         test('generates lints', () {
+          runLinter();
           expect(outSink.toString(),
               contains('[lint] Name types using UpperCamelCase.'));
         });
       });
 
       group('default lints', () {
-        StringSink savedOutSink;
-        Driver driver;
-
-        setUp(() {
-          savedOutSink = outSink;
-          outSink = new StringBuffer();
-
-          driver = new Driver();
-          driver.start([
-            '--lints',
-            'test/data/linter_project/test_file.dart',
-            '--options',
-            'test/data/linter_project/.analysis_options'
-          ]);
-        });
-        tearDown(() {
-          outSink = savedOutSink;
-        });
+        // Shared lint command.
+        var runLinter = () => drive('data/linter_project/test_file.dart',
+            options: 'data/linter_project/.analysis_options',
+            args: ['--lints']);
 
         test('gets default lints', () {
+          runLinter();
+
           /// Lints should be enabled.
           expect(driver.context.analysisOptions.lint, isTrue);
 
@@ -213,39 +174,29 @@
         });
 
         test('generates lints', () {
+          runLinter();
           expect(outSink.toString(),
               contains('[lint] Name types using UpperCamelCase.'));
         });
       });
 
       group('no `--lints` flag (none in options)', () {
-        StringSink savedOutSink;
-        Driver driver;
-
-        setUp(() {
-          savedOutSink = outSink;
-          outSink = new StringBuffer();
-
-          driver = new Driver();
-          driver.start([
-            'test/data/no_lints_project/test_file.dart',
-            '--options',
-            'test/data/no_lints_project/.analysis_options'
-          ]);
-        });
-        tearDown(() {
-          outSink = savedOutSink;
-        });
+        // Shared lint command.
+        var runLinter = () => drive('data/no_lints_project/test_file.dart',
+            options: 'data/no_lints_project/.analysis_options');
 
         test('lints disabled', () {
+          runLinter();
           expect(driver.context.analysisOptions.lint, isFalse);
         });
 
         test('no registered lints', () {
+          runLinter();
           expect(getLints(driver.context), isEmpty);
         });
 
         test('no generated warnings', () {
+          runLinter();
           expect(outSink.toString(), contains('No issues found'));
         });
       });
@@ -277,129 +228,137 @@
     });
 
     group('options processing', () {
-      group('error filters', () {
-        StringSink savedOutSink;
-        Driver driver;
-
-        setUp(() {
-          savedOutSink = outSink;
-          outSink = new StringBuffer();
-
-          driver = new Driver();
-          driver.start([
-            'test/data/options_tests_project/test_file.dart',
-            '--options',
-            'test/data/options_tests_project/.analysis_options'
-          ]);
-        });
-        tearDown(() {
-          outSink = savedOutSink;
-        });
+      group('basic config', () {
+        // Shared driver command.
+        var doDrive = () => drive('data/options_tests_project/test_file.dart',
+            options: 'data/options_tests_project/.analysis_options');
 
         test('filters', () {
-          var processors =
-              driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
-          expect(processors, hasLength(1));
+          doDrive();
+          expect(processors, hasLength(3));
 
+          // unused_local_variable: ignore
           var unused_local_variable = new AnalysisError(
               new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
             ['x']
           ]);
+          expect(processorFor(unused_local_variable).severity, isNull);
 
-          var unusedLocalVariable =
-              processors.firstWhere((p) => p.appliesTo(unused_local_variable));
-          expect(unusedLocalVariable.severity, isNull);
+          // missing_return: error
+          var missing_return = new AnalysisError(
+              new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+            ['x']
+          ]);
+          expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
+          expect(
+              outSink.toString(),
+              contains(
+                  "[error] This function declares a return type of 'int'"));
+          expect(outSink.toString(),
+              contains("1 error and 1 warning found."));
         });
 
-        test('language config', () {
+        test('language', () {
+          doDrive();
           expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
         });
       });
+
+      group('with flags', () {
+        // Shared driver command.
+        var doDrive = () => drive('data/options_tests_project/test_file.dart',
+            args: ['--fatal-warnings'],
+            options: 'data/options_tests_project/.analysis_options');
+
+        test('override fatal warning', () {
+          doDrive();
+          // missing_return: error
+          var undefined_function = new AnalysisError(new TestSource(), 0, 1,
+              StaticTypeWarningCode.UNDEFINED_FUNCTION, [
+            ['x']
+          ]);
+          expect(
+              processorFor(undefined_function).severity, ErrorSeverity.WARNING);
+          // Should not be made fatal by `--fatal-warnings`.
+          expect(outSink.toString(),
+              contains("[warning] The function 'baz' is not defined"));
+          expect(outSink.toString(),
+              contains("1 error and 1 warning found."));
+        });
+      });
     });
 
-    group('in temp directory', () {
-      StringSink savedOutSink, savedErrorSink;
-      int savedExitCode;
-      Directory savedCurrentDirectory;
-      Directory tempDir;
-      setUp(() {
-        savedOutSink = outSink;
-        savedErrorSink = errorSink;
-        savedExitCode = exitCode;
-        outSink = new StringBuffer();
-        errorSink = new StringBuffer();
-        savedCurrentDirectory = Directory.current;
-        tempDir = Directory.systemTemp.createTempSync('analyzer_');
-      });
-      tearDown(() {
-        outSink = savedOutSink;
-        errorSink = savedErrorSink;
-        exitCode = savedExitCode;
-        Directory.current = savedCurrentDirectory;
-        tempDir.deleteSync(recursive: true);
-      });
-
-      test('packages folder', () {
-        Directory.current = tempDir;
-        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
-import 'package:foo/bar.dart';
-main() {
-  baz();
-}
-        ''');
-        Directory packagesDir =
-            new Directory(path.join(tempDir.path, 'packages'));
-        packagesDir.createSync();
-        Directory fooDir = new Directory(path.join(packagesDir.path, 'foo'));
-        fooDir.createSync();
-        new File(path.join(fooDir.path, 'bar.dart')).writeAsStringSync('''
-void baz() {}
-        ''');
-        new Driver().start(['test.dart']);
-        expect(exitCode, 0);
-      });
-
-      test('no package resolution', () {
-        Directory.current = tempDir;
-        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
-import 'package:path/path.dart';
-main() {}
-        ''');
-        new Driver().start(['test.dart']);
-        expect(exitCode, 3);
-        String stdout = outSink.toString();
-        expect(stdout, contains('[error] Target of URI does not exist'));
-        expect(stdout, contains('1 error found.'));
-        expect(errorSink.toString(), '');
-      });
-
-      test('bad package root', () {
-        new Driver().start(['--package-root', 'does/not/exist', 'test.dart']);
-        String stdout = outSink.toString();
-        expect(exitCode, 3);
-        expect(
-            stdout,
-            contains(
-                'Package root directory (does/not/exist) does not exist.'));
-      });
-    });
+//TODO(pq): fix to be bot-friendly (sdk#25258).
+//    group('in temp directory', () {
+//      Directory savedCurrentDirectory;
+//      Directory tempDir;
+//      setUp(() {
+//        // Call base setUp.
+//        _setUp();
+//        savedCurrentDirectory = Directory.current;
+//        tempDir = Directory.systemTemp.createTempSync('analyzer_');
+//      });
+//      tearDown(() {
+//        Directory.current = savedCurrentDirectory;
+//        tempDir.deleteSync(recursive: true);
+//        // Call base tearDown.
+//        _tearDown();
+//      });
+//
+//      test('packages folder', () {
+//        Directory.current = tempDir;
+//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
+//import 'package:foo/bar.dart';
+//main() {
+//  baz();
+//}
+//        ''');
+//        Directory packagesDir =
+//            new Directory(path.join(tempDir.path, 'packages'));
+//        packagesDir.createSync();
+//        Directory fooDir = new Directory(path.join(packagesDir.path, 'foo'));
+//        fooDir.createSync();
+//        new File(path.join(fooDir.path, 'bar.dart')).writeAsStringSync('''
+//void baz() {}
+//        ''');
+//        new Driver().start(['test.dart']);
+//        expect(exitCode, 0);
+//      });
+//
+//      test('no package resolution', () {
+//        Directory.current = tempDir;
+//        new File(path.join(tempDir.path, 'test.dart')).writeAsStringSync('''
+//import 'package:path/path.dart';
+//main() {}
+//        ''');
+//        new Driver().start(['test.dart']);
+//        expect(exitCode, 3);
+//        String stdout = outSink.toString();
+//        expect(stdout, contains('[error] Target of URI does not exist'));
+//        expect(stdout, contains('1 error found.'));
+//        expect(errorSink.toString(), '');
+//      });
+//
+//      test('bad package root', () {
+//        new Driver().start(['--package-root', 'does/not/exist', 'test.dart']);
+//        String stdout = outSink.toString();
+//        expect(exitCode, 3);
+//        expect(
+//            stdout,
+//            contains(
+//                'Package root directory (does/not/exist) does not exist.'));
+//      });
+//    });
   });
+
   group('Bootloader', () {
     group('plugin processing', () {
-      StringSink savedErrorSink;
-      setUp(() {
-        savedErrorSink = errorSink;
-        errorSink = new StringBuffer();
-      });
-      tearDown(() {
-        errorSink = savedErrorSink;
-      });
       test('bad format', () {
         BootLoader loader = new BootLoader();
         loader.createImage([
           '--options',
-          'test/data/bad_plugin_options.yaml',
-          'test/data/test_file.dart'
+          path.join(testDirectory, 'data/bad_plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
         ]);
         expect(
             errorSink.toString(),
@@ -411,8 +370,8 @@
         BootLoader loader = new BootLoader();
         Image image = loader.createImage([
           '--options',
-          'test/data/plugin_options.yaml',
-          'test/data/test_file.dart'
+          path.join(testDirectory, 'data/plugin_options.yaml'),
+          path.join(testDirectory, 'data/test_file.dart')
         ]);
         var plugins = image.config.plugins;
         expect(plugins, hasLength(1));
@@ -444,6 +403,32 @@
   });
 }
 
+const emptyOptionsFile = 'data/empty_options.yaml';
+
+/// Shared driver.
+Driver driver;
+
+List<ErrorProcessor> get processors =>
+    driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
+ErrorProcessor processorFor(AnalysisError error) =>
+    processors.firstWhere((p) => p.appliesTo(error));
+
+/// Start a driver for the given [source], optionally providing additional
+/// [args] and an [options] file path.  The value of [options] defaults to
+/// an empty options file to avoid unwanted configuration from an otherwise
+/// discovered options file.
+void drive(String source,
+    {String options: emptyOptionsFile, List<String> args: const <String>[]}) {
+  driver = new Driver();
+  var cmd = [
+    '--options',
+    path.join(testDirectory, options),
+    path.join(testDirectory, source)
+  ]..addAll(args);
+  driver.start(cmd);
+}
+
 Map<String, YamlNode> parseOptions(String src) =>
     new AnalysisOptionsProvider().getOptionsFromString(src);
 
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
new file mode 100644
index 0000000..f668485
--- /dev/null
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -0,0 +1,22 @@
+// 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_cli.test.perf_report;
+
+import 'dart:convert' show JSON;
+
+import 'package:analyzer_cli/src/options.dart';
+import 'package:analyzer_cli/src/perf_report.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  test('makePerfReport', () {
+    var options = CommandLineOptions.parse(["somefile.dart"]);
+    var encoded = makePerfReport(1000, 1234, options);
+
+    var json = JSON.decode(encoded);
+    expect(json['totalElapsedTime'], 234);
+    expect(json['options']['sourceFiles'], ["somefile.dart"]);
+  });
+}
diff --git a/pkg/analyzer_cli/test/utils.dart b/pkg/analyzer_cli/test/utils.dart
index 25779ab..07dbe4b 100644
--- a/pkg/analyzer_cli/test/utils.dart
+++ b/pkg/analyzer_cli/test/utils.dart
@@ -8,7 +8,16 @@
 import 'dart:mirrors';
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/java_io.dart';
 import 'package:path/path.dart' as pathos;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+/// Gets the test directory in a way that works with
+/// package:test and package:unittest.
+/// See <https://github.com/dart-lang/test/issues/110> for more info.
+final String testDirectory = pathos.dirname(
+    pathos.fromUri((reflectClass(_TestUtils).owner as LibraryMirror).uri));
 
 /// Returns the string representation of the [AnalyzerErrorGroup] thrown when
 /// parsing [contents] as a Dart file. If [contents] doesn't throw any errors,
@@ -34,6 +43,12 @@
   });
 }
 
+/// Test env setup (copied from `analyzer/test/utils.dart`).
+void initializeTestEnvironment() {
+  groupSep = ' | ';
+  JavaFile.pathContext = path.posix;
+}
+
 /// Creates a temporary directory and passes its path to [fn]. Once [fn]
 /// completes, the temporary directory and all its contents will be deleted.
 ///
@@ -47,10 +62,4 @@
   }
 }
 
-/// Gets the test directory in a way that works with
-/// package:test and package:unittest.
-/// See <https://github.com/dart-lang/test/issues/110> for more info.
-final String testDirectory = pathos.dirname(
-    pathos.fromUri((reflectClass(_TestUtils).owner as LibraryMirror).uri));
-
 class _TestUtils {}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 71a2d67..2c3c9a2 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -126,8 +126,8 @@
                 fatalWarnings: hasOption(options, Flags.fatalWarnings),
                 suppressHints: hasOption(options, Flags.suppressHints),
                 terseDiagnostics: hasOption(options, Flags.terse),
-                showPackageWarnings:
-                    hasOption(options, Flags.showPackageWarnings)),
+                shownPackageWarnings: extractOptionalCsvOption(
+                      options, Flags.showPackageWarnings)),
             enableExperimentalMirrors:
                 hasOption(options, Flags.enableExperimentalMirrors),
             enableAssertMessage:
@@ -191,6 +191,23 @@
     return const <String>[];
   }
 
+  /// Extract list of comma separated values provided for [flag]. Returns an
+  /// empty list if [option] contain [flag] without arguments. Returns `null` if
+  /// [option] doesn't contain [flag] with or without arguments.
+  static List<String> extractOptionalCsvOption(
+      List<String> options, String flag) {
+    String prefix = '$flag=';
+    for (String option in options) {
+      if (option == flag) {
+        return const <String>[];
+      }
+      if (option.startsWith(flag)) {
+        return option.substring(prefix.length).split(',');
+      }
+    }
+    return null;
+  }
+
   static Uri resolvePlatformConfig(Uri libraryRoot,
                                    List<String> options) {
     String platformConfigPath =
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index f200ebc..fdb8ca2 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -50,3 +50,8 @@
   // Experimental flags.
   static const String conditionalDirectives = '--conditional-directives';
 }
+
+class Option {
+  static const String showPackageWarnings =
+      '${Flags.showPackageWarnings}|${Flags.showPackageWarnings}=.*';
+}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 3b98b92..ceb9143 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1250,6 +1250,32 @@
     _reporter.onCrashInUserCode(message, exception, stackTrace);
   }
 
+  /// Messages for which compile-time errors are reported but compilation
+  /// continues regardless.
+  static const List<MessageKind> BENIGN_ERRORS = const <MessageKind>[
+      MessageKind.INVALID_METADATA,
+      MessageKind.INVALID_METADATA_GENERIC,
+  ];
+
+  bool markCompilationAsFailed(DiagnosticMessage message, api.Diagnostic kind) {
+    if (testMode) {
+      // When in test mode, i.e. on the build-bot, we always stop compilation.
+      return true;
+    }
+    if (reporter.options.fatalWarnings) {
+      return true;
+    }
+    return !BENIGN_ERRORS.contains(message.message.kind);
+  }
+
+  void fatalDiagnosticReported(DiagnosticMessage message,
+                               List<DiagnosticMessage> infos,
+                               api.Diagnostic kind) {
+    if (markCompilationAsFailed(message, kind)) {
+      compilationFailed = true;
+    }
+  }
+
   /**
    * Translates the [resolvedUri] into a readable URI.
    *
@@ -1668,7 +1694,7 @@
   void reportDiagnosticInternal(DiagnosticMessage message,
                                 List<DiagnosticMessage> infos,
                                 api.Diagnostic kind) {
-    if (!options.showPackageWarnings &&
+    if (!options.showAllPackageWarnings &&
         message.spannable != NO_LOCATION_SPANNABLE) {
       switch (kind) {
       case api.Diagnostic.WARNING:
@@ -1676,6 +1702,10 @@
         Element element = elementFromSpannable(message.spannable);
         if (!compiler.inUserCode(element, assumeInUserCode: true)) {
           Uri uri = compiler.getCanonicalUri(element);
+          if (options.showPackageWarningsFor(uri)) {
+            reportDiagnostic(message, infos, kind);
+            return;
+          }
           SuppressionInfo info =
               suppressedWarnings.putIfAbsent(uri, () => new SuppressionInfo());
           if (kind == api.Diagnostic.WARNING) {
@@ -1701,13 +1731,13 @@
   void reportDiagnostic(DiagnosticMessage message,
                         List<DiagnosticMessage> infos,
                         api.Diagnostic kind) {
+    compiler.reportDiagnostic(message, infos, kind);
     if (kind == api.Diagnostic.ERROR ||
         kind == api.Diagnostic.CRASH ||
         (options.fatalWarnings &&
          kind == api.Diagnostic.WARNING)) {
-      compiler.compilationFailed = true;
+      compiler.fatalDiagnosticReported(message, infos, kind);
     }
-    compiler.reportDiagnostic(message, infos, kind);
   }
 
   /**
@@ -1762,6 +1792,67 @@
     }
     if (uri == null && currentElement != null) {
       uri = currentElement.compilationUnit.script.resourceUri;
+      assert(invariant(currentElement, () {
+
+        /// Check that [begin] and [end] can be found between [from] and [to].
+        validateToken(Token from, Token to) {
+          if (from == null || to == null) return true;
+          bool foundBegin = false;
+          bool foundEnd = false;
+          Token token = from;
+          while (true) {
+            if (token == begin) {
+              foundBegin = true;
+            }
+            if (token == end) {
+              foundEnd = true;
+            }
+            if (foundBegin && foundEnd) {
+              return true;
+            }
+            if (token == to || token == token.next || token.next == null) {
+              break;
+            }
+            token = token.next;
+          }
+
+          // Create a good message for when the tokens were not found.
+          StringBuffer sb = new StringBuffer();
+          sb.write('Invalid current element: $currentElement. ');
+          sb.write('Looking for ');
+          sb.write('[${begin} (${begin.hashCode}),');
+          sb.write('${end} (${end.hashCode})] in');
+
+          token = from;
+          while (true) {
+            sb.write('\n ${token} (${token.hashCode})');
+            if (token == to || token == token.next || token.next == null) {
+              break;
+            }
+            token = token.next;
+          }
+          return sb.toString();
+        }
+
+        if (currentElement.enclosingClass != null &&
+            currentElement.enclosingClass.isEnumClass) {
+          // Enums ASTs are synthesized (and give messed up messages).
+          return true;
+        }
+
+        if (currentElement is AstElement) {
+          AstElement astElement = currentElement;
+          if (astElement.hasNode) {
+            Token from = astElement.node.getBeginToken();
+            Token to = astElement.node.getEndToken();
+            if (astElement.metadata.isNotEmpty) {
+              from = astElement.metadata.first.beginToken;
+            }
+            return validateToken(from, to);
+          }
+        }
+        return true;
+      }, message: "Invalid current element: $currentElement [$begin,$end]."));
     }
     return new SourceSpan.fromTokens(uri, begin, end);
   }
@@ -1936,7 +2027,7 @@
   }
 
   void reportSuppressedMessagesSummary() {
-    if (!options.showPackageWarnings && !options.suppressWarnings) {
+    if (!options.showAllPackageWarnings && !options.suppressWarnings) {
       suppressedWarnings.forEach((Uri uri, SuppressionInfo info) {
         MessageKind kind = MessageKind.HIDDEN_WARNINGS_HINTS;
         if (info.warnings == 0) {
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
index a227794..223c24a 100644
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
@@ -10,12 +10,11 @@
 import '../constants/values.dart';
 import 'cps_fragment.dart';
 import 'type_mask_system.dart';
+import '../types/types.dart';
 import '../world.dart';
 import '../elements/elements.dart';
 import 'loop_effects.dart';
 
-
-
 /// Eliminates bounds checks when they can be proven safe.
 ///
 /// In general, this pass will try to eliminate any branch with arithmetic
@@ -114,17 +113,24 @@
   }
 
   /// Get a constraint variable representing the length of [indexableObject] at
-  /// program locations with the given [effectCounter].
-  SignedVariable getLength(Primitive indexableObject, int effectCounter) {
+  /// program locations with the given [effectNumber].
+  SignedVariable getLength(Primitive indexableObject, int effectNumber) {
     indexableObject = indexableObject.effectiveDefinition;
-    if (indexableObject.type != null &&
-        types.isDefinitelyFixedLengthIndexable(indexableObject.type)) {
-      // Always use the same effect counter if the length is immutable.
-      effectCounter = 0;
+    TypeMask type = indexableObject.type.nonNullable();
+    if (types.isDefinitelyFixedLengthIndexable(type)) {
+      // Always use the same effect number if the length is immutable.
+      effectNumber = 0;
     }
     return lengthOf
         .putIfAbsent(indexableObject, () => <int, SignedVariable>{})
-        .putIfAbsent(effectCounter, () => octagon.makeVariable(0, MAX_UINT32));
+        .putIfAbsent(effectNumber, () {
+            int length = types.getContainerLength(type);
+            if (length != null) {
+              return octagon.makeVariable(length, length);
+            } else {
+              return octagon.makeVariable(0, MAX_UINT32);
+            }
+        });
   }
 
   // ------------- CONSTRAINT HELPERS -----------------
@@ -238,6 +244,11 @@
     return testConstraint(v1, v2.negated, 0);
   }
 
+  /// Return true if we can prove that `v1 < v2`.
+  bool isDefinitelyLessThan(SignedVariable v1, SignedVariable v2) {
+    return testConstraint(v1, v2.negated, -1);
+  }
+
   /// Return true if we can prove that `v1 >= v2`.
   bool isDefinitelyGreaterThanOrEqualTo(SignedVariable v1, SignedVariable v2) {
     return testConstraint(v2, v1.negated, 0);
@@ -466,10 +477,58 @@
   }
 
   @override
+  void visitRefinement(Refinement node) {
+    // In general we should get the container length of the refined type and
+    // add a constraint if we know the length after the refinement.
+    // However, our current type system removes container information when a
+    // type becomes part of a union, so this cannot happen.
+  }
+
+  @override
   void visitGetLength(GetLength node) {
     valueOf[node] = getLength(node.object.definition, currentEffectNumber);
   }
 
+  @override
+  void visitBoundsCheck(BoundsCheck node) {
+    if (node.checks == BoundsCheck.NONE) return;
+    assert(node.index != null); // Because there is at least one check.
+    Primitive object = node.object.definition;
+    SignedVariable length = node.length == null
+        ? null
+        : getValue(node.length.definition);
+    SignedVariable index = getValue(node.index.definition);
+    if (node.hasUpperBoundCheck) {
+      if (isDefinitelyLessThan(index, length)) {
+        node.checks &= ~BoundsCheck.UPPER_BOUND;
+      } else {
+        makeLessThan(index, length);
+      }
+    }
+    if (node.hasLowerBoundCheck) {
+      if (isDefinitelyGreaterThanOrEqualToConstant(index, 0)) {
+        node.checks &= ~BoundsCheck.LOWER_BOUND;
+      } else {
+        makeGreaterThanOrEqualToConstant(index, 0);
+      }
+    }
+    if (node.hasEmptinessCheck) {
+      if (isDefinitelyGreaterThanOrEqualToConstant(length, 1)) {
+        node.checks &= ~BoundsCheck.EMPTINESS;
+      } else {
+        makeGreaterThanOrEqualToConstant(length, 1);
+      }
+    }
+    if (!node.lengthUsedInCheck && node.length != null) {
+      node..length.unlink()..length = null;
+    }
+    if (node.checks == BoundsCheck.NONE) {
+      // We can't remove the bounds check node because it may still be used to
+      // restrict code motion.  But the index is no longer needed.
+      node..index.unlink()..index = null;
+    }
+  }
+
   void analyzeLoopEntry(InvokeContinuation node) {
     foundLoop = true;
     Continuation cont = node.continuation.definition;
diff --git a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
index ada5d1a..5d56560 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_fragment.dart
@@ -104,6 +104,7 @@
 
   Primitive makeZero() => makeConstant(new IntConstantValue(0));
   Primitive makeOne() => makeConstant(new IntConstantValue(1));
+  Primitive makeMinusOne() => makeConstant(new IntConstantValue(-1));
   Primitive makeNull() => makeConstant(new NullConstantValue());
   Primitive makeTrue() => makeConstant(new TrueConstantValue());
   Primitive makeFalse() => makeConstant(new FalseConstantValue());
@@ -113,6 +114,10 @@
     return letPrim(new ApplyBuiltinOperator(op, args, sourceInformation));
   }
 
+  Primitive refine(Primitive value, TypeMask type) {
+    return letPrim(new Refinement(value, type));
+  }
+
   Primitive invokeBuiltin(BuiltinMethod method,
                           Primitive receiver,
                           List<Primitive> arguments,
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 e4fb1fd..afc4cd7 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
@@ -43,7 +43,8 @@
 import 'cps_ir_nodes.dart' as ir;
 import 'cps_ir_builder.dart';
 import '../native/native.dart' show
-    NativeBehavior;
+    NativeBehavior,
+    HasCapturedPlaceholders;
 
 // TODO(karlklose): remove.
 import '../js/js.dart' as js show js, Template, Expression, Name;
@@ -1725,7 +1726,7 @@
           switch (getterKind) {
             case CompoundGetter.FIELD:
               SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return irBuilder.buildStaticFieldGet(getter, src);
+              return buildStaticFieldGet(getter, src);
             case CompoundGetter.GETTER:
               return irBuilder.buildStaticGetterGet(
                   getter, sourceInformationBuilder.buildGet(node));
@@ -1763,7 +1764,7 @@
           switch (getterKind) {
             case CompoundGetter.FIELD:
               SourceInformation src = sourceInformationBuilder.buildGet(node);
-              return irBuilder.buildStaticFieldGet(getter, src);
+              return buildStaticFieldGet(getter, src);
             case CompoundGetter.GETTER:
               return irBuilder.buildStaticGetterGet(
                   getter, sourceInformationBuilder.buildGet(node));
@@ -3489,6 +3490,20 @@
         // using [NativeBehavior]. We can ignore these arguments in the backend.
         List<ir.Primitive> arguments =
             argumentNodes.skip(2).mapToList(visit, growable: false);
+        if (behavior.codeTemplate.positionalArgumentCount != arguments.length) {
+          reporter.reportErrorMessage(
+              node, MessageKind.GENERIC,
+              {'text':
+                'Mismatch between number of placeholders'
+                ' and number of arguments.'});
+          return irBuilder.buildNullConstant();
+        }
+
+        if (HasCapturedPlaceholders.check(behavior.codeTemplate.ast)) {
+          reporter.reportErrorMessage(node, MessageKind.JS_PLACEHOLDER_CAPTURE);
+          return irBuilder.buildNullConstant();
+        }
+
         return irBuilder.buildForeignCode(behavior.codeTemplate, arguments,
             behavior);
 
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 53a1a98..02b963e 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -234,7 +234,14 @@
   // TODO(johnniwinther): Require source information for all primitives.
   SourceInformation get sourceInformation => null;
 
-  /// If this is a [Refinement] node, returns the value being refined.
+  /// If this is a [Refinement], [BoundsCheck] or [NullCheck] node, returns the
+  /// value being refined, the indexable object being checked, or the value
+  /// that was checked to be non-null, respectively.
+  ///
+  /// Those instructions all return the corresponding operand directly, and
+  /// this getter can be used to get (closer to) where the value came from.
+  //
+  // TODO(asgerf): Also do this for [TypeCast]?
   Primitive get effectiveDefinition => this;
 
   /// True if the two primitives are (refinements of) the same value.
@@ -506,6 +513,11 @@
   ///
   /// For example: `foo.bar$1(0, x)`
   DummyIntercepted,
+
+  /// JS receiver is the Dart receiver, there are no extra arguments.
+  ///
+  /// Compiles to a one-shot interceptor, e.g: `J.bar$1(foo, x)`
+  OneShotIntercepted,
 }
 
 /// Invoke a method on an object.
@@ -535,9 +547,15 @@
   Primitive get dartReceiver => dartReceiverReference.definition;
 
   Reference<Primitive> dartArgumentReference(int n) {
-    return callingConvention == CallingConvention.Normal
-        ? arguments[n]
-        : arguments[n + 1];
+    switch (callingConvention) {
+      case CallingConvention.Normal:
+      case CallingConvention.OneShotIntercepted:
+        return arguments[n];
+
+      case CallingConvention.Intercepted:
+      case CallingConvention.DummyIntercepted:
+        return arguments[n + 1];
+    }
   }
 
   Primitive dartArgument(int n) => dartArgumentReference(n).definition;
@@ -704,9 +722,157 @@
   }
 }
 
+/// Checks that [index] is a valid index on a given indexable [object].
+///
+/// Compiles to the following, with a subset of the conditions in the `if`:
+///
+///     if (index < 0 || index >= object.length || object.length === 0)
+///         ThrowIndexOutOfRangeException(object, index);
+///
+/// [index] must be an integer, and [object] must refer to null or an indexable
+/// object, and [length] must be the length of [object] at the time of the
+/// check.
+///
+/// Returns [object] so the bounds check can be used to restrict code motion.
+/// It is possible to have a bounds check node that performs no checks but
+/// is retained to restrict code motion.
+///
+/// The [index] reference may be null if there are no checks to perform,
+/// and the [length] reference may be null if there is no upper bound or
+/// emptiness check.
+///
+/// If a separate code motion guard for the index is required, e.g. because it
+/// must be known to be non-negative in an operator that does not involve
+/// [object], a [Refinement] can be created for it with the non-negative integer
+/// type.
+class BoundsCheck extends Primitive {
+  final Reference<Primitive> object;
+  Reference<Primitive> index;
+  Reference<Primitive> length; // FIXME write docs for length
+  int checks;
+  final SourceInformation sourceInformation;
+
+  /// If true, check that `index >= 0`.
+  bool get hasLowerBoundCheck => checks & LOWER_BOUND != 0;
+
+  /// If true, check that `index < object.length`.
+  bool get hasUpperBoundCheck => checks & UPPER_BOUND != 0;
+
+  /// If true, check that `object.length !== 0`.
+  ///
+  /// Equivalent to a lower bound check with `object.length - 1` as the index,
+  /// but this check is faster.
+  ///
+  /// Although [index] is not used in the condition, it is used to generate
+  /// the thrown error.  Currently it is always `-1` for emptiness checks,
+  /// because that corresponds to `object.length - 1` in the error case.
+  bool get hasEmptinessCheck => checks & EMPTINESS != 0;
+
+  /// True if the [length] is needed to perform the check.
+  bool get lengthUsedInCheck => checks & (UPPER_BOUND | EMPTINESS) != 0;
+
+  bool get hasNoChecks => checks == NONE;
+
+  static const int UPPER_BOUND = 1 << 0;
+  static const int LOWER_BOUND = 1 << 1;
+  static const int EMPTINESS = 1 << 2; // See [hasEmptinessCheck].
+  static const int BOTH_BOUNDS = UPPER_BOUND | LOWER_BOUND;
+  static const int NONE = 0;
+
+  BoundsCheck(Primitive object, Primitive index, Primitive length,
+      [this.checks = BOTH_BOUNDS, this.sourceInformation])
+      : this.object = new Reference<Primitive>(object),
+        this.index = new Reference<Primitive>(index),
+        this.length = new Reference<Primitive>(length);
+
+  BoundsCheck.noCheck(Primitive object, [this.sourceInformation])
+      : this.object = new Reference<Primitive>(object),
+        this.checks = NONE;
+
+  accept(Visitor visitor) => visitor.visitBoundsCheck(this);
+
+  void setParentPointers() {
+    object.parent = this;
+    if (index != null) {
+      index.parent = this;
+    }
+    if (length != null) {
+      length.parent = this;
+    }
+  }
+
+  String get checkString {
+    if (hasUpperBoundCheck && hasLowerBoundCheck) {
+      return 'upper-lower-checks';
+    } else if (hasUpperBoundCheck) {
+      return 'upper-check';
+    } else if (hasLowerBoundCheck) {
+      return 'lower-check';
+    } else if (hasEmptinessCheck) {
+      return 'emptiness-check';
+    } else {
+      return 'no-check';
+    }
+  }
+
+  bool get isSafeForElimination => checks == NONE;
+  bool get isSafeForReordering => false;
+  bool get hasValue => true; // Can be referenced to restrict code motion.
+
+  Primitive get effectiveDefinition => object.definition.effectiveDefinition;
+}
+
+/// Throw an exception if [value] is `null`.
+///
+/// Returns [value] so this can be used to restrict code motion.
+///
+/// In the simplest form this compiles to `value.toString;`.
+///
+/// If [selector] is set, `toString` is replaced with the (possibly minified)
+/// invocation name of the selector.  This can be shorter and generate a more
+/// meaningful error message, but is expensive if [value] is non-null and does
+/// not have that property at runtime.
+///
+/// If [condition] is set, it is assumed that [condition] is true if and only
+/// if [value] is null.  The check then compiles to:
+///
+///     if (condition) value.toString;  (or .selector if non-null)
+///
+/// The latter form is useful when [condition] is a form understood by the JS
+/// runtime, such as a `typeof` test.
+class NullCheck extends Primitive {
+  final Reference<Primitive> value;
+  Selector selector;
+  Reference<Primitive> condition;
+  final SourceInformation sourceInformation;
+
+  NullCheck(Primitive value, this.sourceInformation)
+      : this.value = new Reference<Primitive>(value);
+
+  NullCheck.guarded(Primitive condition, Primitive value, this.selector,
+        this.sourceInformation)
+      : this.condition = new Reference<Primitive>(condition),
+        this.value = new Reference<Primitive>(value);
+
+  bool get isSafeForElimination => false;
+  bool get isSafeForReordering => false;
+  bool get hasValue => true;
+
+  accept(Visitor visitor) => visitor.visitNullCheck(this);
+
+  void setParentPointers() {
+    value.parent = this;
+    if (condition != null) {
+      condition.parent = this;
+    }
+  }
+
+  Primitive get effectiveDefinition => value.definition.effectiveDefinition;
+}
+
 /// An "is" type test.
 ///
-/// Returns `true` if [value] is an instance of [type].
+/// Returns `true` if [value] is an instance of [dartType].
 ///
 /// [type] must not be the [Object], `dynamic` or [Null] types (though it might
 /// be a type variable containing one of these types). This design is chosen
@@ -1093,10 +1259,10 @@
   }
 }
 
-/// Read an entry from a string or native list.
+/// Read an entry from an indexable object.
 ///
-/// [object] must be null or a native list or a string, and [index] must be
-/// an integer.
+/// [object] must be null or an indexable object, and [index] must be
+/// an integer where `0 <= index < object.length`.
 class GetIndex extends Primitive {
   final Reference<Primitive> object;
   final Reference<Primitive> index;
@@ -1150,14 +1316,27 @@
 
 /// Reads the value of a static field or tears off a static method.
 ///
-/// Note that lazily initialized fields should be read using GetLazyStatic.
+/// If [GetStatic] is used to load a lazily initialized static field, it must
+/// have been initialized beforehand, and a [witness] must be set to restrict
+/// code motion.
 class GetStatic extends Primitive {
   /// Can be [FieldElement] or [FunctionElement].
   final Element element;
   final SourceInformation sourceInformation;
 
+  /// If reading a lazily initialized field, [witness] must refer to a node
+  /// that initializes the field or always occurs after the field initializer.
+  ///
+  /// The value of the witness is not used.
+  Reference<Primitive> witness;
+
   GetStatic(this.element, [this.sourceInformation]);
 
+  /// Read a lazily initialized static field that is known to have been
+  /// initialized by [witness] or earlier.
+  GetStatic.witnessed(this.element, Primitive witness, [this.sourceInformation])
+      : witness = witness == null ? null : new Reference<Primitive>(witness);
+
   accept(Visitor visitor) => visitor.visitGetStatic(this);
 
   bool get hasValue => true;
@@ -1166,7 +1345,11 @@
     return element is FunctionElement || element.isFinal;
   }
 
-  void setParentPointers() {}
+  void setParentPointers() {
+    if (witness != null) {
+      witness.parent = this;
+    }
+  }
 }
 
 /// Sets the value of a static field.
@@ -1732,6 +1915,8 @@
   T visitGetIndex(GetIndex node);
   T visitSetIndex(SetIndex node);
   T visitRefinement(Refinement node);
+  T visitBoundsCheck(BoundsCheck node);
+  T visitNullCheck(NullCheck node);
 
   // Support for literal foreign code.
   T visitForeignCode(ForeignCode node);
@@ -1951,6 +2136,9 @@
   processGetStatic(GetStatic node) {}
   visitGetStatic(GetStatic node) {
     processGetStatic(node);
+    if (node.witness != null) {
+      processReference(node.witness);
+    }
   }
 
   processSetStatic(SetStatic node) {}
@@ -2050,6 +2238,27 @@
     processRefinement(node);
     processReference(node.value);
   }
+
+  processBoundsCheck(BoundsCheck node) {}
+  visitBoundsCheck(BoundsCheck node) {
+    processBoundsCheck(node);
+    processReference(node.object);
+    if (node.index != null) {
+      processReference(node.index);
+    }
+    if (node.length != null) {
+      processReference(node.length);
+    }
+  }
+
+  processNullCheck(NullCheck node) {}
+  visitNullCheck(NullCheck node) {
+    processNullCheck(node);
+    processReference(node.value);
+    if (node.condition != null) {
+      processReference(node.condition);
+    }
+  }
 }
 
 typedef void StackAction();
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 12262e13..bf857f9 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -33,6 +33,10 @@
     return decorator(r, namer.getName(r.definition));
   }
 
+  String optionalAccess(Reference<Definition> reference) {
+    return reference == null ? '()' : '(${access(reference)})';
+  }
+
   String visitParameter(Parameter node) {
     return namer.nameParameter(node);
   }
@@ -360,6 +364,19 @@
     String value = access(node.value);
     return '(Refinement $value ${node.type})';
   }
+
+  String visitBoundsCheck(BoundsCheck node) {
+    String object = access(node.object);
+    String index = optionalAccess(node.index);
+    String length = optionalAccess(node.length);
+    return '(BoundsCheck $object $index $length ${node.checkString})';
+  }
+
+  String visitNullCheck(NullCheck node) {
+    String value = access(node.value);
+    String condition = optionalAccess(node.condition);
+    return '(NullCheck $value $condition (${node.selector ?? ""}))';
+  }
 }
 
 class ConstantStringifier extends ConstantValueVisitor<String, Null> {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 6c7469e..e732f3d 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -242,6 +242,7 @@
   }
 
   String formatReference(cps_ir.Reference ref) {
+    if (ref == null) return 'null';
     cps_ir.Definition target = ref.definition;
     if (target is cps_ir.Continuation && target.isReturnContinuation) {
       return "return"; // Do not generate a name for the return continuation
@@ -389,6 +390,23 @@
     String value = formatReference(node.value);
     return 'Refinement $value ${node.refineType}';
   }
+
+  visitBoundsCheck(cps_ir.BoundsCheck node) {
+    String object = formatReference(node.object);
+    String index = node.index == null
+        ? 'no-index'
+        : formatReference(node.index);
+    String length = node.length == null
+        ? 'no-length'
+        : formatReference(node.length);
+    return 'BoundsCheck $object $index $length ${node.checkString}';
+  }
+
+  visitNullCheck(cps_ir.NullCheck node) {
+    String value = formatReference(node.value);
+    String condition = formatReference(node.condition);
+    return 'NullCheck $value condition:$condition selector:${node.selector}';
+  }
 }
 
 /**
@@ -671,4 +689,12 @@
   visitRefinement(cps_ir.Refinement node) {
     unexpectedNode(node);
   }
+
+  visitBoundsCheck(cps_ir.BoundsCheck node) {
+    unexpectedNode(node);
+  }
+
+  visitNullCheck(cps_ir.NullCheck node) {
+    unexpectedNode(node);
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart
new file mode 100644
index 0000000..6f733e3
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/eagerly_load_statics.dart
@@ -0,0 +1,67 @@
+// 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 dart2js.cps_ir.eagerly_load_statics;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart' show Pass;
+import '../elements/elements.dart';
+
+/// Replaces [GetLazyStatic] with [GetStatic] when the static field is known
+/// to have been initialized.
+///
+/// Apart from [GetStatic] generating better code, this improves the side-effect
+/// analysis in the [GVN] pass, since [GetStatic] has no effects.
+class EagerlyLoadStatics extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Eagerly load statics';
+
+  Map<FieldElement, Primitive> initializerFor = <FieldElement, Primitive>{};
+
+  final Map<Continuation, Map<FieldElement, Primitive>> initializersAt =
+      <Continuation, Map<FieldElement, Primitive>>{};
+
+  static Map<FieldElement, Primitive> cloneFieldMap(
+        Map<FieldElement, Primitive> map) {
+    return new Map<FieldElement, Primitive>.from(map);
+  }
+
+  void rewrite(FunctionDefinition node) {
+    visit(node.body);
+  }
+
+  Expression traverseLetCont(LetCont node) {
+    for (Continuation cont in node.continuations) {
+      initializersAt[cont] = cloneFieldMap(initializerFor);
+      push(cont);
+    }
+    return node.body;
+  }
+
+  Expression traverseLetHandler(LetHandler node) {
+    initializersAt[node.handler] = cloneFieldMap(initializerFor);
+    push(node.handler);
+    return node.body;
+  }
+
+  Expression traverseContinuation(Continuation cont) {
+    initializerFor = initializersAt[cont];
+    return cont.body;
+  }
+
+  void visitGetLazyStatic(GetLazyStatic node) {
+    Primitive initializer = initializerFor[node.element];
+    if (initializer != null) {
+      GetStatic newNode = new GetStatic.witnessed(node.element, initializer,
+          node.sourceInformation);
+      newNode.type = node.type;
+      node.replaceWith(newNode);
+    } else {
+      initializerFor[node.element] = node;
+    }
+  }
+
+  void visitSetStatic(SetStatic node) {
+    initializerFor.putIfAbsent(node.element, () => node);
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/finalize.dart b/pkg/compiler/lib/src/cps_ir/finalize.dart
new file mode 100644
index 0000000..1406a58
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/finalize.dart
@@ -0,0 +1,81 @@
+library dart2js.cps_ir.finalize;
+
+import 'cps_ir_nodes.dart';
+import 'cps_fragment.dart';
+import 'optimizers.dart' show Pass;
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../js_backend/backend_helpers.dart';
+
+/// A transformation pass that must run immediately before the tree IR builder.
+///
+/// This expands [BoundsCheck] nodes into more low-level operations.
+class Finalize extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Finalize';
+
+  JavaScriptBackend backend;
+  BackendHelpers get helpers => backend.helpers;
+
+  Finalize(this.backend);
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    CpsFragment cps = visit(node.primitive);
+    if (cps == null) return node.body;
+    cps.insertBelow(node);
+    Expression next = node.body;
+    node.remove();
+    return next;
+  }
+
+  bool areAdjacent(Primitive first, Primitive second) {
+    return first.parent == second.parent.parent;
+  }
+
+  CpsFragment visitBoundsCheck(BoundsCheck node) {
+    CpsFragment cps = new CpsFragment(node.sourceInformation);
+    if (node.hasNoChecks) {
+      node..replaceUsesWith(node.object.definition)..destroy();
+      return cps;
+    }
+    Continuation fail = cps.letCont();
+    if (node.hasLowerBoundCheck) {
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumLt,
+          [node.index.definition, cps.makeZero()]))
+          .invokeContinuation(fail);
+    }
+    if (node.hasUpperBoundCheck) {
+      Primitive length = node.length.definition;
+      if (length is GetLength &&
+          length.hasExactlyOneUse &&
+          areAdjacent(length, node)) {
+        // Rebind the GetLength here, so it does not get stuck outside the
+        // condition, blocked from propagating by the lower bounds check.
+        LetPrim lengthBinding = length.parent;
+        lengthBinding.remove();
+        cps.letPrim(length);
+      }
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.NumGe,
+          [node.index.definition, length]))
+          .invokeContinuation(fail);
+    }
+    if (node.hasEmptinessCheck) {
+      cps.ifTruthy(cps.applyBuiltin(BuiltinOperator.StrictEq,
+          [node.length.definition, cps.makeZero()]))
+          .invokeContinuation(fail);
+    }
+    cps.insideContinuation(fail).invokeStaticThrower(
+          helpers.throwIndexOutOfRangeException,
+          [node.object.definition, node.index.definition]);
+    node..replaceUsesWith(node.object.definition)..destroy();
+    return cps;
+  }
+
+  void visitGetStatic(GetStatic node) {
+    if (node.witness != null) {
+      node..witness.unlink()..witness = null;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/gvn.dart b/pkg/compiler/lib/src/cps_ir/gvn.dart
index 02379d8..cb84402 100644
--- a/pkg/compiler/lib/src/cps_ir/gvn.dart
+++ b/pkg/compiler/lib/src/cps_ir/gvn.dart
@@ -14,6 +14,7 @@
 import '../compiler.dart' show Compiler;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../constants/values.dart';
+import 'type_mask_system.dart';
 
 /// Eliminates redundant primitives by reusing the value of another primitive
 /// that is known to have the same result.  Primitives are also hoisted out of
@@ -44,6 +45,7 @@
   String get passName => 'GVN';
 
   final Compiler compiler;
+  final TypeMaskSystem types;
   JavaScriptBackend get backend => compiler.backend;
   World get world => compiler.world;
 
@@ -80,13 +82,13 @@
 
   Continuation currentLoopHeader;
 
-  GVN(this.compiler);
+  GVN(this.compiler, this.types);
 
   int _usedEffectNumbers = 0;
   int makeNewEffect() => ++_usedEffectNumbers;
 
   void rewrite(FunctionDefinition node) {
-    gvnVectorBuilder = new GvnVectorBuilder(gvnFor, backend);
+    gvnVectorBuilder = new GvnVectorBuilder(gvnFor, compiler, types);
     loopHierarchy = new LoopHierarchy(node);
     loopEffects =
         new LoopSideEffects(node, world, loopHierarchy: loopHierarchy);
@@ -95,6 +97,20 @@
 
   // ------------------ GLOBAL VALUE NUMBERING ---------------------
 
+  /// True if [prim] can be eliminated if its value is already in scope.
+  bool canReplaceWithExistingValue(Primitive prim) {
+    // Primitives that have no side effects other than potentially throwing are
+    // known not the throw if the value is already in scope. Handling those
+    // specially is equivalent to updating refinements during GVN.
+    // GetLazyStatic cannot have side effects because the field has already
+    // been initialized.
+    return prim.isSafeForElimination ||
+           prim is GetField ||
+           prim is GetLength ||
+           prim is GetIndex ||
+           prim is GetLazyStatic;
+  }
+
   @override
   Expression traverseLetPrim(LetPrim node) {
     Expression next = node.body;
@@ -109,13 +125,22 @@
       return next;
     }
 
+    // Update effect numbers due to side effects from a static initializer.
+    // GetLazyStatic is GVN'ed like a GetStatic, but the effects of the static
+    // initializer occur before reading the field.
+    if (prim is GetLazyStatic) {
+      visit(prim);
+    }
+
     // Compute the GVN vector for this computation.
     List vector = gvnVectorBuilder.make(prim, effectNumbers);
 
     // Update effect numbers due to side effects.
     // Do this after computing the GVN vector so the primitive's GVN is not
-    // influenced by its own side effects.
-    visit(prim);
+    // influenced by its own side effects, except in the case of GetLazyStatic.
+    if (prim is! GetLazyStatic) {
+      visit(prim);
+    }
 
     if (vector == null) {
       // The primitive is not GVN'able. Move on.
@@ -129,7 +154,7 @@
     // Try to reuse a previously computed value with the same GVN.
     Primitive existing = environment[gvn];
     if (existing != null &&
-        (prim.isSafeForElimination || prim is GetLazyStatic) &&
+        canReplaceWithExistingValue(prim) &&
         !isTrivialPrimitive(prim)) {
       if (prim is Interceptor) {
         Interceptor interceptor = existing;
@@ -313,15 +338,20 @@
   /// True if [element] is a final or constant field or a function.
   bool isImmutable(Element element) {
     if (element.isField && backend.isNative(element)) return false;
-    return element.isField && (element.isFinal || element.isConst) ||
+    return element.isField && world.fieldNeverChanges(element) ||
            element.isFunction;
   }
 
+  bool isImmutableLength(GetLength length) {
+    return types.isDefinitelyFixedLengthIndexable(length.object.definition.type,
+        allowNull: true);
+  }
+
   /// Assuming [prim] has no side effects, returns true if it can safely
   /// be hoisted out of [loop] without changing its value.
   bool canHoistHeapDependencyOutOfLoop(Primitive prim, Continuation loop) {
     assert(prim.isSafeForElimination);
-    if (prim is GetLength) {
+    if (prim is GetLength && !isImmutableLength(prim)) {
       return !loopEffects.loopChangesLength(loop);
     } else if (prim is GetField && !isImmutable(prim.field)) {
       return !loopEffects.getSideEffectsInLoop(loop).changesInstanceProperty();
@@ -576,10 +606,13 @@
 class GvnVectorBuilder extends DeepRecursiveVisitor {
   List vector;
   final Map<Primitive, int> gvnFor;
-  final JavaScriptBackend backend;
+  final Compiler compiler;
+  World get world => compiler.world;
+  JavaScriptBackend get backend => compiler.backend;
+  final TypeMaskSystem types;
   EffectNumbers effectNumbers;
 
-  GvnVectorBuilder(this.gvnFor, this.backend);
+  GvnVectorBuilder(this.gvnFor, this.compiler, this.types);
 
   List make(Primitive prim, EffectNumbers effectNumbers) {
     this.effectNumbers = effectNumbers;
@@ -609,13 +642,25 @@
   }
 
   processGetLength(GetLength node) {
-    // TODO(asgerf): Take fixed lengths into account?
-    vector = [GvnCode.GET_LENGTH, effectNumbers.indexableLength];
+    if (isImmutableLength(node)) {
+      // Omit the effect number for fixed-length lists.  Note that if a the list
+      // gets refined to a fixed-length type, we still won't be able to GVN a
+      // GetLength across the refinement, because the first GetLength uses an
+      // effect number in its vector while the second one does not.
+      vector = [GvnCode.GET_LENGTH];
+    } else {
+      vector = [GvnCode.GET_LENGTH, effectNumbers.indexableLength];
+    }
   }
 
   bool isImmutable(Element element) {
     return element.isFunction ||
-           element.isField && (element.isFinal || element.isConst);
+           element.isField && world.fieldNeverChanges(element);
+  }
+
+  bool isImmutableLength(GetLength length) {
+    return types.isDefinitelyFixedLengthIndexable(length.object.definition.type,
+        allowNull: true);
   }
 
   bool isNativeField(FieldElement field) {
@@ -637,12 +682,13 @@
     vector = [GvnCode.GET_INDEX, effectNumbers.indexableContent];
   }
 
-  processGetStatic(GetStatic node) {
+  visitGetStatic(GetStatic node) {
     if (isImmutable(node.element)) {
       vector = [GvnCode.GET_STATIC, node.element];
     } else {
       vector = [GvnCode.GET_STATIC, node.element, effectNumbers.staticField];
     }
+    // Suppress visit to witness argument.
   }
 
   processGetLazyStatic(GetLazyStatic node) {
diff --git a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
index 599989a..9f05e39 100644
--- a/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimize_interceptors.dart
@@ -14,6 +14,7 @@
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../types/types.dart' show TypeMask;
 import '../io/source_information.dart' show SourceInformation;
+import '../universe/selector.dart';
 
 /// Replaces `getInterceptor` calls with interceptor constants when possible,
 /// or with "almost constant" expressions like "x && CONST" when the input
@@ -31,6 +32,8 @@
 
   BackendHelpers get helpers => backend.helpers;
 
+  Map<Interceptor, Continuation> loopHeaderFor = <Interceptor, Continuation>{};
+
   void rewrite(FunctionDefinition node) {
     // TODO(asgerf): Computing the LoopHierarchy here may be overkill when all
     //               we want is to hoist constants out of loops.
@@ -101,11 +104,11 @@
     return prim;
   }
 
-  void constifyInterceptor(Interceptor interceptor) {
+  bool constifyInterceptor(Interceptor interceptor) {
     LetPrim let = interceptor.parent;
     InterceptorConstantValue constant = getInterceptorConstant(interceptor);
 
-    if (constant == null) return;
+    if (constant == null) return false;
 
     if (interceptor.isAlwaysIntercepted) {
       Primitive constantPrim = makeConstantFor(constant,
@@ -123,6 +126,7 @@
           sourceInformation: interceptor.sourceInformation);
       CpsFragment cps = new CpsFragment(interceptor.sourceInformation);
       Parameter param = new Parameter(interceptor.hint);
+      param.type = interceptor.type;
       Continuation cont = cps.letCont(<Parameter>[param]);
       if (interceptor.interceptedClasses.every(hasNoFalsyValues)) {
         // If null is the only falsy value, compile as "x && CONST".
@@ -140,16 +144,54 @@
       interceptor..replaceUsesWith(param)..destroy();
       let.remove();
     }
+    return true;
   }
 
   @override
   Expression traverseLetPrim(LetPrim node) {
     Expression next = node.body;
-    if (node.primitive is Interceptor) {
-      constifyInterceptor(node.primitive);
-    }
+    visit(node.primitive);
     return next;
   }
+
+  @override
+  void visitInterceptor(Interceptor node) {
+    if (constifyInterceptor(node)) return;
+    if (node.hasExactlyOneUse) {
+      // Set the loop header on single-use interceptors so [visitInvokeMethod]
+      // can determine if it should become a one-shot interceptor.
+      loopHeaderFor[node] = currentLoopHeader;
+    }
+  }
+
+  @override
+  void visitInvokeMethod(InvokeMethod node) {
+    if (node.callingConvention != CallingConvention.Intercepted) return;
+    Primitive interceptor = node.receiver.definition;
+    if (interceptor is! Interceptor ||
+        interceptor.hasMultipleUses ||
+        loopHeaderFor[interceptor] != currentLoopHeader) {
+      return;
+    }
+    // TODO(asgerf): Consider heuristics for when to use one-shot interceptors.
+    //   E.g. using only one-shot interceptors with a fast path.
+    node.callingConvention = CallingConvention.OneShotIntercepted;
+    node..receiver.unlink()..receiver = node.arguments.removeAt(0);
+  }
+
+  @override
+  void visitTypeTestViaFlag(TypeTestViaFlag node) {
+    Primitive interceptor = node.interceptor.definition;
+    if (interceptor is! Interceptor ||
+        interceptor.hasMultipleUses ||
+        loopHeaderFor[interceptor] != currentLoopHeader ||
+        !backend.mayGenerateInstanceofCheck(node.dartType)) {
+      return;
+    }
+    Interceptor inter = interceptor;
+    Primitive value = inter.input.definition;
+    node.replaceWith(new TypeTest(value, node.dartType, [])..type = node.type);
+  }
 }
 
 /// Shares interceptor constants when one is in scope of another.
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 9d5f13e..ccbee6f 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -14,11 +14,12 @@
 export 'shrinking_reductions.dart' show ShrinkingReducer;
 export 'mutable_ssa.dart' show MutableVariableEliminator;
 export 'insert_refinements.dart' show InsertRefinements;
-export 'remove_refinements.dart' show RemoveRefinements;
+export 'update_refinements.dart' show UpdateRefinements;
 export 'redundant_refinement.dart' show RedundantRefinementEliminator;
 export 'optimize_interceptors.dart' show OptimizeInterceptors;
 export 'bounds_checker.dart' show BoundsChecker;
 export 'gvn.dart' show GVN;
+export 'eagerly_load_statics.dart' show EagerlyLoadStatics;
 export 'parent_visitor.dart' show ParentVisitor;
 
 /// An optimization pass over the CPS IR.
diff --git a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart b/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
deleted file mode 100644
index eead3f0..0000000
--- a/pkg/compiler/lib/src/cps_ir/remove_refinements.dart
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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 cps_ir.optimization.remove_refinements;
-
-import 'optimizers.dart' show Pass;
-import 'cps_ir_nodes.dart';
-
-/// Removes all [Refinement] nodes from the IR.
-///
-/// This simplifies subsequent passes that don't rely on path-sensitive
-/// type information but depend on equality between primitives.
-class RemoveRefinements extends TrampolineRecursiveVisitor implements Pass {
-  String get passName => 'Remove refinement nodes';
-
-  void rewrite(FunctionDefinition node) {
-    visit(node);
-  }
-
-  @override
-  Expression traverseLetPrim(LetPrim node) {
-    Expression next = node.body;
-    if (node.primitive is Refinement) {
-      Refinement refinement = node.primitive;
-      Primitive value = refinement.value.definition;
-      if (refinement.hint != null && value.hint == null) {
-        value.hint = refinement.hint;
-      }
-      refinement..replaceUsesWith(value)..destroy();
-      node.remove();
-    }
-    return next;
-  }
-}
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index f716f05..86333da 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -683,6 +683,21 @@
     if (constantValue != null) return constant(constantValue, mask);
     return nonConstant(mask);
   }
+
+  AbstractConstantValue nonNullable(AbstractConstantValue value) {
+    if (value.isNullConstant) return nothing;
+    if (!value.isNullable) return value;
+    return nonConstant(value.type.nonNullable());
+  }
+
+  /// If [value] is an integer constant, returns its value, otherwise `null`.
+  int intValue(AbstractConstantValue value) {
+    if (value.isConstant && value.constant.isInt) {
+      PrimitiveConstantValue constant = value.constant;
+      return constant.primitiveValue;
+    }
+    return null;
+  }
 }
 
 /**
@@ -847,9 +862,11 @@
     if (prim is! Constant && prim is! Refinement && prim.isSafeForElimination) {
       AbstractConstantValue value = getValue(prim);
       if (value.isConstant) {
-        prim.replaceWith(makeConstantPrimitive(value.constant));
-        push(node.body);
-        return;
+        if (constantIsSafeToCopy(value.constant)) {
+          prim.replaceWith(makeConstantPrimitive(value.constant));
+          push(node.body);
+          return;
+        }
       }
     }
 
@@ -881,6 +898,17 @@
     push(node.body);
   }
 
+  bool constantIsSafeToCopy(ConstantValue constant) {
+    // TODO(25230, 25231): We should refer to large shared strings by name.
+    // This number is chosen to prevent huge strings being copied. Don't make
+    // this too small, otherwise it will suppress otherwise harmless constant
+    // folding.
+    const int MAXIMUM_LENGTH_OF_DUPLICATED_STRING = 500;
+    return constant is StringConstantValue
+        ? constant.length < MAXIMUM_LENGTH_OF_DUPLICATED_STRING
+        : true;
+  }
+
   bool isAlwaysThrowingOrDiverging(Primitive prim) {
     if (prim is SetField) {
       return getValue(prim.object.definition).isNullConstant;
@@ -1073,41 +1101,35 @@
   specializeOperatorCall(InvokeMethod node) {
     bool trustPrimitives = compiler.trustPrimitives;
 
-    /// Checks that the the receiver satisfied the given predicate [guard],
-    /// otherwise ensures a [NoSuchMethodError] will be thrown.
+    /// Throws a [NoSuchMethodError] if the receiver is null, where [guard]
+    /// is a predicate that is true if and only if the receiver is null.
     ///
-    /// For example, if the [guard] is `IsNumber` for a call to `<`:
-    ///
-    ///     if (typeof x !== 'number') return x.$lt();
-    ///
-    /// The [guard] must accept all possible non-null values for the receiver,
-    /// but should be as specific as possible so the VM gets more information
-    /// from the check.
+    /// See [NullCheck.guarded].
     Primitive guardReceiver(CpsFragment cps, BuiltinOperator guard) {
       if (guard == null || getValue(node.dartReceiver).isDefinitelyNotNull) {
         return node.dartReceiver;
       }
       if (!trustPrimitives) {
+        // TODO(asgerf): Perhaps a separate optimization should decide that
+        // the guarded check is better based on the type?
         Primitive check = cps.applyBuiltin(guard, [node.dartReceiver]);
-        cps.ifFalsy(check)
-           ..invokeMethod(node.dartReceiver, node.selector,
-             typeSystem.nullType, [])
-           ..put(new Unreachable());
+        return cps.letPrim(new NullCheck.guarded(check, node.dartReceiver,
+          node.selector, node.sourceInformation));
+      } else {
+        // Refine the receiver to be non-null for use in the operator.
+        // This restricts code motion and improves the type computed for the
+        // built-in operator that depends on it.
+        // This must be done even if trusting primitives.
+        return cps.letPrim(
+            new Refinement(node.dartReceiver, typeSystem.nonNullType));
       }
-      // Refine the receiver to be non-null for use in the operator.
-      // This restricts code motion and improves the type computed for the
-      // built-in operator that depends on it.
-      // This must be done even if trusting primitives.
-      Primitive refined = cps.letPrim(
-          new Refinement(node.dartReceiver, typeSystem.nonNullType));
-      return refined;
     }
 
     /// Replaces the call with [operator], using the receiver and first argument
     /// as operands (in that order).
     ///
     /// If [guard] is given, the receiver is checked using [guardReceiver],
-    /// unless it is known kot to be null.
+    /// unless it is known not to be null.
     CpsFragment makeBinary(BuiltinOperator operator, {BuiltinOperator guard}) {
       CpsFragment cps = new CpsFragment(node.sourceInformation);
       Primitive left = guardReceiver(cps, guard);
@@ -1164,7 +1186,7 @@
           // Try to insert a numeric operator.
           BuiltinOperator operator = NumBinaryBuiltins[opname];
           if (operator != null) {
-            return makeBinary(operator, guard: BuiltinOperator.IsNumber);
+            return makeBinary(operator, guard: BuiltinOperator.IsNotNumber);
           }
           // Shift operators are not in [NumBinaryBuiltins] because Dart shifts
           // behave different to JS shifts, especially in the handling of the
@@ -1174,7 +1196,7 @@
               lattice.isDefinitelyInt(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
             return makeBinary(BuiltinOperator.NumShl,
-                guard: BuiltinOperator.IsNumber);
+                guard: BuiltinOperator.IsNotNumber);
           }
           // Try to insert a shift-right operator. JavaScript's right shift is
           // consistent with Dart's only for left operands in the unsigned
@@ -1183,7 +1205,7 @@
               lattice.isDefinitelyUint32(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
             return makeBinary(BuiltinOperator.NumShr,
-                guard: BuiltinOperator.IsNumber);
+                guard: BuiltinOperator.IsNotNumber);
           }
           // Try to use remainder for '%'. Both operands must be non-negative
           // and the divisor must be non-zero.
@@ -1192,14 +1214,14 @@
               lattice.isDefinitelyUint(right) &&
               lattice.isDefinitelyIntInRange(right, min: 1)) {
             return makeBinary(BuiltinOperator.NumRemainder,
-                guard: BuiltinOperator.IsNumber);
+                guard: BuiltinOperator.IsNotNumber);
           }
 
           if (opname == '~/' &&
               lattice.isDefinitelyUint32(left, allowNull: true) &&
               lattice.isDefinitelyIntInRange(right, min: 2)) {
             return makeBinary(BuiltinOperator.NumTruncatingDivideToSigned32,
-                guard: BuiltinOperator.IsNumber);
+                guard: BuiltinOperator.IsNotNumber);
           }
         }
         if (lattice.isDefinitelyString(left, allowNull: trustPrimitives) &&
@@ -1218,11 +1240,11 @@
         String opname = node.selector.name;
         if (opname == '~') {
           return makeUnary(BuiltinOperator.NumBitNot,
-              guard: BuiltinOperator.IsNumber);
+              guard: BuiltinOperator.IsNotNumber);
         }
         if (opname == 'unary-') {
           return makeUnary(BuiltinOperator.NumNegate,
-              guard: BuiltinOperator.IsNumber);
+              guard: BuiltinOperator.IsNotNumber);
         }
       }
     }
@@ -1238,7 +1260,7 @@
               lattice.isDefinitelyInt(argValue) &&
               isIntNotZero(argValue)) {
             return makeBinary(BuiltinOperator.NumRemainder,
-                guard: BuiltinOperator.IsNumber);
+                guard: BuiltinOperator.IsNotNumber);
           }
         }
       } else if (name == 'codeUnitAt') {
@@ -1247,7 +1269,8 @@
           if (lattice.isDefinitelyString(receiverValue) &&
               lattice.isDefinitelyInt(getValue(index))) {
             SourceInformation sourceInfo = node.sourceInformation;
-            CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo);
+            CpsFragment cps = new CpsFragment(node.sourceInformation);
+            receiver = makeBoundsCheck(cps, receiver, index);
             ApplyBuiltinOperator get =
                 cps.applyBuiltin(BuiltinOperator.CharCodeAt,
                                  <Primitive>[receiver, index]);
@@ -1303,28 +1326,18 @@
   ///
   /// Returns a CPS fragment whose context is the branch where no error
   /// was thrown.
-  CpsFragment makeBoundsCheck(Primitive list,
-                              Primitive index,
-                              SourceInformation sourceInfo) {
-    CpsFragment cps = new CpsFragment(sourceInfo);
+  Primitive makeBoundsCheck(CpsFragment cps,
+                            Primitive list,
+                            Primitive index,
+                            [int checkKind = BoundsCheck.BOTH_BOUNDS]) {
     if (compiler.trustPrimitives) {
-      return cps;
+      return cps.letPrim(new BoundsCheck.noCheck(list, cps.sourceInformation));
+    } else {
+      GetLength length = cps.letPrim(new GetLength(list));
+      list = cps.refine(list, typeSystem.nonNullType);
+      return cps.letPrim(new BoundsCheck(list, index, length, checkKind,
+          cps.sourceInformation));
     }
-    Continuation fail = cps.letCont();
-    if (!typeSystem.isDefinitelyNonNegativeInt(index.type)) {
-      Primitive isTooSmall = cps.applyBuiltin(
-          BuiltinOperator.NumLt,
-          <Primitive>[index, cps.makeZero()]);
-      cps.ifTruthy(isTooSmall).invokeContinuation(fail);
-    }
-    Primitive isTooLarge = cps.applyBuiltin(
-        BuiltinOperator.NumGe,
-        <Primitive>[index, cps.letPrim(new GetLength(list))]);
-    cps.ifTruthy(isTooLarge).invokeContinuation(fail);
-    cps.insideContinuation(fail).invokeStaticThrower(
-        helpers.throwIndexOutOfBoundsError,
-        <Primitive>[list, index]);
-    return cps;
   }
 
   /// Create a check that throws if the length of [list] is not equal to
@@ -1364,7 +1377,8 @@
       case '[]':
         Primitive index = node.dartArgument(0);
         if (!lattice.isDefinitelyInt(getValue(index))) return null;
-        CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo);
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        receiver = makeBoundsCheck(cps, receiver, index);
         GetIndex get = cps.letPrim(new GetIndex(receiver, index));
         node.replaceUsesWith(get);
         // TODO(asgerf): Make replaceUsesWith set the hint?
@@ -1379,7 +1393,8 @@
         Primitive index = node.dartArgument(0);
         Primitive value = node.dartArgument(1);
         if (!lattice.isDefinitelyInt(getValue(index))) return null;
-        CpsFragment cps = makeBoundsCheck(receiver, index, sourceInfo);
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        receiver = makeBoundsCheck(cps, receiver, index);
         cps.letPrim(new SetIndex(receiver, index, value));
         assert(node.hasNoUses);
         return cps;
@@ -1431,14 +1446,8 @@
         }
         if (!isExtendable) return null;
         CpsFragment cps = new CpsFragment(sourceInfo);
-        Primitive length = cps.letPrim(new GetLength(list));
-        Primitive isEmpty = cps.applyBuiltin(
-            BuiltinOperator.StrictEq,
-            [length, cps.makeZero()]);
-        CpsFragment fail = cps.ifTruthy(isEmpty);
-        fail.invokeStaticThrower(
-            helpers.throwIndexOutOfBoundsError,
-            [list, fail.makeConstant(new IntConstantValue(-1))]);
+        list = makeBoundsCheck(cps, list, cps.makeMinusOne(),
+            BoundsCheck.EMPTINESS);
         Primitive removedItem = cps.invokeBuiltin(BuiltinMethod.Pop,
             list,
             <Primitive>[]);
@@ -1481,7 +1490,8 @@
         if (listValue.isNullable) return null;
         Primitive index = node.dartArgument(0);
         if (!lattice.isDefinitelyInt(getValue(index))) return null;
-        CpsFragment cps = makeBoundsCheck(list, index, sourceInfo);
+        CpsFragment cps = new CpsFragment(node.sourceInformation);
+        list = makeBoundsCheck(cps, list, index);
         GetIndex get = cps.letPrim(new GetIndex(list, index));
         get.hint = node.hint;
         node.replaceUsesWith(get);
@@ -2397,6 +2407,48 @@
     }
     return true;
   }
+
+  visitBoundsCheck(BoundsCheck node) {
+    // Eliminate bounds checks using constant folding.
+    // The [BoundsChecker] pass does not try to eliminate checks that could be
+    // eliminated by constant folding.
+    if (node.hasNoChecks) return;
+    int index = lattice.intValue(getValue(node.index.definition));
+    int length = node.length == null
+        ? null
+        : lattice.intValue(getValue(node.length.definition));
+    if (index != null && length != null && index < length) {
+      node.checks &= ~BoundsCheck.UPPER_BOUND;
+    }
+    if (index != null && index >= 0) {
+      node.checks &= ~BoundsCheck.LOWER_BOUND;
+    }
+    if (length != null && length > 0) {
+      node.checks &= ~BoundsCheck.EMPTINESS;
+    }
+    if (!node.lengthUsedInCheck && node.length != null) {
+      node..length.unlink()..length = null;
+    }
+    if (node.checks == BoundsCheck.NONE) {
+      // We can't remove the bounds check node because it may still be used to
+      // restrict code motion.  But the index is no longer needed.
+      // TODO(asgerf): Since this was eliminated by constant folding, it should
+      //     be safe to remove because any path-sensitive information we relied
+      //     upon to do this are expressed by other refinement nodes that also
+      //     restrict code motion.  However, if we want to run this pass after
+      //     [BoundsChecker] that would not be safe any more, so for now we
+      //     keep the node for forward compatibilty.
+      node..index.unlink()..index = null;
+    }
+  }
+
+  visitNullCheck(NullCheck node) {
+    if (!getValue(node.value.definition).isNullable) {
+      node.replaceUsesWith(node.value.definition);
+      return new CpsFragment();
+    }
+    return null;
+  }
 }
 
 /**
@@ -3089,10 +3141,18 @@
     AbstractConstantValue object = getValue(node.object.definition);
     if (object.isNothing || object.isNullConstant) {
       setValue(node, nothing);
-    } else {
-      node.objectIsNotNull = object.isDefinitelyNotNull;
-      setValue(node, lattice.fromMask(typeSystem.getFieldType(node.field)));
+      return;
     }
+    node.objectIsNotNull = object.isDefinitelyNotNull;
+    if (object.isConstant && object.constant.isConstructedObject) {
+      ConstructedConstantValue constructedConstant = object.constant;
+      ConstantValue value = constructedConstant.fields[node.field];
+      if (value != null) {
+        setValue(node, constantValue(value));
+        return;
+      }
+    }
+    setValue(node, lattice.fromMask(typeSystem.getFieldType(node.field)));
   }
 
   void visitSetField(SetField node) {}
@@ -3184,6 +3244,16 @@
           nonConstant(value.type.intersection(node.refineType, classWorld)));
     }
   }
+
+  @override
+  void visitBoundsCheck(BoundsCheck node) {
+    setValue(node, getValue(node.object.definition));
+  }
+
+  @override
+  void visitNullCheck(NullCheck node) {
+    setValue(node, lattice.nonNullable(getValue(node.value.definition)));
+  }
 }
 
 /// Represents the abstract value of a primitive value at some point in the
diff --git a/pkg/compiler/lib/src/cps_ir/update_refinements.dart b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
new file mode 100644
index 0000000..d93e747
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
@@ -0,0 +1,67 @@
+library dart2js.cps_ir.update_refinements;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart' show Pass;
+import 'type_mask_system.dart';
+
+/// Updates all references to use the most refined version in scope.
+///
+/// [GVN] and [RedundantJoinElimination], and possibly other passes, can create
+/// references that don't use the best refinement in scope. This pass improves
+/// the refinement information.
+///
+//
+// TODO(asgerf): Could be done during GVN for another adjacent pass.
+//   It is easier to measure performance and rearrange passes when it has its
+//   own pass, but we can merge it with an adjacent pass later.
+//
+class UpdateRefinements extends TrampolineRecursiveVisitor implements Pass {
+  String get passName => 'Update refinements';
+
+  final TypeMaskSystem typeSystem;
+
+  Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
+
+  UpdateRefinements(this.typeSystem);
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Expression traverseLetPrim(LetPrim node) {
+    visit(node.primitive);
+    return node.body;
+  }
+
+  @override
+  visitRefinement(Refinement node) {
+    if (refine(node.value)) {
+      // Update the type if the input has changed.
+      node.type = typeSystem.intersection(node.value.definition.type,
+          node.refineType);
+    }
+    Primitive value = node.effectiveDefinition;
+    Refinement old = refinementFor[value];
+    refinementFor[value] = node;
+    pushAction(() {
+      refinementFor[value] = old;
+    });
+  }
+
+  @override
+  processReference(Reference ref) {
+    refine(ref);
+  }
+
+  bool refine(Reference ref) {
+    Definition def = ref.definition;
+    if (def is Primitive) {
+      Refinement refinement = refinementFor[def.effectiveDefinition];
+      if (refinement != null && refinement != ref.definition) {
+        ref.changeTo(refinement);
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 0e2c63f..f46ad8d 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -351,7 +351,7 @@
     new OptionHandler(Flags.dumpInfo, setDumpInfo),
     new OptionHandler('--disallow-unsafe-eval',
                       (_) => hasDisallowUnsafeEval = true),
-    new OptionHandler(Flags.showPackageWarnings, passThrough),
+    new OptionHandler(Option.showPackageWarnings, passThrough),
     new OptionHandler(Flags.useContentSecurityPolicy, passThrough),
     new OptionHandler(Flags.enableExperimentalMirrors, passThrough),
     new OptionHandler(Flags.enableAssertMessage, passThrough),
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index e4bd449..8d5baac 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -16,8 +16,10 @@
   /// Emit terse diagnostics without howToFix.
   final bool terseDiagnostics;
 
-  /// If `true`, warnings and hints not from user code are reported.
-  final bool showPackageWarnings;
+  /// List of packages for which warnings and hints are reported. If `null`,
+  /// no package warnings or hints are reported. If empty, all warnings and
+  /// hints are reported.
+  final List<String> _shownPackageWarnings;
 
   /// If `true`, warnings are not reported.
   final bool suppressWarnings;
@@ -33,7 +35,29 @@
     this.fatalWarnings: false,
     this.suppressHints: false,
     this.terseDiagnostics: false,
-    this.showPackageWarnings: false});
+    List<String> shownPackageWarnings: null})
+      : _shownPackageWarnings = shownPackageWarnings;
+
+
+  /// Returns `true` if warnings and hints are shown for all packages.
+  bool get showAllPackageWarnings {
+    return _shownPackageWarnings != null && _shownPackageWarnings.isEmpty;
+  }
+
+  /// Returns `true` if warnings and hints are hidden for all packages.
+  bool get hidePackageWarnings => _shownPackageWarnings == null;
+
+  /// Returns `true` if warnings should be should for [uri].
+  bool showPackageWarningsFor(Uri uri) {
+    if (showAllPackageWarnings) {
+      return true;
+    }
+    if (_shownPackageWarnings != null) {
+      return uri.scheme == 'package' &&
+          _shownPackageWarnings.contains(uri.pathSegments.first);
+    }
+    return false;
+  }
 }
 
 // TODO(johnniwinther): Rename and cleanup this interface. Add severity enum.
@@ -45,6 +69,11 @@
 
   internalError(Spannable spannable, message);
 
+  /// Creates a [SourceSpan] for [node] in scope of the current element.
+  ///
+  /// If [node] is a [Node] or [Token] we assert in checked mode that the
+  /// corresponding tokens can be found within the tokens of the current
+  /// element.
   SourceSpan spanFromSpannable(Spannable node);
 
   void reportErrorMessage(
@@ -85,10 +114,8 @@
   void reportInfo(Spannable node, MessageKind errorCode,
                   [Map arguments = const {}]);
 
-  // TODO(ahe): We should not expose this here.  Perhaps a
-  // [SourceSpan] should implement [Spannable], and we should have a
-  // way to construct a [SourceSpan] from a [Spannable] and an
-  // [Element].
+  /// Set current element of this reporter to [element]. This is used for
+  /// creating [SourceSpan] in [spanFromSpannable].
   withCurrentElement(Element element, f());
 
   DiagnosticMessage createMessage(
diff --git a/pkg/compiler/lib/src/diagnostics/invariant.dart b/pkg/compiler/lib/src/diagnostics/invariant.dart
index b6d4d0f..349d89b 100644
--- a/pkg/compiler/lib/src/diagnostics/invariant.dart
+++ b/pkg/compiler/lib/src/diagnostics/invariant.dart
@@ -48,6 +48,10 @@
   }
   if (condition is Function){
     condition = condition();
+    if (condition is String) {
+      message = condition;
+      condition = false;
+    }
   }
   if (!condition) {
     if (message is Function) {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 200b63f..e651063 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -4,13 +4,14 @@
 
 library dart2js.messages;
 
+import 'package:dart_messages/shared_messages.dart' as shared_messages;
+
 import '../tokens/token.dart' show ErrorToken, Token;
 
 import 'invariant.dart' show invariant;
 import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
 
 import 'dart2js_messages.dart' as dart2js_messages;
-import 'shared_messages.dart' as shared_messages;
 
 /// Keys for the [MessageTemplate]s.
 enum MessageKind {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index a568066..4ff72ab 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -538,11 +538,28 @@
   }
 
   TypeMask joinTypeMasks(Iterable<TypeMask> masks) {
-    TypeMask newType = const TypeMask.nonNullEmpty();
+    var dynamicType = compiler.typesTask.dynamicType;
+    // Optimization: we are iterating over masks twice, but because `masks` is a
+    // mapped iterable, we save the intermediate results to avoid computing them
+    // again.
+    var list = [];
     for (TypeMask mask in masks) {
-      newType = newType.union(mask, classWorld);
+      // Don't do any work on computing unions if we know that after all that
+      // work the result will be `dynamic`.
+      // TODO(sigmund): change to `mask == dynamicType` so we can continue to
+      // track the non-nullable bit.
+      if (mask.containsAll(classWorld)) return dynamicType;
+      list.add(mask);
     }
-    return newType.containsAll(classWorld) ? dynamicType.type : newType;
+
+    TypeMask newType = null;
+    for (TypeMask mask in masks) {
+      newType = newType == null ? mask : newType.union(mask, classWorld);
+      // Likewise - stop early if we already reach dynamic.
+      if (newType.containsAll(classWorld)) return dynamicType;
+    }
+
+    return newType ?? const TypeMask.nonNullEmpty();
   }
 }
 
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 5bd42a1..05b00d1 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -2425,6 +2425,12 @@
   }
 
   void onElementResolved(Element element, TreeElements elements) {
+    if (element.isMalformed) {
+      // Elements that are marker as malformed during parsing or resolution
+      // might be registered here. These should just be ignored.
+      return;
+    }
+
     if ((element.isFunction || element.isConstructor) &&
         annotations.noInline(element)) {
       inlineCache.markAsNonInlinable(element);
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index f0a92d7..804594c 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -433,10 +433,6 @@
     return findHelper('throwConcurrentModificationError');
   }
 
-  Element get throwIndexOutOfBoundsError {
-    return findHelper('ioore');
-  }
-
   Element get stringInterpolationHelper {
     return findHelper('S');
   }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 8bb26fd..54f2d40 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -281,29 +281,19 @@
         sourceInformation: node.sourceInformation);
   }
 
-  void registerMethodInvoke(tree_ir.InvokeMethod node) {
-    Selector selector = node.selector;
-    TypeMask mask = node.mask;
-    mask = glue.extendMaskIfReachesAll(selector, mask);
-    if (selector.isGetter) {
-      registry.registerDynamicUse(new DynamicUse(selector, mask));
-    } else if (selector.isSetter) {
-      registry.registerDynamicUse(new DynamicUse(selector, mask));
-    } else {
-      assert(invariant(CURRENT_ELEMENT_SPANNABLE,
-          selector.isCall || selector.isOperator ||
-          selector.isIndex || selector.isIndexSet,
-          message: 'unexpected kind ${selector.kind}'));
+  void registerMethodInvoke(Selector selector, TypeMask receiverType) {
+    registry.registerDynamicUse(new DynamicUse(selector, receiverType));
+    if (!selector.isGetter && !selector.isSetter) {
       // TODO(sigurdm): We should find a better place to register the call.
       Selector call = new Selector.callClosureFrom(selector);
       registry.registerDynamicUse(new DynamicUse(call, null));
-      registry.registerDynamicUse(new DynamicUse(selector, mask));
     }
   }
 
   @override
   js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
-    registerMethodInvoke(node);
+    TypeMask mask = glue.extendMaskIfReachesAll(node.selector, node.mask);
+    registerMethodInvoke(node.selector, mask);
     return js.propertyCall(visitExpression(node.receiver),
                            glue.invocationName(node.selector),
                            visitExpressionList(node.arguments))
@@ -355,6 +345,17 @@
   }
 
   @override
+  js.Expression visitOneShotInterceptor(tree_ir.OneShotInterceptor node) {
+    registerMethodInvoke(node.selector, node.mask);
+    registry.registerUseInterceptor();
+    return js.js('#.#(#)',
+        [glue.getInterceptorLibrary(),
+         glue.registerOneShotInterceptor(node.selector),
+         visitExpressionList(node.arguments)])
+        .withSourceInformation(node.sourceInformation);
+  }
+
+  @override
   js.Expression visitLiteralList(tree_ir.LiteralList node) {
     registry.registerInstantiatedClass(glue.listClass);
     List<js.Expression> entries = visitExpressionList(node.values);
@@ -399,6 +400,19 @@
     return new js.This();
   }
 
+  /// Ensure that 'instanceof' checks may be performed against [class_].
+  ///
+  /// Even if the class is never instantiated, a JS constructor must be emitted
+  /// so the 'instanceof' expression does not throw an exception at runtime.
+  ///
+  /// It does not help to ask the class world if the class is instantiated,
+  /// because it could still get tree-shaken if it is unused after optimization.
+  void registerInstanceofCheck(ClassElement class_) {
+    // TODO(asgerf): This is the only hook we have to ensure the JS constructor
+    //   gets emitted, but it is very imprecise. We should do better.
+    registry.registerInstantiatedClass(class_);
+  }
+
   @override
   js.Expression visitTypeOperator(tree_ir.TypeOperator node) {
     js.Expression value = visitExpression(node.value);
@@ -406,7 +420,6 @@
     DartType type = node.type;
     if (type is InterfaceType) {
       registry.registerTypeUse(new TypeUse.isCheck(type));
-      //glue.registerIsCheck(type, registry);
       ClassElement clazz = type.element;
 
       if (glue.isStringClass(clazz)) {
@@ -419,6 +432,11 @@
           return js.js(r'typeof # === "boolean"', <js.Expression>[value]);
         }
         // TODO(sra): Implement fast cast via calling 'boolTypeCast'.
+      } else if (node.isTypeTest &&
+                 node.typeArguments.isEmpty &&
+                 glue.mayGenerateInstanceofCheck(type)) {
+        registerInstanceofCheck(clazz);
+        return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]);
       }
 
       // The helper we use needs the JSArray class to exist, but for some
@@ -823,7 +841,7 @@
           new StaticUse.staticTearOff(node.element.declaration));
       return glue.isolateStaticClosureAccess(node.element);
     }
-    if (glue.isLazilyInitialized(node.element)) {
+    if (node.useLazyGetter) {
       // Read a lazily initialized field.
       registry.registerStaticUse(
           new StaticUse.staticInit(node.element.declaration));
@@ -945,6 +963,24 @@
   }
 
   @override
+  void visitNullCheck(tree_ir.NullCheck node) {
+    js.Expression value = visitExpression(node.value);
+    js.Expression access = node.selector != null
+        ? js.js('#.#', [value, glue.invocationName(node.selector)])
+        : js.js('#.toString', [value]);
+    if (node.condition != null) {
+      js.Expression condition = visitExpression(node.condition);
+      js.Statement body = isNullReturn(node.next)
+          ? new js.ExpressionStatement(access)
+          : new js.Return(access);
+      accumulator.add(new js.If.noElse(condition, body));
+    } else {
+      accumulator.add(new js.ExpressionStatement(access));
+    }
+    visitStatement(node.next);
+  }
+
+  @override
   js.Expression visitApplyBuiltinOperator(tree_ir.ApplyBuiltinOperator node) {
     List<js.Expression> args = visitExpressionList(node.arguments);
     switch (node.operator) {
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index 463d6da..b7d4c24 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -292,4 +292,12 @@
   }
 
   FunctionElement get closureFromTearOff => _backend.helpers.closureFromTearOff;
+
+  js.Name registerOneShotInterceptor(Selector selector) {
+    return _backend.registerOneShotInterceptor(selector);
+  }
+
+  bool mayGenerateInstanceofCheck(DartType type) {
+    return _backend.mayGenerateInstanceofCheck(type);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index cad67af..78f61cb 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -27,6 +27,7 @@
 import '../../cps_ir/optimizers.dart';
 import '../../cps_ir/optimizers.dart' as cps_opt;
 import '../../cps_ir/type_mask_system.dart';
+import '../../cps_ir/finalize.dart' show Finalize;
 import '../../diagnostics/invariant.dart' show
     DEBUG_MODE;
 import '../../elements/elements.dart';
@@ -208,14 +209,15 @@
       applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new RedundantRefinementEliminator(typeSystem), cpsFunction);
-      applyCpsPass(new GVN(compiler), cpsFunction);
-      applyCpsPass(new RemoveRefinements(), cpsFunction);
+      applyCpsPass(new EagerlyLoadStatics(), cpsFunction);
+      applyCpsPass(new GVN(compiler, typeSystem), cpsFunction);
+      applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
+      applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new ScalarReplacer(compiler), cpsFunction);
       applyCpsPass(new MutableVariableEliminator(), cpsFunction);
       applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
       applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-      applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new OptimizeInterceptors(backend), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
@@ -224,6 +226,7 @@
   }
 
   tree_ir.FunctionDefinition compileToTreeIr(cps.FunctionDefinition cpsNode) {
+    applyCpsPass(new Finalize(backend), cpsNode);
     tree_builder.Builder builder = new tree_builder.Builder(
         reporter.internalError);
     tree_ir.FunctionDefinition treeNode =
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 5b87b15..0550d8d 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -153,9 +153,8 @@
    */
   @override
   jsAst.Expression visitString(StringConstantValue constant, [_]) {
-    StringBuffer sb = new StringBuffer();
-    writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb);
-    return new jsAst.LiteralString('"$sb"');
+    return js.escapedString(constant.primitiveValue.slowToString(),
+                            ascii: true);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 2eabee0..3d3270c 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -217,17 +217,22 @@
     } else if (selector.isIndex || selector.isIndexSet) {
       // For an index operation, this code generates:
       //
-      //    if (receiver.constructor == Array || typeof receiver == "string") {
-      //      if (a0 >>> 0 === a0 && a0 < receiver.length) {
-      //        return receiver[a0];
+      //    if (typeof a0 === "number") {
+      //      if (receiver.constructor == Array ||
+      //          typeof receiver == "string") {
+      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
+      //          return receiver[a0];
+      //        }
       //      }
       //    }
       //
       // For an index set operation, this code generates:
       //
-      //    if (receiver.constructor == Array && !receiver.immutable$list) {
-      //      if (a0 >>> 0 === a0 && a0 < receiver.length) {
-      //        return receiver[a0] = a1;
+      //    if (typeof a0 === "number") {
+      //      if (receiver.constructor == Array && !receiver.immutable$list) {
+      //        if (a0 >>> 0 === a0 && a0 < receiver.length) {
+      //          return receiver[a0] = a1;
+      //        }
       //      }
       //    }
       bool containsArray = classes.contains(helpers.jsArrayClass);
@@ -270,9 +275,10 @@
         }
 
         return js.statement('''
-          if (#)
-            if ((a0 >>> 0) === a0 && a0 < receiver.length)
-              return receiver[a0];
+          if (typeof a0 === "number")
+            if (#)
+              if ((a0 >>> 0) === a0 && a0 < receiver.length)
+                return receiver[a0];
           ''', typeCheck);
       } else {
         jsAst.Expression typeCheck;
@@ -285,9 +291,10 @@
         }
 
         return js.statement(r'''
-          if (# && !receiver.immutable$list &&
-              (a0 >>> 0) === a0 && a0 < receiver.length)
-            return receiver[a0] = a1;
+          if (typeof a0 === "number")
+            if (# && !receiver.immutable$list &&
+                (a0 >>> 0) === a0 && a0 < receiver.length)
+              return receiver[a0] = a1;
           ''', typeCheck);
       }
     }
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 6006bc9..6defd7d 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -1092,7 +1092,7 @@
         if (element == null) {
           if (combinator.isHide) {
             if (library.isPackageLibrary &&
-                !reporter.options.showPackageWarnings) {
+                reporter.options.hidePackageWarnings) {
               // Only report hide hint on packages if we show warnings on these:
               // The hide may be non-empty in some versions of the package, in
               // which case you shouldn't remove the combinator.
diff --git a/pkg/compiler/lib/src/parser/partial_elements.dart b/pkg/compiler/lib/src/parser/partial_elements.dart
index e26d838..d72c6b7 100644
--- a/pkg/compiler/lib/src/parser/partial_elements.dart
+++ b/pkg/compiler/lib/src/parser/partial_elements.dart
@@ -297,7 +297,9 @@
     // TODO(johnniwinther): Compute this in the resolver.
     VariableDefinitions node = parseNode(element, resolution.parsing);
     if (node.type != null) {
-      type = resolution.resolveTypeAnnotation(element, node.type);
+      type = resolution.reporter.withCurrentElement(element, () {
+        return resolution.resolveTypeAnnotation(element, node.type);
+      });
     } else {
       type = const DynamicType();
     }
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index ce4e93c..aa70072 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -66,7 +66,9 @@
     return node.receiver.asIdentifier().isThis();
   }
 
-  reportDuplicateInitializerError(Element field, Node init, Node existing) {
+  reportDuplicateInitializerError(Element field,
+                                  Node init,
+                                  Spannable existing) {
     reporter.reportError(
         reporter.createMessage(
             init,
@@ -90,7 +92,9 @@
       field.parseNode(visitor.resolution.parsing);
       Expression initializer = field.initializer;
       if (initializer != null) {
-        reportDuplicateInitializerError(field, init, initializer);
+        reportDuplicateInitializerError(field, init,
+            reporter.withCurrentElement(field,
+                () => reporter.spanFromSpannable(initializer)));
       }
     }
     initialized[field] = init;
diff --git a/pkg/compiler/lib/src/resolution/enum_creator.dart b/pkg/compiler/lib/src/resolution/enum_creator.dart
index f9913c2..953225b 100644
--- a/pkg/compiler/lib/src/resolution/enum_creator.dart
+++ b/pkg/compiler/lib/src/resolution/enum_creator.dart
@@ -180,6 +180,8 @@
   }
 }
 
+// TODO(johnniwinther): Avoid creating synthesized ASTs for enums when SSA is
+// removed.
 class EnumCreator {
   final DiagnosticReporter reporter;
   final CoreTypes coreTypes;
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 8426021..da82058 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -802,7 +802,7 @@
       registry.registerFeature(Feature.COMPILE_TIME_ERROR);
       return new StaticAccess.invalid(error);
     }
-    registry.registerSuperUse(node);
+    registry.registerSuperUse(reporter.spanFromSpannable(node));
     return null;
   }
 
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index a01b17c..5fc06e1 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -19,6 +19,7 @@
     Compiler;
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../diagnostics/source_span.dart';
 import '../enqueue.dart' show
     ResolutionEnqueuer;
 import '../elements/elements.dart';
@@ -314,8 +315,8 @@
     worldImpact.registerTypeUse(typeUse);
   }
 
-  void registerSuperUse(Node node) {
-    mapping.addSuperUse(node);
+  void registerSuperUse(SourceSpan span) {
+    mapping.addSuperUse(span);
   }
 
   void registerTypeLiteral(Send node, DartType type) {
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 737b5f0..bcb686e 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -513,7 +513,7 @@
    * called by [resolveClass] and [ClassSupertypeResolver].
    */
   void loadSupertypes(BaseClassElementX cls, Spannable from) {
-    reporter.withCurrentElement(cls, () => measure(() {
+    measure(() {
       if (cls.supertypeLoadState == STATE_DONE) return;
       if (cls.supertypeLoadState == STATE_STARTED) {
         reporter.reportErrorMessage(
@@ -540,7 +540,7 @@
           cls.supertypeLoadState = STATE_DONE;
         }
       });
-    }));
+    });
   }
 
   // TODO(johnniwinther): Remove this queue when resolution has been split into
@@ -763,7 +763,7 @@
                            ClassElement mixin) {
     // TODO(johnniwinther): Avoid the use of [TreeElements] here.
     if (resolutionTree == null) return;
-    Iterable<Node> superUses = resolutionTree.superUses;
+    Iterable<SourceSpan> superUses = resolutionTree.superUses;
     if (superUses.isEmpty) return;
     DiagnosticMessage error = reporter.createMessage(
         mixinApplication,
@@ -771,7 +771,7 @@
         {'className': mixin.name});
     // Show the user the problematic uses of 'super' in the mixin.
     List<DiagnosticMessage> infos = <DiagnosticMessage>[];
-    for (Node use in superUses) {
+    for (SourceSpan use in superUses) {
       infos.add(reporter.createMessage(
           use,
           MessageKind.ILLEGAL_MIXIN_SUPER_USE));
diff --git a/pkg/compiler/lib/src/resolution/tree_elements.dart b/pkg/compiler/lib/src/resolution/tree_elements.dart
index e04b537..a60bb79 100644
--- a/pkg/compiler/lib/src/resolution/tree_elements.dart
+++ b/pkg/compiler/lib/src/resolution/tree_elements.dart
@@ -7,6 +7,7 @@
 import '../common.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../diagnostics/source_span.dart';
 import '../elements/elements.dart';
 import '../types/types.dart' show
     TypeMask;
@@ -22,7 +23,7 @@
 
 abstract class TreeElements {
   AnalyzableElement get analyzedElement;
-  Iterable<Node> get superUses;
+  Iterable<SourceSpan> get superUses;
 
   void forEachConstantNode(f(Node n, ConstantExpression c));
 
@@ -111,7 +112,7 @@
   Map<Spannable, TypeMask> _typeMasks;
   Map<Node, DartType> _types;
   Map<Node, DartType> typesCache = <Node, DartType>{};
-  Setlet<Node> _superUses;
+  Setlet<SourceSpan> _superUses;
   Map<Node, ConstantExpression> _constants;
   Map<VariableElement, List<Node>> _potentiallyMutated;
   Map<Node, Map<VariableElement, List<Node>>> _potentiallyMutatedIn;
@@ -191,15 +192,15 @@
 
   DartType getType(Node node) => _types != null ? _types[node] : null;
 
-  Iterable<Node> get superUses {
-    return _superUses != null ? _superUses : const <Node>[];
+  Iterable<SourceSpan> get superUses {
+    return _superUses != null ? _superUses : const <SourceSpan>[];
   }
 
-  void addSuperUse(Node node) {
+  void addSuperUse(SourceSpan span) {
     if (_superUses == null) {
-      _superUses = new Setlet<Node>();
+      _superUses = new Setlet<SourceSpan>();
     }
-    _superUses.add(node);
+    _superUses.add(span);
   }
 
   Selector _getSelector(Spannable node) {
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart b/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
index 18bab39..3b3a74a 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/pull_into_initializers.dart
@@ -168,6 +168,16 @@
     return node;
   }
 
+  Statement visitNullCheck(NullCheck node) {
+    if (node.condition != null) {
+      node.condition = visitExpression(node.condition);
+      // The value occurs in conditional context, so don't pull from that.
+    } else {
+      node.value = visitExpression(node.value);
+    }
+    return node;
+  }
+
   Expression visitAssign(Assign node) {
     bool inImpureContext = impureCounter > 0;
     bool inBranch = branchCounter > 0;
@@ -249,6 +259,12 @@
     return node;
   }
 
+  Expression visitOneShotInterceptor(OneShotInterceptor node) {
+    super.visitOneShotInterceptor(node);
+    ++impureCounter;
+    return node;
+  }
+
   Expression visitConditional(Conditional node) {
     node.condition = visitExpression(node.condition);
     // Visit the branches to detect impure subexpressions, but do not pull
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index ecdbccb..f38dcf3 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -503,6 +503,11 @@
     return node;
   }
 
+  Expression visitOneShotInterceptor(OneShotInterceptor node) {
+    _rewriteList(node.arguments);
+    return node;
+  }
+
   Expression visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
     if (node.receiverIsNotNull) {
       _rewriteList(node.arguments);
@@ -1144,10 +1149,7 @@
     // Some arguments will get inserted in a JS code template.  The arguments
     // will not always be evaluated (e.g. the second placeholder in the template
     // '# && #').
-
-    // TODO(sra): Find out which tree_ir expressions are not nullable. It helps
-    // a lot with templates like '#.push(#)'.
-    bool isNullable(e) => true;
+    bool isNullable(int position) => node.nullableArguments[position];
 
     int safeArguments =
       PlaceholderSafetyAnalysis.analyze(node.codeTemplate.ast, isNullable);
@@ -1185,6 +1187,23 @@
     node.next = visitStatement(node.next);
     return node;
   }
+
+  @override
+  Statement visitNullCheck(NullCheck node) {
+    inEmptyEnvironment(() {
+      node.next = visitStatement(node.next);
+    });
+    if (node.condition != null) {
+      inEmptyEnvironment(() {
+        // Value occurs in conditional context.
+        node.value = visitExpression(node.value);
+      });
+      node.condition = visitExpression(node.condition);
+    } else {
+      node.value = visitExpression(node.value);
+    }
+    return node;
+  }
 }
 
 /// Result of combining two expressions, with the potential for reverting the
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 84c5200..c36a394 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -98,6 +98,7 @@
   /// Obtains the variable representing the given primitive. Returns null for
   /// primitives that have no reference and do not need a variable.
   Variable getVariable(cps_ir.Primitive primitive) {
+    primitive = primitive.effectiveDefinition;
     return primitive2variable.putIfAbsent(primitive,
         () => new Variable(currentElement, primitive.hint));
   }
@@ -107,10 +108,16 @@
   /// This increments the reference count for the given variable, so the
   /// returned expression must be used in the tree.
   Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
-    if (thisParameter != null && reference.definition == thisParameter) {
+    cps_ir.Primitive prim = reference.definition.effectiveDefinition;
+    if (thisParameter != null && prim == thisParameter) {
       return new This();
     }
-    return new VariableUse(getVariable(reference.definition));
+    return new VariableUse(getVariable(prim));
+  }
+
+  Expression getVariableUseOrNull(
+        cps_ir.Reference<cps_ir.Primitive> reference) {
+    return reference == null ? null : getVariableUse(reference);
   }
 
   Label getLabel(cps_ir.Continuation cont) {
@@ -452,7 +459,7 @@
 
   Expression visitGetField(cps_ir.GetField node) {
     return new GetField(getVariableUse(node.object), node.field,
-        objectIsNotNull: node.objectIsNotNull);
+        objectIsNotNull: !node.object.definition.type.isNullable);
   }
 
   Expression visitCreateBox(cps_ir.CreateBox node) {
@@ -496,10 +503,6 @@
     );
   }
 
-  FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
-    return createInnerBuilder().buildFunction(function);
-  }
-
   Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
     return new ReifyRuntimeType(
         getVariableUse(node.value), node.sourceInformation);
@@ -553,7 +556,7 @@
     return new ApplyBuiltinMethod(node.method,
         getVariableUse(node.receiver),
         translateArguments(node.arguments),
-        receiverIsNotNull: node.receiverIsNotNull);
+        receiverIsNotNull: !node.receiver.definition.type.isNullable);
   }
 
   Expression visitGetLength(cps_ir.GetLength node) {
@@ -578,13 +581,29 @@
   }
 
   Expression visitInvokeMethod(cps_ir.InvokeMethod node) {
+    if (node.callingConvention == cps_ir.CallingConvention.OneShotIntercepted) {
+      List<Expression> arguments = new List.generate(
+          1 + node.arguments.length,
+          (n) => getVariableUse(n == 0 ? node.receiver : node.arguments[n - 1]),
+          growable: false);
+      return new OneShotInterceptor(node.selector, node.mask, arguments,
+          node.sourceInformation);
+    }
     InvokeMethod invoke = new InvokeMethod(
         getVariableUse(node.receiver),
         node.selector,
         node.mask,
         translateArguments(node.arguments),
         node.sourceInformation);
-    invoke.receiverIsNotNull = node.receiverIsNotNull;
+    // Sometimes we know the Dart receiver is non-null because it has been
+    // refined, which implies that the JS receiver also can not be null at the
+    // use-site.  Interceptors are not refined, so this information is not
+    // always available on the JS receiver.
+    // Also check the JS receiver's type, however, because sometimes we know an
+    // interceptor is non-null because it intercepts JSNull.
+    invoke.receiverIsNotNull =
+        !node.dartReceiver.type.isNullable ||
+        !node.receiver.definition.type.isNullable;
     return invoke;
   }
 
@@ -614,21 +633,16 @@
   visitForeignCode(cps_ir.ForeignCode node) {
     List<Expression> arguments =
         node.arguments.map(getVariableUse).toList(growable: false);
-    if (HasCapturedArguments.check(node.codeTemplate.ast)) {
-      for (Expression arg in arguments) {
-        if (arg is VariableUse) {
-          arg.variable.isCaptured = true;
-        } else {
-          // TODO(asgerf): Avoid capture of 'this'.
-        }
-      }
-    }
+    List<bool> nullableArguments = node.arguments
+        .map((argument) => argument.definition.type.isNullable)
+        .toList(growable: false);
     if (node.codeTemplate.isExpression) {
       return new ForeignExpression(
           node.codeTemplate,
           node.type,
           arguments,
           node.nativeBehavior,
+          nullableArguments,
           node.dependency);
     } else {
       return (Statement next) {
@@ -638,15 +652,23 @@
             node.type,
             arguments,
             node.nativeBehavior,
+            nullableArguments,
             node.dependency);
       };
     }
   }
 
+  visitNullCheck(cps_ir.NullCheck node) => (Statement next) {
+    return new NullCheck(
+        condition: getVariableUseOrNull(node.condition),
+        value: getVariableUse(node.value),
+        selector: node.selector,
+        next: next,
+        sourceInformation: node.sourceInformation);
+  };
+
   Expression visitGetLazyStatic(cps_ir.GetLazyStatic node) {
-    // In the tree IR, GetStatic handles lazy fields because we do not need
-    // as fine-grained control over side effects.
-    return new GetStatic(node.element, node.sourceInformation);
+    return new GetStatic.lazy(node.element, node.sourceInformation);
   }
 
   @override
@@ -662,8 +684,13 @@
   }
 
   @override
-  Expression visitRefinement(cps_ir.Refinement node) {
-    throw 'Unexpected Refinement node in tree builder';
+  visitRefinement(cps_ir.Refinement node) {
+    return (Statement next) => next; // Compile to nothing.
+  }
+
+  @override
+  Expression visitBoundsCheck(cps_ir.BoundsCheck node) {
+    throw 'Unexpected BoundsCheck node in tree builder';
   }
 
   /********** UNUSED VISIT METHODS *************/
@@ -679,28 +706,3 @@
   visitContinuation(cps_ir.Continuation node) => unexpectedNode(node);
   visitMutableVariable(cps_ir.MutableVariable node) => unexpectedNode(node);
 }
-
-class HasCapturedArguments extends js.BaseVisitor {
-  static bool check(js.Node node) {
-    HasCapturedArguments visitor = new HasCapturedArguments();
-    node.accept(visitor);
-    return visitor.found;
-  }
-
-  int enclosingFunctions = 0;
-  bool found = false;
-
-  @override
-  visitFun(js.Fun node) {
-    ++enclosingFunctions;
-    node.visitChildren(this);
-    --enclosingFunctions;
-  }
-
-  @override
-  visitInterpolatedNode(js.InterpolatedNode node) {
-    if (enclosingFunctions > 0) {
-      found = true;
-    }
-  }
-}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 80e4f28..215cf3a 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -268,6 +268,26 @@
   }
 }
 
+/// Call a method using a one-shot interceptor.
+///
+/// There is no explicit receiver, the first argument serves that purpose.
+class OneShotInterceptor extends Expression implements Invoke {
+  final Selector selector;
+  final TypeMask mask;
+  final List<Expression> arguments;
+  final SourceInformation sourceInformation;
+
+  OneShotInterceptor(this.selector,
+                     this.mask,
+                     this.arguments,
+                     this.sourceInformation);
+
+  accept(ExpressionVisitor visitor) => visitor.visitOneShotInterceptor(this);
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitOneShotInterceptor(this, arg);
+  }
+}
+
 /**
  * A constant.
  */
@@ -744,15 +764,17 @@
       visitor.visitGetTypeTestProperty(this, arg);
 }
 
-
 /// Read the value of a field, possibly provoking its initializer to evaluate,
 /// or tear off a static method.
 class GetStatic extends Expression {
   Element element;
   SourceInformation sourceInformation;
+  bool useLazyGetter = false;
 
   GetStatic(this.element, this.sourceInformation);
 
+  GetStatic.lazy(this.element, this.sourceInformation) : useLazyGetter = true;
+
   accept(ExpressionVisitor visitor) => visitor.visitGetStatic(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetStatic(this, arg);
 }
@@ -865,17 +887,22 @@
   final types.TypeMask type;
   final List<Expression> arguments;
   final native.NativeBehavior nativeBehavior;
+  final List<bool> nullableArguments;  // One 'bit' per argument.
   final Element dependency;
 
   ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior,
-      this.dependency);
+      this.nullableArguments, this.dependency) {
+    assert(arguments.length == nullableArguments.length);
+  }
 }
 
 class ForeignExpression extends ForeignCode implements Expression {
-  ForeignExpression(js.Template codeTemplate, types.TypeMask type,
+  ForeignExpression(
+      js.Template codeTemplate, types.TypeMask type,
       List<Expression> arguments, native.NativeBehavior nativeBehavior,
+      List<bool> nullableArguments,
       Element dependency)
-      : super(codeTemplate, type, arguments, nativeBehavior,
+      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
           dependency);
 
   accept(ExpressionVisitor visitor) {
@@ -888,10 +915,12 @@
 }
 
 class ForeignStatement extends ForeignCode implements Statement {
-  ForeignStatement(js.Template codeTemplate, types.TypeMask type,
+  ForeignStatement(
+      js.Template codeTemplate, types.TypeMask type,
       List<Expression> arguments, native.NativeBehavior nativeBehavior,
+      List<bool> nullableArguments,
       Element dependency)
-      : super(codeTemplate, type, arguments, nativeBehavior,
+      : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
           dependency);
 
   accept(StatementVisitor visitor) {
@@ -957,6 +986,25 @@
   }
 }
 
+class NullCheck extends Statement {
+  Expression condition;
+  Expression value;
+  Selector selector;
+  Statement next;
+  SourceInformation sourceInformation;
+
+  NullCheck({this.condition, this.value, this.selector, this.next,
+      this.sourceInformation});
+
+  accept(StatementVisitor visitor) {
+    return visitor.visitNullCheck(this);
+  }
+
+  accept1(StatementVisitor1 visitor, arg) {
+    return visitor.visitNullCheck(this, arg);
+  }
+}
+
 abstract class ExpressionVisitor<E> {
   E visitExpression(Expression node) => node.accept(this);
   E visitVariableUse(VariableUse node);
@@ -965,6 +1013,7 @@
   E visitInvokeMethod(InvokeMethod node);
   E visitInvokeMethodDirectly(InvokeMethodDirectly node);
   E visitInvokeConstructor(InvokeConstructor node);
+  E visitOneShotInterceptor(OneShotInterceptor node);
   E visitConstant(Constant node);
   E visitThis(This node);
   E visitConditional(Conditional node);
@@ -1002,6 +1051,7 @@
   E visitInvokeMethod(InvokeMethod node, A arg);
   E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
   E visitInvokeConstructor(InvokeConstructor node, A arg);
+  E visitOneShotInterceptor(OneShotInterceptor node, A arg);
   E visitConstant(Constant node, A arg);
   E visitThis(This node, A arg);
   E visitConditional(Conditional node, A arg);
@@ -1047,6 +1097,7 @@
   S visitUnreachable(Unreachable node);
   S visitForeignStatement(ForeignStatement node);
   S visitYield(Yield node);
+  S visitNullCheck(NullCheck node);
 }
 
 abstract class StatementVisitor1<S, A> {
@@ -1065,6 +1116,7 @@
   S visitUnreachable(Unreachable node, A arg);
   S visitForeignStatement(ForeignStatement node, A arg);
   S visitYield(Yield node, A arg);
+  S visitNullCheck(NullCheck node, A arg);
 }
 
 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
@@ -1100,6 +1152,10 @@
     node.arguments.forEach(visitExpression);
   }
 
+  visitOneShotInterceptor(OneShotInterceptor node) {
+    node.arguments.forEach(visitExpression);
+  }
+
   visitConstant(Constant node) {}
 
   visitThis(This node) {}
@@ -1277,6 +1333,12 @@
     visitExpression(node.input);
     visitStatement(node.next);
   }
+
+  visitNullCheck(NullCheck node) {
+    if (node.condition != null) visitExpression(node.condition);
+    visitExpression(node.value);
+    visitStatement(node.next);
+  }
 }
 
 abstract class Transformer implements ExpressionVisitor<Expression>,
@@ -1321,6 +1383,11 @@
     return node;
   }
 
+  visitOneShotInterceptor(OneShotInterceptor node) {
+    _replaceExpressions(node.arguments);
+    return node;
+  }
+
   visitConstant(Constant node) => node;
 
   visitThis(This node) => node;
@@ -1534,6 +1601,15 @@
     node.next = visitStatement(node.next);
     return node;
   }
+
+  visitNullCheck(NullCheck node) {
+    if (node.condition != null) {
+      node.condition = visitExpression(node.condition);
+    }
+    node.value = visitExpression(node.value);
+    node.next = visitStatement(node.next);
+    return node;
+  }
 }
 
 class FallthroughTarget {
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index 3f08e95..f43f287 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -182,6 +182,11 @@
     _addStatement(node);
     visitStatement(node.next);
   }
+
+  visitNullCheck(NullCheck node) {
+    _addStatement(node);
+    visitStatement(node.next);
+  }
 }
 
 class TreeTracer extends TracerUtil with StatementVisitor {
@@ -346,6 +351,11 @@
     String name = node.hasStar ? 'yield*' : 'yield';
     printStatement(null, '$name ${expr(node.input)}');
   }
+
+  @override
+  visitNullCheck(NullCheck node) {
+    printStatement(null, 'NullCheck ${expr(node.value)}');
+  }
 }
 
 class SubexpressionVisitor extends ExpressionVisitor<String> {
@@ -401,6 +411,12 @@
     return "$keyword $callName($args)";
   }
 
+  String visitOneShotInterceptor(OneShotInterceptor node) {
+    String name = node.selector.name;
+    String args = formatArguments(node);
+    return "oneshot $name($args)";
+  }
+
   String visitLiteralList(LiteralList node) {
     String values = node.values.map(visitExpression).join(', ');
     return "list [$values]";
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 63a421d..4a8397e 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -94,26 +94,31 @@
     bool useSubclass = masks.every((e) => !e.isSubtype);
     bool isNullable = masks.any((e) => e.isNullable);
 
+    List<ClassElement> masksBases = masks.map((mask) => mask.base).toList();
     Iterable<ClassElement> candidates =
-        classWorld.commonSupertypesOf(masks.map((mask) => mask.base));
+        classWorld.commonSupertypesOf(masksBases);
 
     // Compute the best candidate and its kind.
     ClassElement bestElement;
     int bestKind;
     int bestSize;
     for (ClassElement candidate in candidates) {
-      Iterable<ClassElement> subclasses = useSubclass
-          ? classWorld.strictSubclassesOf(candidate)
-          : const <ClassElement>[];
+      bool isInstantiatedStrictSubclass(cls) => cls != candidate &&
+          classWorld.isDirectlyInstantiated(cls) &&
+          classWorld.isSubclassOf(cls, candidate);
+
       int size;
       int kind;
-      if (masks.every((t) => subclasses.contains(t.base))) {
+      if (useSubclass && masksBases.every(isInstantiatedStrictSubclass)) {
         // If both [this] and [other] are subclasses of the supertype,
         // then we prefer to construct a subclass type mask because it
         // will always be at least as small as the corresponding
         // subtype type mask.
         kind = FlatTypeMask.SUBCLASS;
-        size = subclasses.length;
+        // TODO(sigmund, johnniwinther): computing length here (and below) is
+        // expensive. If we can't prevent `flatten` from being called a lot, it
+        // might be worth caching results.
+        size = classWorld.strictSubclassesOf(candidate).length;
         assert(size <= classWorld.strictSubtypesOf(candidate).length);
       } else {
         kind = FlatTypeMask.SUBTYPE;
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 8fd7e6c..22adbfa 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -310,6 +310,8 @@
   /// Returns `true` if all directly instantiated classes that implement [cls]
   /// extend it.
   bool hasOnlySubclasses(ClassElement cls) {
+    // TODO(johnniwinther): move this to ClassSet?
+    if (cls == objectClass) return true;
     Iterable<ClassElement> subtypes = strictSubtypesOf(cls);
     if (subtypes == null) return true;
     Iterable<ClassElement> subclasses = strictSubclassesOf(cls);
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index c885986..3b7e3ea 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -17,6 +17,8 @@
     path: ../../../../dart2js_info
   lookup_map:
     path: ../lookup_map
+  dart_messages:
+    path: ../dart_messages
 
 # Uncomment if running gclient, so you can depend directly on the downloaded
 # versions of dart2js's transitive dependencies:
diff --git a/pkg/dart_messages/bin/json_converter.dart b/pkg/dart_messages/bin/json_converter.dart
new file mode 100644
index 0000000..8d9b8ca
--- /dev/null
+++ b/pkg/dart_messages/bin/json_converter.dart
@@ -0,0 +1,20 @@
+// 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.
+
+import 'dart:convert';
+import 'dart:io';
+
+import '../lib/shared_messages.dart' as shared_messages;
+
+/// Translates the shared messages in `../lib/shared_messages` to JSON and
+/// emits it into `../lib/shared_messages.json`.
+void main() {
+  var input = shared_messages.MESSAGES;
+  var outPath =
+      Platform.script.resolve('../lib/shared_messages.json').toFilePath();
+  print("Input: ${input.length} entries");
+  print("Output: $outPath");
+  new File(outPath).writeAsStringSync(JSON.encode(shared_messages.MESSAGES));
+  print("Done");
+}
diff --git a/pkg/dart_messages/bin/message_id.dart b/pkg/dart_messages/bin/message_id.dart
new file mode 100644
index 0000000..2d7ed53
--- /dev/null
+++ b/pkg/dart_messages/bin/message_id.dart
@@ -0,0 +1,35 @@
+// 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.
+
+import 'dart:math' as math;
+
+import '../lib/shared_messages.dart' as shared_messages;
+
+math.Random random = new math.Random();
+
+const idLength = 6;
+final $A = "A".codeUnitAt(0);
+final $Z = "Z".codeUnitAt(0);
+
+String computeId() {
+  List charCodes = [];
+  for (int i = 0; i < idLength; i++) {
+    charCodes.add($A + random.nextInt($Z - $A));
+  }
+  return new String.fromCharCodes(charCodes);
+}
+
+/// Computes a random message ID that hasn't been used before.
+void main() {
+  var usedIds =
+      shared_messages.MESSAGES.values.map((entry) => entry['id']).toSet();
+
+  print("${usedIds.length} existing ids");
+
+  var newId;
+  do {
+    newId = computeId();
+  } while (!usedIds.contains(newId));
+  print("Available id: $newId");
+}
diff --git a/pkg/compiler/lib/src/diagnostics/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
similarity index 89%
rename from pkg/compiler/lib/src/diagnostics/shared_messages.dart
rename to pkg/dart_messages/lib/shared_messages.dart
index 0a4d2ab..bd51f58 100644
--- a/pkg/compiler/lib/src/diagnostics/shared_messages.dart
+++ b/pkg/dart_messages/lib/shared_messages.dart
@@ -2,10 +2,11 @@
 // 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 is parsed by JavaScript and must not use fancy Dart constructs.
-// It can contain JSON like constructs and "//" comments (but not "/*" "*/").
-// It must have one assignment (`final MESSAGES =`).
-// All strings must be raw strings.
+// An update to this file must be followed by regenerating the corresponding
+// json file. Use `json_converter.dart` in the bin directory.
+//
+// Every message in this file must have an id. Use `message_id.dart` in the
+// bin directory to generate a fresh one.
 
 // The messages in this file should meet the following guide lines:
 //
@@ -57,5 +58,5 @@
 // 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
 // combine the first two in [template] and the last in [howToFix].
 
-final MESSAGES = {
+final Map<String, Map> MESSAGES = {
 };
diff --git a/pkg/dart_messages/lib/shared_messages.json b/pkg/dart_messages/lib/shared_messages.json
new file mode 100644
index 0000000..9e26dfe
--- /dev/null
+++ b/pkg/dart_messages/lib/shared_messages.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/pkg/dart_messages/pubspec.yaml b/pkg/dart_messages/pubspec.yaml
new file mode 100644
index 0000000..2df3361
--- /dev/null
+++ b/pkg/dart_messages/pubspec.yaml
@@ -0,0 +1,4 @@
+# This package is not intended to be published.
+name: dart_messages
+#version: do-not-upload
+dependencies:
diff --git a/pkg/dart_messages/test/dart_messages_test.dart b/pkg/dart_messages/test/dart_messages_test.dart
new file mode 100644
index 0000000..3983773
--- /dev/null
+++ b/pkg/dart_messages/test/dart_messages_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+import 'dart:convert';
+import 'dart:io';
+
+import '../lib/shared_messages.dart';
+
+void testJsonIsUpdated() {
+  var packageRoot = Platform.packageRoot;
+  if (packageRoot == null || packageRoot == "") {
+    throw new UnsupportedError("This test requires a package root.");
+  }
+  var jsonUri =
+      Uri.parse(packageRoot).resolve('dart_messages/shared_messages.json');
+  var jsonPath = jsonUri.toFilePath();
+  var content = new File(jsonPath).readAsStringSync();
+  if (JSON.encode(MESSAGES) != content) {
+    print("The content of the Dart messages and the corresponding JSON file");
+    print("is not the same.");
+    print("Please run bin/json_converter to update the JSON file.");
+    throw "Content is not the same";
+  }
+}
+
+void testIdsAreUnique() {
+  var usedIds = new Set();
+  for (var entry in MESSAGES.values) {
+    var id = entry['id'];
+    if (!usedIds.add(id)) {
+      throw "Id appears twice: $id";
+    }
+  }
+}
+
+void main() {
+  testJsonIsUpdated();
+  testIdsAreUnique();
+}
diff --git a/pkg/fixnum/lib/src/int64.dart b/pkg/fixnum/lib/src/int64.dart
index 7ff28d2..769ef21 100644
--- a/pkg/fixnum/lib/src/int64.dart
+++ b/pkg/fixnum/lib/src/int64.dart
@@ -104,7 +104,7 @@
 
     if (negative) return _negate(d0, d1, d2);
 
-    return new Int64._bits(d0, d1, d2);
+    return Int64._masked(d0, d1, d2);
   }
 
   /**
@@ -131,18 +131,13 @@
       negative = true;
       value = -value - 1;
     }
-    if (_haveBigInts) {
-      v0 = _MASK & value;
-      v1 = _MASK & (value >> _BITS);
-      v2 = _MASK2 & (value >> _BITS01);
-    } else {
-      // Avoid using bitwise operations that coerce their input to 32 bits.
-      v2 = value ~/ 17592186044416; // 2^44
-      value -= v2 * 17592186044416;
-      v1 = value ~/ 4194304; // 2^22
-      value -= v1 * 4194304;
-      v0 = value;
-    }
+    // Avoid using bitwise operations that in JavaScript coerce their input to
+    // 32 bits.
+    v2 = value ~/ 17592186044416; // 2^44
+    value -= v2 * 17592186044416;
+    v1 = value ~/ 4194304; // 2^22
+    value -= v1 * 4194304;
+    v0 = value;
 
     if (negative) {
       v0 = ~v0;
@@ -202,7 +197,7 @@
     int d0 = _MASK & bottom;
     int d1 = ((0xfff & top) << 10) | (0x3ff & (bottom >> _BITS));
     int d2 = _MASK2 & (top >> 12);
-    return new Int64._bits(d0, d1, d2);
+    return  Int64._masked(d0, d1, d2);
   }
 
   // Returns the [Int64] representation of the specified value. Throws
@@ -325,7 +320,7 @@
     int a0 = _l & o._l;
     int a1 = _m & o._m;
     int a2 = _h & o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator |(other) {
@@ -333,7 +328,7 @@
     int a0 = _l | o._l;
     int a1 = _m | o._m;
     int a2 = _h | o._h;
-    return new Int64._bits(a0, a1, a2);
+    return Int64._masked(a0, a1, a2);
   }
 
   Int64 operator ^(other) {
@@ -629,23 +624,15 @@
     int l = _l;
     int m = _m;
     int h = _h;
-    bool negative = false;
+    // In the sum we add least significant to most significant so that in
+    // JavaScript double arithmetic rounding occurs on only the last addition.
     if ((_h & _SIGN_BIT_MASK) != 0) {
       l = _MASK & ~_l;
       m = _MASK & ~_m;
       h = _MASK2 & ~_h;
-      negative = true;
-    }
-
-    if (_haveBigInts) {
-      int result = (h << _BITS01) | (m << _BITS) | l;
-      return negative ? -result - 1 : result;
+      return -((1 + l) + (4194304 * m) + (17592186044416 * h));
     } else {
-      if (negative) {
-        return -((l + 1) + (m * 4194304) + (h * 17592186044416));
-      } else {
-        return (l + (m * 4194304)) + (h * 17592186044416);
-      }
+      return l + (4194304 * m) + (17592186044416 * h);
     }
   }
 
@@ -671,7 +658,6 @@
     if (isZero) return "0";
     Int64 x = this;
     String hexStr = "";
-    Int64 digit_f = new Int64(0xf);
     while (!x.isZero) {
       int digit = x._l & 0xf;
       hexStr = "${_hexDigit(digit)}$hexStr";
@@ -843,27 +829,8 @@
     return _sub(0, 0, 0, b0, b1, b2);
   }
 
-  // Determine whether the platform supports ints greater than 2^53
-  // without loss of precision.
-  static bool _haveBigIntsCached = null;
-
-  static bool get _haveBigInts {
-    if (_haveBigIntsCached == null) {
-      var x = 9007199254740992;
-      // Defeat compile-time constant folding.
-      if (2 + 2 != 4) {
-        x = 0;
-      }
-      var y = x + 1;
-      var same = y == x;
-      _haveBigIntsCached = !same;
-    }
-    return _haveBigIntsCached;
-  }
-
   String _hexDigit(int digit) => "0123456789ABCDEF"[digit];
 
-
   // Work around dart2js bugs with negative arguments to '>>' operator.
   static int _shiftRight(int x, int n) {
     if (x >= 0) {
diff --git a/pkg/fixnum/pubspec.yaml b/pkg/fixnum/pubspec.yaml
index b657f19..3d3bdaf 100644
--- a/pkg/fixnum/pubspec.yaml
+++ b/pkg/fixnum/pubspec.yaml
@@ -1,5 +1,5 @@
 name: fixnum
-version: 0.10.2
+version: 0.10.3
 author: Dart Team <misc@dartlang.org>
 description: Library for 32- and 64-bit fixed size integers.
 homepage: http://www.dartlang.org
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 67ea25c..5d680f5 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -299,18 +299,19 @@
   }
 
   /// Creates a literal js string from [value].
-  LiteralString escapedString(String value) {
+  LiteralString _legacyEscapedString(String value) {
    // Start by escaping the backslashes.
     String escaped = value.replaceAll('\\', '\\\\');
     // Do not escape unicode characters and ' because they are allowed in the
     // string literal anyway.
-    escaped = escaped.replaceAllMapped(new RegExp('\n|"|\b|\t|\v'), (match) {
+    escaped = escaped.replaceAllMapped(new RegExp('\n|"|\b|\t|\v|\r'), (match) {
       switch (match.group(0)) {
         case "\n" : return r"\n";
         case "\"" : return r'\"';
         case "\b" : return r"\b";
         case "\t" : return r"\t";
         case "\f" : return r"\f";
+        case "\r" : return r"\r";
         case "\v" : return r"\v";
       }
     });
@@ -322,6 +323,105 @@
   }
 
   /// Creates a literal js string from [value].
+  LiteralString escapedString(String value,
+       {bool utf8: false, bool ascii: false}) {
+    if (utf8 == false && ascii == false) return _legacyEscapedString(value);
+    if (utf8 && ascii) throw new ArgumentError('Cannot be both UTF8 and ASCII');
+
+    int singleQuotes = 0;
+    int doubleQuotes = 0;
+    int otherEscapes = 0;
+    int unpairedSurrogates = 0;
+
+    for (int rune in value.runes) {
+      if (rune == charCodes.$BACKSLASH) {
+        ++otherEscapes;
+      } else if (rune == charCodes.$SQ) {
+        ++singleQuotes;
+      } else if (rune == charCodes.$DQ) {
+        ++doubleQuotes;
+      } else if (rune == charCodes.$LF || rune == charCodes.$CR ||
+                 rune == charCodes.$LS || rune == charCodes.$PS) {
+        // Line terminators.
+        ++otherEscapes;
+      } else if (rune == charCodes.$BS || rune == charCodes.$TAB ||
+                 rune == charCodes.$VTAB || rune == charCodes.$FF) {
+        ++otherEscapes;
+      } else if (_isUnpairedSurrogate(rune)) {
+        ++unpairedSurrogates;
+      } else {
+        if (ascii && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
+          ++otherEscapes;
+        }
+      }
+    }
+
+    LiteralString finish(String quote, String contents) {
+      return new LiteralString('$quote$contents$quote');
+    }
+
+    if (otherEscapes == 0 && unpairedSurrogates == 0) {
+      if (doubleQuotes == 0) return finish('"', value);
+      if (singleQuotes == 0) return finish("'", value);
+    }
+
+    bool useSingleQuotes = singleQuotes < doubleQuotes;
+
+    StringBuffer sb = new StringBuffer();
+
+    for (int rune in value.runes) {
+      String escape = _irregularEscape(rune, useSingleQuotes);
+      if (escape != null) {
+        sb.write(escape);
+        continue;
+      }
+      if (rune == charCodes.$LS ||
+          rune == charCodes.$PS ||
+          _isUnpairedSurrogate(rune) ||
+          ascii && (rune < charCodes.$SPACE || rune >= charCodes.$DEL)) {
+        if (rune < 0x100) {
+          sb.write(r'\x');
+          sb.write(rune.toRadixString(16).padLeft(2, '0'));
+        } else if (rune < 0x10000) {
+          sb.write(r'\u');
+          sb.write(rune.toRadixString(16).padLeft(4, '0'));
+        } else {
+          // Not all browsers accept the ES6 \u{zzzzzz} encoding, so emit two
+          // surrogate pairs.
+          var bits = rune - 0x10000;
+          var leading = 0xD800 | (bits >> 10);
+          var trailing = 0xDC00 | (bits & 0x3ff);
+          sb.write(r'\u');
+          sb.write(leading.toRadixString(16));
+          sb.write(r'\u');
+          sb.write(trailing.toRadixString(16));
+        }
+      } else {
+        sb.writeCharCode(rune);
+      }
+    }
+
+    return finish(useSingleQuotes ? "'" : '"', sb.toString());
+  }
+
+  static bool _isUnpairedSurrogate(int code) => (code & 0xFFFFF800) == 0xD800;
+
+  static String _irregularEscape(int code, bool useSingleQuotes) {
+    switch (code) {
+      case charCodes.$SQ: return useSingleQuotes ? r"\'" : r"'";
+      case charCodes.$DQ: return useSingleQuotes ? r'"' : r'\"';
+      case charCodes.$BACKSLASH: return r'\\';
+      case charCodes.$BS: return r'\b';
+      case charCodes.$TAB: return r'\t';
+      case charCodes.$LF: return r'\n';
+      case charCodes.$VTAB: return r'\v';
+      case charCodes.$FF: return r'\f';
+      case charCodes.$CR: return r'\r';
+    }
+    return null;
+  }
+
+  /// Creates a literal js string from [value].
   ///
   /// Note that this function only puts quotes around [value]. It does not do
   /// any escaping, so use only when you can guarantee that [value] does not
@@ -1436,4 +1536,4 @@
   Iterator<Node> get iterator {
     return new _InterleaveIterator(source.iterator, separator);
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/js_ast/test/string_escape_test.dart b/pkg/js_ast/test/string_escape_test.dart
new file mode 100644
index 0000000..3811629
--- /dev/null
+++ b/pkg/js_ast/test/string_escape_test.dart
@@ -0,0 +1,149 @@
+// 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 js_ast.string_escape_test;
+
+import 'package:js_ast/js_ast.dart';
+import 'package:js_ast/src/characters.dart';
+import 'package:unittest/unittest.dart';
+
+const int $LCURLY = $OPEN_CURLY_BRACKET;
+const int $RCURLY = $CLOSE_CURLY_BRACKET;
+
+void main() {
+  check(input, expected, {ascii: false, utf8: false}) {
+    if (input is List) input = new String.fromCharCodes(input);
+    String actual = js.escapedString(input, ascii: ascii, utf8: utf8).value;
+    if (expected is List) {
+      expect(actual.codeUnits, expected);
+    } else {
+      expect(actual, expected);
+    }
+  }
+
+  test('simple', () {
+      check('', [$DQ, $DQ]);
+      check('a', [$DQ, $a, $DQ]);
+    });
+
+  test('simple-escapes', () {
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ]);
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ], ascii: true);
+      check([$BS], [$DQ, $BACKSLASH, $b, $DQ], utf8: true);
+
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ]);
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ], ascii: true);
+      check([$LF], [$DQ, $BACKSLASH, $n, $DQ], utf8: true);
+
+      check([$FF], [$DQ, $FF, $DQ]);
+      check([$FF], [$DQ, $BACKSLASH, $f, $DQ], ascii: true);
+      check([$FF], [$DQ, $BACKSLASH, $f, $DQ], utf8: true);
+
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ]);
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ], ascii: true);
+      check([$CR], [$DQ, $BACKSLASH, $r, $DQ], utf8: true);
+
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ]);
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], ascii: true);
+      check([$TAB], [$DQ, $BACKSLASH, $t, $DQ], utf8: true);
+
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ]);
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], ascii: true);
+      check([$VTAB], [$DQ, $BACKSLASH, $v, $DQ], utf8: true);
+    });
+
+  test('unnamed-control-codes-escapes', () {
+      check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ]);
+      check([0, 1, 2, 3], r'''"\x00\x01\x02\x03"''', ascii: true);
+      check([0, 1, 2, 3], [$DQ, 0, 1, 2, 3, $DQ], utf8: true);
+    });
+
+
+  test('line-separator', () {
+      // Legacy escaper is broken.
+      // check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ]);
+      check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], ascii: true);
+      check([$LS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $8, $DQ], utf8: true);
+    });
+
+  test('page-separator', () {
+      // Legacy escaper is broken.
+      // check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ]);
+      check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], ascii: true);
+      check([$PS], [$DQ, $BACKSLASH, $u, $2, $0, $2, $9, $DQ], utf8: true);
+    });
+
+  test('legacy-escaper-is-broken', () {
+      check([$LS], [$DQ, 0x2028, $DQ]);
+      check([$PS], [$DQ, 0x2029, $DQ]);
+    });
+
+  test('choose-quotes', () {
+      check('\'', [$DQ, $SQ, $DQ]);
+      check('"', [$SQ, $DQ, $SQ], ascii: true);
+      check("'", [$DQ, $SQ, $DQ], ascii: true);
+      // Legacy always double-quotes
+      check([$DQ, $DQ, $SQ],
+            [$DQ, $BACKSLASH, $DQ, $BACKSLASH, $DQ, $SQ, $DQ]);
+      // Using single quotes saves us one backslash:
+      check([$DQ, $DQ, $SQ],
+            [$SQ, $DQ, $DQ, $BACKSLASH, $SQ, $SQ],
+            ascii: true);
+      check([$DQ, $SQ, $SQ],
+            [$DQ, $BACKSLASH, $DQ, $SQ, $SQ, $DQ],
+            ascii: true);
+    });
+
+  test('u1234', () {
+      check('\u1234', [$DQ, 0x1234, $DQ]);
+      check('\u1234', [$DQ, $BACKSLASH, $u, $1, $2, $3, $4, $DQ], ascii: true);
+      check('\u1234', [$DQ, 0x1234, $DQ], utf8: true);
+    });
+
+  test('u12345', () {
+      check([0x12345], [$DQ, 55304, 57157, $DQ]);
+      // TODO: ES6 option:
+      //check([0x12345],
+      //      [$DQ, $BACKSLASH, $u, $LCURLY, $1, $2, $3, $4, $5, $RCURLY, $DQ],
+      //      ascii: true);
+      check([0x12345], r'''"\ud808\udf45"''', ascii: true);
+      check([0x12345],
+            [$DQ, $BACKSLASH, $u, $d, $8, $0, $8,
+                  $BACKSLASH, $u, $d, $f, $4, $5, $DQ],
+            ascii: true);
+      check([0x12345], [$DQ, 55304, 57157, $DQ], utf8: true);
+    });
+
+  test('unpaired-surrogate', () {
+      // (0xD834, 0xDD1E) = 0x1D11E
+      // Strings containing unpaired surrogates must be encoded to prevent
+      // problems with the utf8 file-level encoding.
+      check([0xD834], [$DQ, 0xD834, $DQ]);  // Legacy escapedString broken.
+      check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], ascii: true);
+      check([0xD834], [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $DQ], utf8: true);
+
+      check([0xDD1E], [$DQ, 0xDD1E, $DQ]);  // Legacy escapedString broken.
+      check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], ascii: true);
+      check([0xDD1E], [$DQ, $BACKSLASH, $u, $d, $d, $1, $e, $DQ], utf8: true);
+
+      check([0xD834, $A],
+            [$DQ, 0xD834, $A, $DQ]);  // Legacy escapedString broken.
+      check([0xD834, $A],
+            [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
+            ascii: true);
+      check([0xD834, $A],
+            [$DQ, $BACKSLASH, $u, $d, $8, $3, $4, $A, $DQ],
+            utf8: true);
+
+      check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ]);  // Legacy ok.
+      check([0xD834, 0xDD1E],
+            [$DQ,
+              $BACKSLASH, $u, $d, $8, $3, $4,
+              $BACKSLASH, $u, $d, $d, $1, $e,
+              $DQ],
+            ascii: true);
+      check([0xD834, 0xDD1E], r'''"\ud834\udd1e"''', ascii: true);
+      check([0xD834, 0xDD1E], [$DQ, 0xD834, 0xDD1E, $DQ], utf8: true);
+    });
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index ff080b5..0d48659 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -48,6 +48,7 @@
 analyzer/test/generated/ast_test: Pass, Slow # Issue 21628
 analyzer/test/generated/compile_time_error_code_test: Pass, Slow
 analyzer/test/generated/compile_time_error_code_test: Pass, Slow # Issue 21628
+analyzer/test/generated/declaration_resolver_test: Pass, Slow # Issue 21628
 analyzer/test/generated/element_test: Pass, Slow # Issue 21628
 analyzer/test/generated/engine_test: SkipSlow
 analyzer/test/generated/incremental_resolver_test: Pass, Slow # Issue 21628
@@ -63,6 +64,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/element/element_test: Pass, Slow # Issue 21628
 analyzer/test/src/summary/summary_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
@@ -76,6 +78,7 @@
 analyzer/test/src/task/model_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/options_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/options_work_manager_test: Pass, Slow # Issue 21628
+analyzer/test/src/task/strong/checker_test: Pass, Slow # Issue 21628
 collection/test/equality_test/01: Fail # Issue 1533
 collection/test/equality_test/02: Fail # Issue 1533
 collection/test/equality_test/03: Fail # Issue 1533
@@ -119,7 +122,7 @@
 # Unexplained errors only occuring on Safari 6.1 and earlier.
 typed_data/test/typed_buffers_test: RuntimeError
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
 lookup_map/test/version_check_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
 lookup_map/test/lookup_map_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
@@ -144,6 +147,7 @@
 http_server/test/*: Fail, OK # Uses dart:io.
 observe/test/transformer_test: Fail, OK # Uses dart:io.
 observe/test/unique_message_test: SkipByDesign  # Uses dart:io.
+dart_messages/test/dart_messages_test: Skip  # Uses dart:io.
 
 [ $runtime == vm && ($arch == simarm64 || $arch == simarm || $arch == simarmv5te || $arch == simmips || $arch == armv5te) ]
 # Timeout. These are not unit tests. They do not run efficiently on our
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 989b980..78c5a58 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -503,6 +503,7 @@
             '--outer_namespace', 'dart',
             '--inner_namespace', 'bin',
             '--name', 'observatory_assets_archive',
+            '--compress',
             '--client_root', '<(PRODUCT_DIR)/observatory/deployed/web/',
           ],
           'message': 'Generating ''<(observatory_assets_cc_file)'' file.'
@@ -587,6 +588,7 @@
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -639,6 +641,7 @@
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -682,6 +685,7 @@
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
@@ -737,6 +741,7 @@
       ],
       'include_dirs': [
         '..',
+        '../../third_party/', # Zlib
       ],
       'sources': [
         'main.cc',
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 7088bed..dc374f6 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -234,6 +234,9 @@
     packageRoot = _trimWindowsPath(packageRoot);
     _packageRoot = _workingDirectory.resolveUri(new Uri.file(packageRoot));
   }
+  // Now that we have determined the packageRoot value being used, set it
+  // up for use in Platform.packageRoot.
+  VMLibraryHooks.packageRoot = _packageRoot.toString();
   if (_traceLoading) {
     _log('Package root URI: $_packageRoot');
   }
@@ -482,6 +485,7 @@
     // resolve it against the working directory.
     packagesUri = _workingDirectory.resolveUri(packagesUri);
   }
+  VMLibraryHooks.packageConfig = packagesUri.toString();
   if (_traceLoading) {
     _log('Resolved packages map to: $packagesUri');
   }
diff --git a/runtime/bin/common_patch.dart b/runtime/bin/common_patch.dart
index d794cb6..feaf552 100644
--- a/runtime/bin/common_patch.dart
+++ b/runtime/bin/common_patch.dart
@@ -9,4 +9,5 @@
 
 _setupHooks() {
   VMLibraryHooks.eventHandlerSendData = _EventHandler._sendData;
+  VMLibraryHooks.timerMillisecondClock = _EventHandler._timerMillisecondClock;
 }
\ No newline at end of file
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 9e2fcf7..e86fad9 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -608,7 +608,7 @@
   }
 
   if (buffer_copy != NULL) {
-    free(const_cast<uint8_t *>(buffer_copy));
+    free(buffer_copy);
   }
 
   if (Dart_IsError(result)) {
diff --git a/runtime/bin/eventhandler.cc b/runtime/bin/eventhandler.cc
index 9e53d5f..bb9a7fe 100644
--- a/runtime/bin/eventhandler.cc
+++ b/runtime/bin/eventhandler.cc
@@ -131,5 +131,12 @@
   event_handler->SendData(id, dart_port, data);
 }
 
+
+void FUNCTION_NAME(EventHandler_TimerMillisecondClock)(
+    Dart_NativeArguments args) {
+  int64_t now = TimerUtils::GetCurrentMonotonicMillis();
+  Dart_SetReturnValue(args, Dart_NewInteger(now));
+}
+
 }  // namespace bin
 }  // namespace dart
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index 14cddc1..6fdabfb 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -333,7 +333,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
@@ -341,7 +341,7 @@
 void EventHandlerImplementation::HandleTimeout() {
   if (timeout_queue_.HasTimeout()) {
     int64_t millis = timeout_queue_.CurrentTimeout() -
-        TimerUtils::GetCurrentTimeMilliseconds();
+        TimerUtils::GetCurrentMonotonicMillis();
     if (millis <= 0) {
       DartUtils::PostNull(timeout_queue_.CurrentPort());
       timeout_queue_.RemoveCurrent();
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index f28481f..4c605ce 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -109,7 +109,7 @@
   if (status == -1) {
     FATAL("Failed adding interrupt fd to epoll instance");
   }
-  timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC));
+  timer_fd_ = NO_RETRY_EXPECTED(timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC));
   if (timer_fd_ == -1) {
     FATAL1("Failed creating timerfd file descriptor: %i", errno);
   }
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index edd0485..faf471b 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -394,7 +394,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
@@ -402,7 +402,7 @@
 void EventHandlerImplementation::HandleTimeout() {
   if (timeout_queue_.HasTimeout()) {
     int64_t millis = timeout_queue_.CurrentTimeout() -
-        TimerUtils::GetCurrentTimeMilliseconds();
+        TimerUtils::GetCurrentMonotonicMillis();
     if (millis <= 0) {
       DartUtils::PostNull(timeout_queue_.CurrentPort());
       timeout_queue_.RemoveCurrent();
diff --git a/runtime/bin/eventhandler_patch.dart b/runtime/bin/eventhandler_patch.dart
index 3dcce2d..d92271b 100644
--- a/runtime/bin/eventhandler_patch.dart
+++ b/runtime/bin/eventhandler_patch.dart
@@ -9,5 +9,8 @@
                                     SendPort sendPort,
                                     int data)
       native "EventHandler_SendData";
+
+  static int _timerMillisecondClock()
+      native "EventHandler_TimerMillisecondClock";
 }
 
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 33f59d6..8e0adc5 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -1352,7 +1352,7 @@
     return kInfinityTimeout;
   }
   int64_t millis = timeout_queue_.CurrentTimeout() -
-      TimerUtils::GetCurrentTimeMilliseconds();
+      TimerUtils::GetCurrentMonotonicMillis();
   return (millis < 0) ? 0 : millis;
 }
 
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 011e792..ec70232 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -31,6 +31,7 @@
   V(Directory_Rename, 2)                                                       \
   V(Directory_List, 3)                                                         \
   V(EventHandler_SendData, 3)                                                  \
+  V(EventHandler_TimerMillisecondClock, 0)                                     \
   V(File_Open, 2)                                                              \
   V(File_Exists, 1)                                                            \
   V(File_GetFD, 1)                                                             \
@@ -84,7 +85,6 @@
   V(Platform_ResolvedExecutableName, 0)                                        \
   V(Platform_Environment, 0)                                                   \
   V(Platform_ExecutableArguments, 0)                                           \
-  V(Platform_PackageRoot, 0)                                                   \
   V(Platform_GetVersion, 0)                                                    \
   V(Process_Start, 11)                                                         \
   V(Process_Wait, 5)                                                           \
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 49a993f..29d2884 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -36,12 +36,14 @@
       this->packages_file = strdup(packages_file);
     }
   }
+#if 0
   ~IsolateData() {
     free(script_url);
     free(package_root);
     free(packages_file);
     free(udp_receive_buffer);
   }
+#endif
 
   char* script_url;
   char* package_root;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index f8ef12f..7fc19c4 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -26,6 +26,7 @@
 #include "platform/globals.h"
 #include "platform/hashmap.h"
 #include "platform/text_buffer.h"
+#include "zlib/zlib.h"
 
 namespace dart {
 namespace bin {
@@ -763,8 +764,6 @@
       Dart_TimelineAsyncEnd("LoadScript", isolate_data->load_async_id);
     }
 
-    Platform::SetPackageRoot(package_root);
-
     result = DartUtils::SetupIOLibrary(script_uri);
     CHECK_RESULT(result);
   }
@@ -1282,10 +1281,83 @@
 extern unsigned int observatory_assets_archive_len;
 extern const uint8_t* observatory_assets_archive;
 
+
+// |input| is assumed to be a gzipped stream.
+// This function allocates the output buffer in the C heap and the caller
+// is responsible for freeing it.
+void Decompress(const uint8_t* input, unsigned int input_len,
+                uint8_t** output, unsigned int* output_length) {
+  ASSERT(input != NULL);
+  ASSERT(input_len > 0);
+  ASSERT(output != NULL);
+  ASSERT(output_length != NULL);
+
+  // Initialize output.
+  *output = NULL;
+  *output_length = 0;
+
+  const unsigned int kChunkSize = 256 * 1024;
+  uint8_t chunk_out[kChunkSize];
+  z_stream strm;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+  strm.avail_in = 0;
+  strm.next_in = 0;
+  int ret = inflateInit2(&strm, 32 + MAX_WBITS);
+  ASSERT(ret == Z_OK);
+
+  unsigned int input_cursor = 0;
+  unsigned int output_cursor = 0;
+  do {
+    // Setup input.
+    unsigned int size_in = input_len - input_cursor;
+    if (size_in > kChunkSize) {
+      size_in = kChunkSize;
+    }
+    strm.avail_in = size_in;
+    strm.next_in = const_cast<uint8_t*>(&input[input_cursor]);
+
+    // Inflate until we've exhausted the current input chunk.
+    do {
+      // Setup output.
+      strm.avail_out = kChunkSize;
+      strm.next_out = &chunk_out[0];
+      // Inflate.
+      ret = inflate(&strm, Z_SYNC_FLUSH);
+      // We either hit the end of the stream or made forward progress.
+      ASSERT((ret == Z_STREAM_END) || (ret == Z_OK));
+      // Grow output buffer size.
+      unsigned int size_out = kChunkSize - strm.avail_out;
+      *output_length += size_out;
+      *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length));
+      // Copy output.
+      memmove(&((*output)[output_cursor]), &chunk_out[0], size_out);
+      output_cursor += size_out;
+    } while (strm.avail_out == 0);
+
+    // We've processed size_in bytes.
+    input_cursor += size_in;
+
+    // We're finished decompressing when zlib tells us.
+  } while (ret != Z_STREAM_END);
+
+  inflateEnd(&strm);
+}
+
+
 Dart_Handle GetVMServiceAssetsArchiveCallback() {
-  return DartUtils::MakeUint8Array(
-      observatory_assets_archive,
-      observatory_assets_archive_len);
+  uint8_t* decompressed = NULL;
+  unsigned int decompressed_len = 0;
+  Decompress(observatory_assets_archive,
+             observatory_assets_archive_len,
+             &decompressed,
+             &decompressed_len);
+  Dart_Handle tar_file = DartUtils::MakeUint8Array(decompressed,
+                                                   decompressed_len);
+  // Free decompressed memory as it has been copied into a Dart array.
+  free(decompressed);
+  return tar_file;
 }
 
 
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 0ed2bd3..ec75ee9 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -14,7 +14,6 @@
 
 const char* Platform::executable_name_ = NULL;
 const char* Platform::resolved_executable_name_ = NULL;
-const char* Platform::package_root_ = NULL;
 int Platform::script_index_ = 1;
 char** Platform::argv_ = NULL;
 
@@ -76,15 +75,6 @@
 }
 
 
-void FUNCTION_NAME(Platform_PackageRoot)(Dart_NativeArguments args) {
-  const char* package_root = Platform::GetPackageRoot();
-  if (package_root == NULL) {
-    package_root = "";
-  }
-  Dart_SetReturnValue(args, Dart_NewStringFromCString(package_root));
-}
-
-
 void FUNCTION_NAME(Platform_Environment)(Dart_NativeArguments args) {
   intptr_t count = 0;
   char** env = Platform::Environment(&count);
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index 4d847e7..4dec601 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -56,14 +56,6 @@
     return resolved_executable_name_;
   }
 
-  // Stores and gets the package root.
-  static void SetPackageRoot(const char* package_root) {
-    package_root_ = package_root;
-  }
-  static const char* GetPackageRoot() {
-    return package_root_;
-  }
-
   // Stores and gets the flags passed to the executable.
   static void SetExecutableArguments(int script_index, char** argv) {
     script_index_ = script_index;
@@ -84,7 +76,6 @@
   // The path to the resolved executable.
   static const char* resolved_executable_name_;
 
-  static const char* package_root_;
   static int script_index_;
   static char** argv_;  // VM flags are argv_[1 ... script_index_ - 1]
 
diff --git a/runtime/bin/platform_patch.dart b/runtime/bin/platform_patch.dart
index c917b54..dec7493 100644
--- a/runtime/bin/platform_patch.dart
+++ b/runtime/bin/platform_patch.dart
@@ -15,6 +15,7 @@
   /* patch */ static _environment() native "Platform_Environment";
   /* patch */ static List<String> _executableArguments()
        native "Platform_ExecutableArguments";
-  /* patch */ static String _packageRoot() native "Platform_PackageRoot";
+  /* patch */ static String _packageRoot() => VMLibraryHooks.packageRoot;
+  /* patch */ static String _packageConfig() => VMLibraryHooks.packageConfig;
   /* patch */ static String _version() native "Platform_GetVersion";
 }
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 1910f86..e7646da 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -145,13 +145,13 @@
     Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
     if (Dart_IsError(result)) Dart_PropagateError(result);
     Dart_Handle err;
-    RawAddr& raw = const_cast<RawAddr&>(addr);
     if (addr.addr.sa_family == AF_INET6) {
       err = Dart_ListSetAsBytes(
-          result, 0, reinterpret_cast<uint8_t*>(&raw.in6.sin6_addr), len);
+          result, 0,
+          reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len);
     } else {
       err = Dart_ListSetAsBytes(
-          result, 0, reinterpret_cast<uint8_t*>(&raw.in.sin_addr), len);
+          result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
     }
     if (Dart_IsError(err)) Dart_PropagateError(err);
     return result;
@@ -159,14 +159,13 @@
 
   static CObjectUint8Array* ToCObject(const RawAddr& addr) {
     int in_addr_len = SocketAddress::GetInAddrLength(addr);
-    void* in_addr;
-    RawAddr& raw = const_cast<RawAddr&>(addr);
+    const void* in_addr;
     CObjectUint8Array* data =
         new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
     if (addr.addr.sa_family == AF_INET6) {
-      in_addr = reinterpret_cast<void*>(&raw.in6.sin6_addr);
+      in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
     } else {
-      in_addr = reinterpret_cast<void*>(&raw.in.sin_addr);
+      in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
     }
     memmove(data->Buffer(), in_addr, in_addr_len);
     return data;
diff --git a/runtime/bin/utils.h b/runtime/bin/utils.h
index 2c3f1fc..a1714c2 100644
--- a/runtime/bin/utils.h
+++ b/runtime/bin/utils.h
@@ -98,8 +98,8 @@
 
 class TimerUtils {
  public:
-  static int64_t GetCurrentTimeMicros();
-  static int64_t GetCurrentTimeMilliseconds();
+  static int64_t GetCurrentMonotonicMicros();
+  static int64_t GetCurrentMonotonicMillis();
   static void Sleep(int64_t millis);
 };
 
diff --git a/runtime/bin/utils_android.cc b/runtime/bin/utils_android.cc
index d96eb5d..db9eb75 100644
--- a/runtime/bin/utils_android.cc
+++ b/runtime/bin/utils_android.cc
@@ -71,17 +71,21 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
-  struct timeval tv;
-  if (gettimeofday(&tv, NULL) < 0) {
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+  // Convert to microseconds.
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
 }
 
 void TimerUtils::Sleep(int64_t millis) {
diff --git a/runtime/bin/utils_linux.cc b/runtime/bin/utils_linux.cc
index f84ba33..419df95 100644
--- a/runtime/bin/utils_linux.cc
+++ b/runtime/bin/utils_linux.cc
@@ -69,17 +69,21 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
-  struct timeval tv;
-  if (gettimeofday(&tv, NULL) < 0) {
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
     return 0;
   }
-  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+  // Convert to microseconds.
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
 }
 
 void TimerUtils::Sleep(int64_t millis) {
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index 1d792c9..80cd038 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -7,6 +7,9 @@
 
 #include <errno.h>  // NOLINT
 #include <netdb.h>  // NOLINT
+#include <mach/mach.h>  // NOLINT
+#include <mach/clock.h>  // NOLINT
+#include <mach/mach_time.h>  // NOLINT
 #include <sys/time.h>  // NOLINT
 #include <time.h>  // NOLINT
 
@@ -71,17 +74,44 @@
   return false;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
 }
 
-int64_t TimerUtils::GetCurrentTimeMicros() {
-  struct timeval tv;
-  if (gettimeofday(&tv, NULL) < 0) {
-    UNREACHABLE();
-    return 0;
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+#if TARGET_OS_IOS
+  // On iOS mach_absolute_time stops while the device is sleeping. Instead use
+  // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
+  // changes. KERN_BOOTTIME will be updated by the system whenever the system
+  // clock change.
+  struct timeval boottime;
+  int mib[2] = {CTL_KERN, KERN_BOOTTIME};
+  size_t size = sizeof(boottime);
+  int kr = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &boottime, &size, NULL, 0);
+  ASSERT(KERN_SUCCESS == kr);
+  int64_t now = GetCurrentTimeMicros();
+  int64_t origin = boottime.tv_sec * kMicrosecondsPerSecond;
+  origin += boottime.tv_usec;
+  return now - origin;
+#else
+  static mach_timebase_info_data_t timebase_info;
+  if (timebase_info.denom == 0) {
+    // Zero-initialization of statics guarantees that denom will be 0 before
+    // calling mach_timebase_info.  mach_timebase_info will never set denom to
+    // 0 as that would be invalid, so the zero-check can be used to determine
+    // whether mach_timebase_info has already been called.  This is
+    // recommended by Apple's QA1398.
+    kern_return_t kr = mach_timebase_info(&timebase_info);
+    ASSERT(KERN_SUCCESS == kr);
   }
-  return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec;
+
+  // timebase_info converts absolute time tick units into nanoseconds.  Convert
+  // to microseconds.
+  int64_t result = mach_absolute_time() / kNanosecondsPerMicrosecond;
+  result *= timebase_info.numer;
+  result /= timebase_info.denom;
+  return result;
+#endif  // TARGET_OS_IOS
 }
 
 void TimerUtils::Sleep(int64_t millis) {
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 65d4c65..ae12f4b 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -168,11 +168,7 @@
   return true;
 }
 
-int64_t TimerUtils::GetCurrentTimeMilliseconds() {
-  return GetCurrentTimeMicros() / 1000;
-}
-
-int64_t TimerUtils::GetCurrentTimeMicros() {
+static int64_t GetCurrentTimeMicros() {
   static const int64_t kTimeEpoc = 116444736000000000LL;
   static const int64_t kTimeScaler = 10;  // 100 ns to us.
 
@@ -191,6 +187,29 @@
   return (time.t_ - kTimeEpoc) / kTimeScaler;
 }
 
+int64_t TimerUtils::GetCurrentMonotonicMillis() {
+  return GetCurrentMonotonicMicros() / 1000;
+}
+
+static int64_t qpc_ticks_per_second = 0;
+
+int64_t TimerUtils::GetCurrentMonotonicMicros() {
+  if (qpc_ticks_per_second == 0) {
+    // QueryPerformanceCounter not supported, fallback.
+    return GetCurrentTimeMicros();
+  }
+  // Grab performance counter value.
+  LARGE_INTEGER now;
+  QueryPerformanceCounter(&now);
+  int64_t qpc_value = static_cast<int64_t>(now.QuadPart);
+  // Convert to microseconds.
+  int64_t seconds = qpc_value / qpc_ticks_per_second;
+  int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second);
+  int64_t result = seconds * kMicrosecondsPerSecond;
+  result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second);
+  return result;
+}
+
 void TimerUtils::Sleep(int64_t millis) {
   ::Sleep(millis);
 }
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 6215fe71..aa5a62a 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -10,6 +10,7 @@
 #include "bin/platform.h"
 #include "bin/thread.h"
 #include "bin/vmservice_impl.h"
+#include "zlib/zlib.h"
 
 namespace dart {
 namespace bin {
@@ -92,6 +93,68 @@
 }
 
 
+void VmServiceServer::DecompressAssets(const uint8_t* input,
+                                       unsigned int input_len,
+                                       uint8_t** output,
+                                       unsigned int* output_length) {
+  ASSERT(input != NULL);
+  ASSERT(input_len > 0);
+  ASSERT(output != NULL);
+  ASSERT(output_length != NULL);
+
+  // Initialize output.
+  *output = NULL;
+  *output_length = 0;
+
+  const unsigned int kChunkSize = 256 * 1024;
+  uint8_t chunk_out[kChunkSize];
+  z_stream strm;
+  strm.zalloc = Z_NULL;
+  strm.zfree = Z_NULL;
+  strm.opaque = Z_NULL;
+  strm.avail_in = 0;
+  strm.next_in = 0;
+  int ret = inflateInit2(&strm, 32 + MAX_WBITS);
+  ASSERT(ret == Z_OK);
+
+  unsigned int input_cursor = 0;
+  unsigned int output_cursor = 0;
+  do {
+    // Setup input.
+    unsigned int size_in = input_len - input_cursor;
+    if (size_in > kChunkSize) {
+      size_in = kChunkSize;
+    }
+    strm.avail_in = size_in;
+    strm.next_in = const_cast<uint8_t*>(&input[input_cursor]);
+
+    // Inflate until we've exhausted the current input chunk.
+    do {
+      // Setup output.
+      strm.avail_out = kChunkSize;
+      strm.next_out = &chunk_out[0];
+      // Inflate.
+      ret = inflate(&strm, Z_SYNC_FLUSH);
+      // We either hit the end of the stream or made forward progress.
+      ASSERT((ret == Z_STREAM_END) || (ret == Z_OK));
+      // Grow output buffer size.
+      unsigned int size_out = kChunkSize - strm.avail_out;
+      *output_length += size_out;
+      *output = reinterpret_cast<uint8_t*>(realloc(*output, *output_length));
+      // Copy output.
+      memmove(&((*output)[output_cursor]), &chunk_out[0], size_out);
+      output_cursor += size_out;
+    } while (strm.avail_out == 0);
+
+    // We've processed size_in bytes.
+    input_cursor += size_in;
+
+    // We're finished decompressing when zlib tells us.
+  } while (ret != Z_STREAM_END);
+
+  inflateEnd(&strm);
+}
+
 /* DISALLOW_ALLOCATION */
 void VmServiceServer::operator delete(void* pointer)  {
   fprintf(stderr, "unreachable code\n");
diff --git a/runtime/bin/vmservice_dartium.h b/runtime/bin/vmservice_dartium.h
index 9064f73..11067ee 100644
--- a/runtime/bin/vmservice_dartium.h
+++ b/runtime/bin/vmservice_dartium.h
@@ -21,6 +21,9 @@
   static const char* GetServerIP();
   static intptr_t GetServerPort();
 
+  static void DecompressAssets(const uint8_t* input, unsigned int input_len,
+                               uint8_t** output, unsigned int* output_length);
+
 /* DISALLOW_ALLOCATION */
   void operator delete(void* pointer);
  private:
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 9666364..227c84f 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1792,7 +1792,7 @@
  */
 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
                                             intptr_t offset,
-                                            uint8_t* native_array,
+                                            const uint8_t* native_array,
                                             intptr_t length);
 
 
diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h
index ea7900d..7dce495 100644
--- a/runtime/include/dart_native_api.h
+++ b/runtime/include/dart_native_api.h
@@ -102,6 +102,16 @@
 DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message);
 
 /**
+ * Posts a message on some port. The message will contain the integer 'message'.
+ *
+ * \param port_id The destination port.
+ * \param message The message to send.
+ *
+ * \return True if the message was posted.
+ */
+DART_EXPORT bool Dart_PostInteger(Dart_Port port_id, int64_t message);
+
+/**
  * A native message handler.
  *
  * This handler is associated with a native port by calling
diff --git a/runtime/lib/developer.cc b/runtime/lib/developer.cc
index d2466af..ead1de1 100644
--- a/runtime/lib/developer.cc
+++ b/runtime/lib/developer.cc
@@ -60,6 +60,14 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Developer_postEvent, 2) {
+  GET_NON_NULL_NATIVE_ARGUMENT(String, event_kind, arguments->NativeArgAt(0));
+  GET_NON_NULL_NATIVE_ARGUMENT(String, event_data, arguments->NativeArgAt(1));
+  Service::SendExtensionEvent(isolate, event_kind, event_data);
+  return Object::null();
+}
+
+
 DEFINE_NATIVE_ENTRY(Developer_lookupExtension, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(0));
   return isolate->LookupServiceExtensionHandler(name);
diff --git a/runtime/lib/developer.dart b/runtime/lib/developer.dart
index 71b1f5c..af505ff 100644
--- a/runtime/lib/developer.dart
+++ b/runtime/lib/developer.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:isolate';
+
 patch bool debugger({bool when: true,
                      String message}) native "Developer_debugger";
 
@@ -50,8 +52,88 @@
      Object error,
      StackTrace stackTrace) native "Developer_log";
 
+patch void _postEvent(String eventKind, String eventData)
+    native "Developer_postEvent";
+
 patch ServiceExtensionHandler _lookupExtension(String method)
     native "Developer_lookupExtension";
 
 patch _registerExtension(String method, ServiceExtensionHandler handler)
     native "Developer_registerExtension";
+
+// This code is only invoked when there is no other Dart code on the stack.
+_runExtension(ServiceExtensionHandler handler,
+              String method,
+              List<String> parameterKeys,
+              List<String> parameterValues,
+              SendPort replyPort,
+              Object id) {
+  var parameters = {};
+  for (var i = 0; i < parameterKeys.length; i++) {
+    parameters[parameterKeys[i]] = parameterValues[i];
+  }
+  var response;
+  try {
+    response = handler(method, parameters);
+  } catch (e, st) {
+    var errorDetails = (st == null) ? '$e' : '$e\n$st';
+    response = new ServiceExtensionResponse.error(
+        ServiceExtensionResponse.kExtensionError,
+        errorDetails);
+    _postResponse(replyPort, id, response);
+    return;
+  }
+  if (response is! Future) {
+    response = new ServiceExtensionResponse.error(
+          ServiceExtensionResponse.kExtensionError,
+          "Extension handler must return a Future");
+    _postResponse(replyPort, id, response);
+    return;
+  }
+  response.catchError((e, st) {
+    // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
+    var errorDetails = (st == null) ? '$e' : '$e\n$st';
+    return new ServiceExtensionResponse.error(
+        ServiceExtensionResponse.kExtensionError,
+        errorDetails);
+  }).then((response) {
+    // Post the valid response or the wrapped error after verifying that
+    // the response is a ServiceExtensionResponse.
+    if (response is! ServiceExtensionResponse) {
+      response = new ServiceExtensionResponse.error(
+          ServiceExtensionResponse.kExtensionError,
+          "Extension handler must complete to a ServiceExtensionResponse");
+    }
+    _postResponse(replyPort, id, response);
+  }).catchError((e, st) {
+    // We do not expect any errors to occur in the .then or .catchError blocks
+    // but, suppress them just in case.
+  });
+}
+
+// This code is only invoked by _runExtension.
+_postResponse(SendPort replyPort,
+              Object id,
+              ServiceExtensionResponse response) {
+  assert(replyPort != null);
+  if (id == null) {
+    // No id -> no response.
+    replyPort.send(null);
+    return;
+  }
+  assert(id != null);
+  StringBuffer sb = new StringBuffer();
+  sb.write('{"jsonrpc":"2.0",');
+  if (response._isError()) {
+    sb.write('"error":');
+  } else {
+    sb.write('"result":');
+  }
+  sb.write('${response._toString()},');
+  if (id is String) {
+    sb.write('"id":"$id"}');
+  } else {
+    sb.write('"id":$id}');
+  }
+  replyPort.send(sb.toString());
+}
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 8e95506..2227603 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -11,11 +11,20 @@
 class VMLibraryHooks {
   // Example: "dart:isolate _Timer._factory"
   static var timerFactory;
+
   // Example: "dart:io _EventHandler._sendData"
   static var eventHandlerSendData;
+
+  // A nullary closure that answers the current clock value in milliseconds.
+  // Example: "dart:io _EventHandler._timerMillisecondClock"
+  static var timerMillisecondClock;
+
   // Implementation of Resource.readAsBytes.
   static var resourceReadAsBytes;
+
   // Implementation of package root/map provision.
+  static var packageRoot;
+  static var packageConfig;
   static var getPackageRoot;
   static var getPackageMap;
 }
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index dc52798..21f1274 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -8,6 +8,7 @@
 #include "vm/class_finalizer.h"
 #include "vm/dart.h"
 #include "vm/dart_api_impl.h"
+#include "vm/dart_api_message.h"
 #include "vm/dart_entry.h"
 #include "vm/exceptions.h"
 #include "vm/lockers.h"
@@ -106,18 +107,22 @@
   // TODO(iposva): Allow for arbitrary messages to be sent.
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, obj, arguments->NativeArgAt(1));
 
-  uint8_t* data = NULL;
-
   const Dart_Port destination_port_id = port.Id();
   const bool can_send_any_object = isolate->origin_id() == port.origin_id();
 
-  MessageWriter writer(&data, &allocator, can_send_any_object);
-  writer.WriteMessage(obj);
+  if (ApiObjectConverter::CanConvert(obj.raw())) {
+    PortMap::PostMessage(new Message(
+        destination_port_id, obj.raw(), Message::kNormalPriority));
+  } else {
+    uint8_t* data = NULL;
+    MessageWriter writer(&data, &allocator, can_send_any_object);
+    writer.WriteMessage(obj);
 
-  // TODO(turnidge): Throw an exception when the return value is false?
-  PortMap::PostMessage(new Message(destination_port_id,
-                                   data, writer.BytesWritten(),
-                                   Message::kNormalPriority));
+    // TODO(turnidge): Throw an exception when the return value is false?
+    PortMap::PostMessage(new Message(destination_port_id,
+                                     data, writer.BytesWritten(),
+                                     Message::kNormalPriority));
+  }
   return Object::null();
 }
 
@@ -252,7 +257,7 @@
 }
 
 
-static char* String2UTF8(const String& str) {
+static const char* String2UTF8(const String& str) {
   intptr_t len = Utf8::Length(str);
   char* result = new char[len + 1];
   str.ToUTF8(reinterpret_cast<uint8_t*>(result), len);
@@ -262,11 +267,11 @@
 }
 
 
-static char* CanonicalizeUri(Thread* thread,
-                             const Library& library,
-                             const String& uri,
-                             char** error) {
-  char* result = NULL;
+static const char* CanonicalizeUri(Thread* thread,
+                                   const Library& library,
+                                   const String& uri,
+                                   char** error) {
+  const char* result = NULL;
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   Dart_LibraryTagHandler handler = isolate->library_tag_handler();
@@ -329,19 +334,19 @@
   const Library& root_lib =
       Library::Handle(isolate->object_store()->root_library());
   char* error = NULL;
-  char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
+  const char* canonical_uri = CanonicalizeUri(thread, root_lib, uri, &error);
   if (canonical_uri == NULL) {
     const String& msg = String::Handle(String::New(error));
     ThrowIsolateSpawnException(msg);
   }
 
-  char* utf8_package_root =
+  const char* utf8_package_root =
       package_root.IsNull() ? NULL : String2UTF8(package_root);
 
-  char** utf8_package_map = NULL;
+  const char** utf8_package_map = NULL;
   if (!packages.IsNull()) {
     intptr_t len = packages.Length();
-    utf8_package_map = new char*[len + 1];
+    utf8_package_map = new const char*[len + 1];
 
     Object& entry = Object::Handle();
     for (intptr_t i = 0; i < len; i++) {
@@ -367,7 +372,7 @@
           isolate->init_callback_data(),
           canonical_uri,
           utf8_package_root,
-          const_cast<const char**>(utf8_package_map),
+          utf8_package_map,
           args,
           message,
           paused.value(),
diff --git a/runtime/lib/timer_impl.dart b/runtime/lib/timer_impl.dart
index d4a8160..a0660e1 100644
--- a/runtime/lib/timer_impl.dart
+++ b/runtime/lib/timer_impl.dart
@@ -172,7 +172,7 @@
     // to nearest millisecond, not up, so that time + duration is before
     // duration milliseconds from now. Using microsecond timers like
     // Stopwatch allows detecting that the timer fires early.
-    int now = new DateTime.now().millisecondsSinceEpoch;
+    int now = VMLibraryHooks.timerMillisecondClock();
     int wakeupTime = (milliSeconds == 0) ? now : (now + 1 + milliSeconds);
 
     _Timer timer = new _Timer._internal(callback,
@@ -232,7 +232,7 @@
     if (_milliSeconds > 0) {
       _wakeupTime += _milliSeconds;
     } else {
-      _wakeupTime = new DateTime.now().millisecondsSinceEpoch;
+      _wakeupTime = VMLibraryHooks.timerMillisecondClock();
     }
   }
 
@@ -340,7 +340,7 @@
     } else {
       // Collect pending timers from the timer heap which have expired at this
       // time.
-      var currentTime = new DateTime.now().millisecondsSinceEpoch;
+      var currentTime = VMLibraryHooks.timerMillisecondClock();
       var timer;
       while (!_heap.isEmpty && (_heap.first._wakeupTime <= currentTime)) {
         timer = _heap.removeFirst();
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 9988ec9..47bbff7 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -429,7 +429,7 @@
           if (loc.tokenPos != null) {
             line = script.tokenToLine(loc.tokenPos);
           } else {
-            line = script.tokenToLine(loc.line);
+            line = loc.line;
           }
           if ((line >= _startLine) && (line <= _endLine)) {
             _updateTask.queue();
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index 2d7049f..04a7376 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -32,10 +32,15 @@
 
   Future postMessage(String method) {
     IFrameElement e = $['root'];
+    var isolateIds = new List();
+    for (var isolate in app.vm.isolates) {
+      isolateIds.add(isolate.id);
+    }
     var message = {
       'method': method,
       'params': {
-        'vmAddress': (app.vm as WebSocketVM).target.networkAddress
+        'vmAddress': (app.vm as WebSocketVM).target.networkAddress,
+        'isolateIds': isolateIds
       }
     };
     e.contentWindow.postMessage(JSON.encode(message), window.location.href);
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 8c9717f..e45cb8d 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1137,6 +1137,8 @@
 /// State for a running isolate.
 class Isolate extends ServiceObjectOwner with Coverage {
   static const kLoggingStream = '_Logging';
+  static const kExtensionStream = 'Extension';
+
   @reflectable VM get vm => owner;
   @reflectable Isolate get isolate => this;
   @observable int number;
@@ -1171,6 +1173,8 @@
 
   @observable bool ioEnabled = false;
 
+  final List<String> extensionRPCs = new List<String>();
+
   Map<String,ServiceObject> _cache = new Map<String,ServiceObject>();
   final TagProfile tagProfile = new TagProfile(20);
 
@@ -1436,6 +1440,11 @@
     if (savedStartTime == null) {
       vm._buildIsolateList();
     }
+
+    extensionRPCs.clear();
+    if (map['extensionRPCs'] != null) {
+      extensionRPCs.addAll(map['extensionRPCs']);
+    }
   }
 
   Future<TagProfile> updateTagProfile() {
@@ -1884,6 +1893,7 @@
   static const kIsolateRunnable        = 'IsolateRunnable';
   static const kIsolateExit            = 'IsolateExit';
   static const kIsolateUpdate          = 'IsolateUpdate';
+  static const kServiceExtensionAdded  = 'ServiceExtensionAdded';
   static const kPauseStart             = 'PauseStart';
   static const kPauseExit              = 'PauseExit';
   static const kPauseBreakpoint        = 'PauseBreakpoint';
@@ -1899,6 +1909,7 @@
   static const kDebuggerSettingsUpdate = '_DebuggerSettingsUpdate';
   static const kConnectionClosed       = 'ConnectionClosed';
   static const kLogging                = '_Logging';
+  static const kExtension              = 'Extension';
 
   ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -1910,6 +1921,7 @@
   @observable DateTime timestamp;
   @observable Breakpoint breakpoint;
   @observable Frame topFrame;
+  @observable String extensionRPC;
   @observable Instance exception;
   @observable Instance asyncContinuation;
   @observable bool atAsyncJump;
@@ -1920,6 +1932,8 @@
   @observable String exceptions;
   @observable String bytesAsString;
   @observable Map logRecord;
+  @observable String extensionKind;
+  @observable Map extensionData;
 
   int chunkIndex, chunkCount, nodeCount;
 
@@ -1952,6 +1966,9 @@
         breakpoint = pauseBpts[0];
       }
     }
+    if (map['extensionRPC'] != null) {
+      extensionRPC = map['extensionRPC'];
+    }
     topFrame = map['topFrame'];
     if (map['exception'] != null) {
       exception = map['exception'];
@@ -1994,6 +2011,10 @@
           new DateTime.fromMillisecondsSinceEpoch(logRecord['time']);
       logRecord['level'] = _findLogLevel(logRecord['level']);
     }
+    if (map['extensionKind'] != null) {
+      extensionKind = map['extensionKind'];
+      extensionData = map['extensionData'];
+    }
   }
 
   String toString() {
diff --git a/runtime/observatory/observatory.gypi b/runtime/observatory/observatory.gypi
index 4971524..5d282ac 100644
--- a/runtime/observatory/observatory.gypi
+++ b/runtime/observatory/observatory.gypi
@@ -44,6 +44,7 @@
       'target_name': 'build_observatory',
       'type': 'none',
       'dependencies': [
+        'dart_bootstrap#host',
         'fetch_observatory_deps#host',
       ],
       'toolsets': ['host'],
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index 59ec18c..b00ab07 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -15,7 +15,7 @@
     commandLineOptions: [--show-package-warnings]
 dependencies:
   args: any
-  charted: ^0.2.9
+  charted: ^0.3.0
   polymer: ^0.16.3
   unittest: < 0.12.0
   usage: any
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index f134606..e29686b 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -55,6 +55,11 @@
 
 void test() {
   registerExtension('__delay', Handler);
+  debugger();
+  postEvent('ALPHA', {
+    'cat': 'dog'
+  });
+  debugger();
   registerExtension('__error', Handler);
   registerExtension('__exception', Handler);
   registerExtension('__null', Handler);
@@ -71,6 +76,24 @@
 }
 
 var tests = [
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    await isolate.load();
+    expect(isolate.extensionRPCs.length, 1);
+    expect(isolate.extensionRPCs[0], equals('__delay'));
+  },
+  resumeIsolateAndAwaitEvent(Isolate.kExtensionStream, (ServiceEvent event) {
+    expect(event.kind, equals(ServiceEvent.kExtension));
+    expect(event.extensionKind, equals('ALPHA'));
+    expect(event.extensionData, new isInstanceOf<Map>());
+    expect(event.extensionData['cat'], equals('dog'));
+  }),
+  hasStoppedAtBreakpoint,
+  resumeIsolateAndAwaitEvent(VM.kIsolateStream, (ServiceEvent event) {
+    // Check that we received an event when '__error' was registered.
+    expect(event.kind, equals(ServiceEvent.kServiceExtensionAdded));
+    expect(event.extensionRPC, equals('__error'));
+  }),
   // Initial.
   (Isolate isolate) async {
     var result;
@@ -130,4 +153,4 @@
   },
 ];
 
-main(args) async => runIsolateTests(args, tests, testeeBefore:test);
+main(args) async => runIsolateTests(args, tests, testeeConcurrent:test);
diff --git a/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart
new file mode 100644
index 0000000..4a6a88d
--- /dev/null
+++ b/runtime/observatory/tests/service/get_cpu_profile_timeline_rpc_test.dart
@@ -0,0 +1,57 @@
+// 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+fib(n) {
+  if (n < 0) return 0;
+  if (n == 0) return 1;
+  return fib(n - 1) + fib(n - 2);
+}
+
+testeeDo() {
+  print("Testee doing something.");
+  fib(25);
+  print("Testee did something.");
+}
+
+var tests = [
+  (Isolate isolate) async {
+    var params = {
+      'tags': 'VMUser'
+    };
+    var result = await isolate.invokeRpcNoUpgrade(
+        '_getCpuProfileTimeline', params);
+    print(result);
+    expect(result['type'], equals('_CpuProfileTimeline'));
+
+    var isString = new isInstanceOf<String>();
+    var isInt = new isInstanceOf<int>();
+
+    Map frames = result['stackFrames'];
+    for (Map frame in frames.values) {
+      expect(frame['category'], isString);
+      expect(frame['name'], isString);
+      if (frame['parent'] != null) {
+        expect(frames.containsKey(frame['parent']), isTrue);
+      }
+    }
+
+    List events = result['traceEvents'];
+    for (Map event in events) {
+      expect(event['ph'], equals('P'));
+      expect(event['pid'], isInt);
+      expect(event['tid'], isInt);
+      expect(event['ts'], isInt);
+      expect(event['cat'], equals("Dart"));
+      expect(frames.containsKey(event['sf']), isTrue);
+    }
+  },
+];
+
+main(args) async => runIsolateTests(args, tests, testeeBefore: testeeDo);
diff --git a/runtime/observatory/tests/service/get_stack_rpc_test.dart b/runtime/observatory/tests/service/get_stack_rpc_test.dart
index 2bf7c3a..7757819 100644
--- a/runtime/observatory/tests/service/get_stack_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_rpc_test.dart
@@ -74,7 +74,7 @@
   for (var message in stack['messages']) {
     print('checking message $messageDepth');
     expect(message.index, equals(messageDepth++));
-    expect(message.size, greaterThanOrEqualTo(1));
+    expect(message.size, greaterThanOrEqualTo(0));
     expect(message.handler.type, equals('Function'));
     expect(message.location.type, equals('SourceLocation'));
     if (message.handler.name.contains('msgHandler')) {
diff --git a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
index a1f4806..3de30cb 100644
--- a/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_vm_timeline_rpc_test.dart
@@ -46,6 +46,10 @@
       // Skip VM category events which don't have an isolate.
       continue;
     }
+    if (event['cat'] == 'API') {
+      // Skip API category events which sometimes don't have an isolate.
+      continue;
+    }
     Map arguments = event['args'];
     expect(arguments, new isInstanceOf<Map>());
     expect(arguments['isolateNumber'], new isInstanceOf<String>());
diff --git a/runtime/observatory/tests/service/observatory_assets_test.dart b/runtime/observatory/tests/service/observatory_assets_test.dart
new file mode 100644
index 0000000..bd3befb
--- /dev/null
+++ b/runtime/observatory/tests/service/observatory_assets_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'dart:io';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_helper.dart';
+
+var tests = [
+  (VM vm) async {
+    // Simple heartbeat test to ensure we can fetch Observatory resources.
+    var heartBeatUrl =
+        serviceHttpAddress + '/third_party/trace_viewer_full.html';
+    print('Trying to fetch $heartBeatUrl');
+    HttpClient client = new HttpClient();
+    HttpClientRequest request = await client.getUrl(Uri.parse(heartBeatUrl));
+    HttpClientResponse response = await request.close();
+    expect(response.statusCode, 200);
+    await response.drain();
+  }
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 84145a3..0044c29 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -15,7 +15,7 @@
 *: SkipByDesign
 
 # Tests with known analyzer issues
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 developer_extension_test: SkipByDesign
 
 [ $arch == arm ]
diff --git a/runtime/observatory/web/timeline.js b/runtime/observatory/web/timeline.js
index 155d010..27f572c 100644
--- a/runtime/observatory/web/timeline.js
+++ b/runtime/observatory/web/timeline.js
@@ -40,18 +40,50 @@
   console.log('GET ' + uri);
 }
 
+
+var traceObject;
+var pendingRequests;
+
+function gotReponse() {
+  pendingRequests--;
+  if (pendingRequests == 0) {
+    console.log("Got all timeline parts");
+    updateTimeline(traceObject);
+  }
+}
+
 function fetchTimelineOnLoad(event) {
   var xhr = event.target;
   var response = JSON.parse(xhr.responseText);
   var result = response['result'];
-  var traceEvents = result['traceEvents'];
-  updateTimeline(traceEvents);
+  var newStackFrames = result['stackFrames'];  // Map.
+  var newTraceEvents = result['traceEvents'];  // List.
+
+  // Merge in timeline events.
+  traceObject.traceEvents = traceObject.traceEvents.concat(newTraceEvents);
+  for (var key in newStackFrames) {
+    if (newStackFrames.hasOwnProperty(key)) {
+      traceObject.stackFrames[key] = newStackFrames[key];
+    }
+  }
+
+  gotReponse();
 }
 
 function fetchTimelineOnError(event) {
+  var xhr = event.target;
+  console.log(xhr.statusText);
+  gotReponse();
 }
 
-function fetchTimeline(vmAddress) {
+function fetchTimeline(vmAddress, isolateIds) {
+  // Reset combined timeline.
+  traceObject = {
+    'stackFrames': {},
+    'traceEvents': []
+  };
+  pendingRequests = 1 + isolateIds.length;
+
   var parser = document.createElement('a');
   parser.href = vmAddress;
   var requestUri = 'http://' +
@@ -60,6 +92,17 @@
                    parser.port +
                    '/_getVMTimeline';
   fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
+
+  for (var i = 0; i < isolateIds.length; i++) {
+    var isolateId = isolateIds[i];
+    var requestUri = 'http://' +
+                     parser.hostname +
+                     ':' +
+                     parser.port +
+                     '/_getCpuProfileTimeline?tags=VMUser&isolateId=' +
+                     isolateId;
+    fetchUri(requestUri, fetchTimelineOnLoad, fetchTimelineOnError);
+  }
 }
 
 function onMessage(event) {
@@ -68,7 +111,7 @@
   var params = request['params'];
   switch (method) {
     case 'refresh':
-      fetchTimeline(params['vmAddress']);
+      fetchTimeline(params['vmAddress'], params['isolateIds']);
     break;
     case 'clear':
       clearTimeline();
@@ -90,4 +133,4 @@
   registerForMessages();
 });
 
-console.log('loaded');
\ No newline at end of file
+console.log('loaded');
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index faa6779..21a91f8 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -53,7 +53,7 @@
 # minifying they can be renamed, which is issue 7953.
 dart/inline_stack_frame_test: RuntimeError, Pass # Issue 7953
 
-[ $compiler == dart2js || $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2js || $compiler == dart2analyzer ]
 # Data uri's not supported by dart2js or the analyzer.
 dart/data_uri*test: Skip
 
@@ -70,7 +70,7 @@
 [ $arch == mips && $mode == debug ]
 cc/FindCodeObject: Skip # Takes more than 8 minutes. Issue 17440
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 dart/optimized_stacktrace_test: StaticWarning
 
 [ $runtime != vm ]
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index f2fe6c1..7b0e99d 100644
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -14,8 +14,11 @@
 import tarfile
 import tempfile
 
-def makeArchive(tar_path, client_root, files):
-  tar = tarfile.open(tar_path, mode='w')
+def makeArchive(tar_path, client_root, compress, files):
+  mode_string = 'w'
+  if compress:
+    mode_string = 'w:gz'
+  tar = tarfile.open(tar_path, mode=mode_string)
   for input_file_name in files:
     # Chop off client_root.
     archive_file_name = input_file_name[ len(client_root) : ]
@@ -98,6 +101,7 @@
     parser.add_option("--name",
                       action="store", type="string",
                       help="name of tar archive symbol")
+    parser.add_option("--compress", action="store_true", default=False)
     parser.add_option("--client_root",
                       action="store", type="string",
                       help="root directory client resources")
@@ -129,7 +133,10 @@
         files.append(src_path)
 
     # Write out archive.
-    makeArchive(options.tar_output, options.client_root, files)
+    makeArchive(options.tar_output,
+                options.client_root,
+                options.compress,
+                files)
 
     # Read it back in.
     with open(options.tar_output, 'rb') as tar_file:
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 8698e26..0b585d5 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -99,7 +99,7 @@
   LocalVariable* temp_var =
       new LocalVariable(token_pos(),
                         String::ZoneHandle(Symbols::New(name)),
-                        Type::ZoneHandle(Type::DynamicType()));
+                        Object::dynamic_type());
   vars_.Add(temp_var);
   return temp_var;
 }
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index 95d8d4f..ae42b70 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -71,7 +71,7 @@
   if (await_tmp == NULL) {
     // We need a new temp variable; add it to the function's top scope.
     await_tmp = new (Z) LocalVariable(
-        Scanner::kNoSourcePos, symbol, Type::ZoneHandle(Type::DynamicType()));
+        Scanner::kNoSourcePos, symbol, Object::dynamic_type());
     async_temp_scope_->AddVariable(await_tmp);
     // After adding it to the top scope, we can look it up from the preamble.
     // The following call includes an ASSERT check.
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 76413a6..3d2254f 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -73,6 +73,7 @@
   V(Developer_lookupExtension, 1)                                              \
   V(Developer_registerExtension, 2)                                            \
   V(Developer_log, 8)                                                          \
+  V(Developer_postEvent, 2)                                                    \
   V(Double_getIsNegative, 1)                                                   \
   V(Double_getIsInfinite, 1)                                                   \
   V(Double_getIsNaN, 1)                                                        \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 9ca3731..1151e2d 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2069,6 +2069,7 @@
 
 void ClassFinalizer::CreateForwardingConstructors(
     const Class& mixin_app,
+    const Class& mixin_cls,
     const GrowableObjectArray& cloned_funcs) {
   const String& mixin_name = String::Handle(mixin_app.Name());
   const Class& super_class = Class::Handle(mixin_app.SuperClass());
@@ -2091,6 +2092,13 @@
                   ctor_name.ToCString(),
                   clone_name.ToCString());
       }
+
+      // The owner of the forwarding constructor is the mixin application
+      // class. The source is the mixin class. The source may be needed
+      // to parse field initializer expressions in the mixin class.
+      const PatchClass& owner =
+          PatchClass::Handle(PatchClass::New(mixin_app, mixin_cls));
+
       const Function& clone = Function::Handle(
           Function::New(clone_name,
                         func.kind(),
@@ -2099,9 +2107,8 @@
                         false,  // Not abstract.
                         false,  // Not external.
                         false,  // Not native.
-                        mixin_app,
-                        mixin_app.token_pos()));
-
+                        owner,
+                        mixin_cls.token_pos()));
       clone.set_num_fixed_parameters(func.num_fixed_parameters());
       clone.SetNumOptionalParameters(func.NumOptionalParameters(),
                                      func.HasOptionalPositionalParameters());
@@ -2151,7 +2158,7 @@
   const GrowableObjectArray& cloned_funcs =
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
 
-  CreateForwardingConstructors(cls, cloned_funcs);
+  CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
 
   Array& functions = Array::Handle(zone);
   Function& func = Function::Handle(zone);
@@ -2381,7 +2388,12 @@
       (cls.functions() == Object::empty_array().raw())) {
     const GrowableObjectArray& cloned_funcs =
         GrowableObjectArray::Handle(GrowableObjectArray::New());
-    CreateForwardingConstructors(cls, cloned_funcs);
+
+    const Class& mixin_app_class = Class::Handle(cls.SuperClass());
+    const Type& mixin_type = Type::Handle(mixin_app_class.mixin());
+    const Class& mixin_cls = Class::Handle(mixin_type.type_class());
+
+    CreateForwardingConstructors(cls, mixin_cls, cloned_funcs);
     const Array& functions = Array::Handle(Array::MakeArray(cloned_funcs));
     cls.SetFunctions(functions);
   }
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 0b8d7c5..3aa7c2c 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -123,6 +123,7 @@
   static void ApplyMixinMembers(const Class& cls);
   static void CreateForwardingConstructors(
       const Class& mixin_app,
+      const Class& mixin_cls,
       const GrowableObjectArray& cloned_funcs);
   static void CollectTypeArguments(const Class& cls,
                                    const Type& type,
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 493cc0e..17edba2 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -314,10 +314,7 @@
                             "CompileClass");
   if (tds.enabled()) {
     tds.SetNumArguments(1);
-    tds.CopyArgument(
-        0,
-        "class",
-        const_cast<char*>(cls.ToCString()));
+    tds.CopyArgument(0, "class", cls.ToCString());
   }
 
   GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
@@ -414,6 +411,7 @@
   Thread* const thread = Thread::Current();
   Zone* const zone = thread->zone();
   Isolate* const isolate = thread->isolate();
+  TimelineStream* compiler_timeline = isolate->GetCompilerStream();
   CSTAT_TIMER_SCOPE(thread, codegen_timer);
   HANDLESCOPE(thread);
 
@@ -433,7 +431,8 @@
   bool done = false;
   // volatile because the variable may be clobbered by a longjmp.
   volatile bool use_far_branches = false;
-  volatile bool use_speculative_inlining = true;
+  volatile bool use_speculative_inlining =
+      FLAG_max_speculative_inlining_attempts > 0;
   GrowableArray<intptr_t> inlining_black_list;
 
   while (!done) {
@@ -475,6 +474,9 @@
           }
         }
 
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "BuildFlowGraph");
         flow_graph = pipeline->BuildFlowGraph(zone,
                                               parsed_function,
                                               *ic_data_array,
@@ -498,10 +500,16 @@
       const bool reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized);
       if (reorder_blocks) {
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "BlockScheduler::AssignEdgeWeights");
         block_scheduler.AssignEdgeWeights();
       }
 
       if (optimized) {
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "ComputeSSA");
         CSTAT_TIMER_SCOPE(thread, ssa_timer);
         // Transform to SSA (virtual register 0 and no inlining arguments).
         flow_graph->ComputeSSA(0, NULL);
@@ -520,6 +528,9 @@
       // have non-generic type feedback attached to them that can
       // potentially affect optimizations.
       if (optimized) {
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "OptimizationPasses");
         inline_id_to_function.Add(&function);
         // Top scope function has no caller (-1).
         caller_inline_id.Add(-1);
@@ -549,6 +560,9 @@
 
         // Inlining (mutates the flow graph)
         if (FLAG_use_inlining) {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "Inlining");
           CSTAT_TIMER_SCOPE(thread, graphinliner_timer);
           // Propagate types to create more inlining opportunities.
           FlowGraphTypePropagator::Propagate(flow_graph);
@@ -572,9 +586,14 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Use propagated class-ids to optimize further.
-        optimizer.ApplyClassIds();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "ApplyClassIds");
+          // Use propagated class-ids to optimize further.
+          optimizer.ApplyClassIds();
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         // Propagate types for potentially newly added instructions by
         // ApplyClassIds(). Must occur before canonicalization.
@@ -589,13 +608,21 @@
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        BranchSimplifier::Simplify(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "BranchSimplifier");
+          BranchSimplifier::Simplify(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        IfConverter::Simplify(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          IfConverter::Simplify(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         if (FLAG_constant_propagation) {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "ConstantPropagation");
           ConstantPropagator::Optimize(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // A canonicalization pass to remove e.g. smi checks on smi constants.
@@ -621,43 +648,54 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Where beneficial convert Smi operations into Int32 operations.
-        // Only meanigful for 32bit platforms right now.
-        optimizer.WidenSmiToInt32();
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "SelectRepresentations");
+          // Where beneficial convert Smi operations into Int32 operations.
+          // Only meanigful for 32bit platforms right now.
+          optimizer.WidenSmiToInt32();
 
-        // Unbox doubles. Performed after constant propagation to minimize
-        // interference from phis merging double values and tagged
-        // values coming from dead paths.
-        optimizer.SelectRepresentations();
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
-
-        if (FLAG_common_subexpression_elimination ||
-            FLAG_loop_invariant_code_motion) {
-          flow_graph->ComputeBlockEffects();
-        }
-
-        if (FLAG_common_subexpression_elimination) {
-          if (DominatorBasedCSE::Optimize(flow_graph)) {
-            DEBUG_ASSERT(flow_graph->VerifyUseLists());
-            optimizer.Canonicalize();
-            // Do another round of CSE to take secondary effects into account:
-            // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
-            // TODO(fschneider): Change to a one-pass optimization pass.
-            if (DominatorBasedCSE::Optimize(flow_graph)) {
-              optimizer.Canonicalize();
-            }
-            DEBUG_ASSERT(flow_graph->VerifyUseLists());
-          }
-        }
-
-        // Run loop-invariant code motion right after load elimination since it
-        // depends on the numbering of loads from the previous load-elimination.
-        if (FLAG_loop_invariant_code_motion) {
-          LICM licm(flow_graph);
-          licm.Optimize();
+          // Unbox doubles. Performed after constant propagation to minimize
+          // interference from phis merging double values and tagged
+          // values coming from dead paths.
+          optimizer.SelectRepresentations();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
-        flow_graph->RemoveRedefinitions();
+
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "CommonSubexpressionElinination");
+          if (FLAG_common_subexpression_elimination ||
+              FLAG_loop_invariant_code_motion) {
+            flow_graph->ComputeBlockEffects();
+          }
+
+          if (FLAG_common_subexpression_elimination) {
+            if (DominatorBasedCSE::Optimize(flow_graph)) {
+              DEBUG_ASSERT(flow_graph->VerifyUseLists());
+              optimizer.Canonicalize();
+              // Do another round of CSE to take secondary effects into account:
+              // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
+              // TODO(fschneider): Change to a one-pass optimization pass.
+              if (DominatorBasedCSE::Optimize(flow_graph)) {
+                optimizer.Canonicalize();
+              }
+              DEBUG_ASSERT(flow_graph->VerifyUseLists());
+            }
+          }
+
+          // Run loop-invariant code motion right after load elimination since
+          // it depends on the numbering of loads from the previous
+          // load-elimination.
+          if (FLAG_loop_invariant_code_motion) {
+            LICM licm(flow_graph);
+            licm.Optimize();
+            DEBUG_ASSERT(flow_graph->VerifyUseLists());
+          }
+          flow_graph->RemoveRedefinitions();
+        }
 
         // Optimize (a << b) & c patterns, merge operations.
         // Run after CSE in order to have more opportunity to merge
@@ -665,9 +703,17 @@
         optimizer.TryOptimizePatterns();
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        DeadStoreElimination::Optimize(flow_graph);
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "DeadStoreElimination");
+          DeadStoreElimination::Optimize(flow_graph);
+        }
 
         if (FLAG_range_analysis) {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "RangeAnalysis");
           // Propagate types after store-load-forwarding. Some phis may have
           // become smi phis that can be processed by range analysis.
           FlowGraphTypePropagator::Propagate(flow_graph);
@@ -681,6 +727,9 @@
         }
 
         if (FLAG_constant_propagation) {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "ConstantPropagator::OptimizeBranches");
           // Constant propagation can use information from range analysis to
           // find unreachable branch targets and eliminate branches that have
           // the same true- and false-target.
@@ -693,16 +742,26 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Optimize try-blocks.
-        TryCatchAnalyzer::Optimize(flow_graph);
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "TryCatchAnalyzer::Optimize");
+          // Optimize try-blocks.
+          TryCatchAnalyzer::Optimize(flow_graph);
+        }
 
         // Detach environments from the instructions that can't deoptimize.
         // Do it before we attempt to perform allocation sinking to minimize
         // amount of materializations it has to perform.
         optimizer.EliminateEnvironments();
 
-        DeadCodeElimination::EliminateDeadPhis(flow_graph);
-        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "EliminateDeadPhis");
+          DeadCodeElimination::EliminateDeadPhis(flow_graph);
+          DEBUG_ASSERT(flow_graph->VerifyUseLists());
+        }
 
         if (optimizer.Canonicalize()) {
           optimizer.Canonicalize();
@@ -713,6 +772,9 @@
         AllocationSinking* sinking = NULL;
         if (FLAG_allocation_sinking &&
             (flow_graph->graph_entry()->SuccessorCount()  == 1)) {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "AllocationSinking::Optimize");
           // TODO(fschneider): Support allocation sinking with try-catch.
           sinking = new AllocationSinking(flow_graph);
           sinking->Optimize();
@@ -725,9 +787,14 @@
         FlowGraphTypePropagator::Propagate(flow_graph);
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
-        // Ensure that all phis inserted by optimization passes have consistent
-        // representations.
-        optimizer.SelectRepresentations();
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "SelectRepresentations");
+          // Ensure that all phis inserted by optimization passes have
+          // consistent representations.
+          optimizer.SelectRepresentations();
+        }
 
         if (optimizer.Canonicalize()) {
           // To fully remove redundant boxing (e.g. BoxDouble used only in
@@ -740,6 +807,10 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         if (sinking != NULL) {
+          TimelineDurationScope tds2(
+              thread,
+              compiler_timeline,
+              "AllocationSinking::DetachMaterializations");
           // Remove all MaterializeObject instructions inserted by allocation
           // sinking from the flow graph and let them float on the side
           // referenced only from environments. Register allocator will consider
@@ -751,10 +822,21 @@
         // to be later used by the inliner.
         FlowGraphInliner::CollectGraphInfo(flow_graph, true);
 
-        // Perform register allocation on the SSA graph.
-        FlowGraphAllocator allocator(*flow_graph);
-        allocator.AllocateRegisters();
-        if (reorder_blocks) block_scheduler.ReorderBlocks();
+        {
+          TimelineDurationScope tds2(thread,
+                                     compiler_timeline,
+                                     "AllocateRegisters");
+          // Perform register allocation on the SSA graph.
+          FlowGraphAllocator allocator(*flow_graph);
+          allocator.AllocateRegisters();
+        }
+
+        if (reorder_blocks) {
+          TimelineDurationScope tds(thread,
+                                    compiler_timeline,
+                                    "BlockScheduler::ReorderBlocks");
+          block_scheduler.ReorderBlocks();
+        }
 
         if (print_flow_graph) {
           FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph);
@@ -769,10 +851,16 @@
                                        caller_inline_id);
       {
         CSTAT_TIMER_SCOPE(thread, graphcompiler_timer);
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "CompileGraph");
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation();
       }
       {
+        TimelineDurationScope tds(thread,
+                                  compiler_timeline,
+                                  "FinalizeCompilation");
         // This part of compilation must be at a safepoint.
         if (!Thread::Current()->IsMutatorThread()) {
           // Stop mutator thread before creating the instruction object and
@@ -1503,7 +1591,7 @@
         Class::Handle(Type::Handle(Type::Function()).type_class()),
         fragment->token_pos()));
 
-    func.set_result_type(Type::Handle(Type::DynamicType()));
+    func.set_result_type(Object::dynamic_type());
     func.set_num_fixed_parameters(0);
     func.SetNumOptionalParameters(0, true);
     // Manually generated AST, do not recompile.
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 5e4f53c..1b70c96 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -867,7 +867,7 @@
   if (IsConstant(object)) {
     if (instr->type().IsTypeParameter()) {
       if (object.IsNull()) {
-        SetValue(instr, Type::ZoneHandle(Z, Type::DynamicType()));
+        SetValue(instr, Object::dynamic_type());
         return;
       }
       // We could try to instantiate the type parameter and return it if no
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index 2cb2e00..b78ea60 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -243,7 +243,7 @@
 }
 
 
-const char* saved_echo = NULL;
+char* saved_echo = NULL;
 static void native_echo(Dart_NativeArguments args) {
   Dart_EnterScope();
   Dart_Handle arg = Dart_GetNativeArgument(args, 0);
@@ -252,7 +252,7 @@
   const char* c_str = NULL;
   EXPECT_VALID(Dart_StringToCString(toString, &c_str));
   if (saved_echo) {
-    free(const_cast<char*>(saved_echo));
+    free(saved_echo);
   }
   saved_echo = strdup(c_str);
   OS::Print("-- (isolate=%p) %s\n", Dart_CurrentIsolate(), c_str);
@@ -350,7 +350,7 @@
   }
   OS::Print("-- Finished event loop --\n");
   EXPECT_STREQ("Received: 43", saved_echo);
-  free(const_cast<char*>(saved_echo));
+  free(saved_echo);
 
   delete event_queue;
   event_queue = NULL;
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index eb12276..7568924 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -225,6 +225,14 @@
   // Shut down profiling.
   Profiler::Shutdown();
 
+  {
+    // Set the VM isolate as current isolate when shutting down
+    // Metrics so that we can use a StackZone.
+    Thread::EnterIsolate(vm_isolate_);
+    Metric::Cleanup();
+    Thread::ExitIsolate();
+  }
+
   if (FLAG_shutdown) {
     // Disable the creation of new isolates.
     Isolate::DisableIsolateCreation();
@@ -266,7 +274,6 @@
 
   CodeObservers::DeleteAll();
   Timeline::Shutdown();
-  Metric::Cleanup();
 
   return NULL;
 }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index f607b18..a61715b 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -59,8 +59,6 @@
 DEFINE_FLAG(bool, check_function_fingerprints, true,
             "Check function fingerprints");
 #endif  // defined(DART_NO_SNAPSHOT).
-DEFINE_FLAG(bool, trace_api, false,
-            "Trace invocation of API calls (debug mode only)");
 DEFINE_FLAG(bool, verify_acquired_data, false,
             "Verify correct API acquire/release of typed data.");
 
@@ -79,6 +77,20 @@
   }
 }
 
+#if 0
+#define API_TIMELINE_DURATION                                                  \
+  TimelineDurationScope tds(Thread::Current(),                                 \
+                            Timeline::GetVMApiStream(),                        \
+                            CURRENT_FUNC)
+
+#define API_TIMELINE_BEGIN_END                                                 \
+  TimelineBeginEndScope tbes(Thread::Current(),                                \
+                             Timeline::GetVMApiStream(),                       \
+                             CURRENT_FUNC)
+#else
+#define API_TIMELINE_DURATION ASSERT(true)
+#define API_TIMELINE_BEGIN_END ASSERT(true)
+#endif
 
 #if defined(DEBUG)
 // An object visitor which will iterate over all the function objects in the
@@ -701,31 +713,26 @@
 // --- Handles ---
 
 DART_EXPORT bool Dart_IsError(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsErrorClassId(Api::ClassId(handle));
 }
 
 
 DART_EXPORT bool Dart_IsApiError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kApiErrorCid;
 }
 
 
 DART_EXPORT bool Dart_IsUnhandledExceptionError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kUnhandledExceptionCid;
 }
 
 
 DART_EXPORT bool Dart_IsCompilationError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kLanguageErrorCid;
 }
 
 
 DART_EXPORT bool Dart_IsFatalError(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kUnwindErrorCid;
 }
 
@@ -738,6 +745,7 @@
 
 
 DART_EXPORT const char* Dart_GetError(Dart_Handle handle) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsError()) {
@@ -1280,7 +1288,6 @@
 
 
 DART_EXPORT void* Dart_IsolateData(Dart_Isolate isolate) {
-  TRACE_API_CALL(CURRENT_FUNC);
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1449,7 +1456,6 @@
 
 
 DART_EXPORT void Dart_InterruptIsolate(Dart_Isolate isolate) {
-  TRACE_API_CALL(CURRENT_FUNC);
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1461,6 +1467,7 @@
 
 DART_EXPORT bool Dart_IsolateMakeRunnable(Dart_Isolate isolate) {
   CHECK_NO_ISOLATE(Isolate::Current());
+  API_TIMELINE_DURATION;
   if (isolate == NULL) {
     FATAL1("%s expects argument 'isolate' to be non-null.",  CURRENT_FUNC);
   }
@@ -1504,6 +1511,7 @@
   Isolate* I = T->isolate();
   CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_BEGIN_END;
   Monitor monitor;
   MonitorLocker ml(&monitor);
   {
@@ -1539,6 +1547,7 @@
   Isolate* I = T->isolate();
   CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_BEGIN_END;
   if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
     Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error());
     I->object_store()->clear_sticky_error();
@@ -1553,7 +1562,7 @@
   Isolate* I = T->isolate();
   CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
-
+  API_TIMELINE_DURATION;
   ASSERT(I->GetAndClearResumeRequest() == false);
   MessageHandler::MessageStatus status =
       I->message_handler()->HandleOOBMessages();
@@ -1584,10 +1593,20 @@
 
 DART_EXPORT bool Dart_Post(Dart_Port port_id, Dart_Handle handle) {
   DARTSCOPE(Thread::Current());
+  API_TIMELINE_DURATION;
+  NoSafepointScope no_safepoint_scope;
   if (port_id == ILLEGAL_PORT) {
     return false;
   }
-  const Object& object = Object::Handle(Z, Api::UnwrapHandle(handle));
+
+  // Smis and null can be sent without serialization.
+  RawObject* raw_obj = Api::UnwrapHandle(handle);
+  if (ApiObjectConverter::CanConvert(raw_obj)) {
+    return PortMap::PostMessage(new Message(
+        port_id, raw_obj, Message::kNormalPriority));
+  }
+
+  const Object& object = Object::Handle(Z, raw_obj);
   uint8_t* data = NULL;
   MessageWriter writer(&data, &allocator, false);
   writer.WriteMessage(object);
@@ -1613,6 +1632,7 @@
                                            Dart_Port* port_id) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
   const SendPort& send_port = Api::UnwrapSendPortHandle(Z, port);
   if (send_port.IsNull()) {
     RETURN_TYPE_ERROR(Z, port, SendPort);
@@ -1772,50 +1792,42 @@
 
 
 DART_EXPORT bool Dart_IsNumber(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsNumberClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsInteger(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsIntegerClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsDouble(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kDoubleCid;
 }
 
 
 DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kBoolCid;
 }
 
 
 DART_EXPORT bool Dart_IsString(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsOneByteStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsExternalString(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return RawObject::IsExternalStringClassId(Api::ClassId(object));
 }
 
 
 DART_EXPORT bool Dart_IsList(Dart_Handle object) {
   if (RawObject::IsBuiltinListClassId(Api::ClassId(object))) {
-    TRACE_API_CALL(CURRENT_FUNC);
     return true;
   }
 
@@ -1833,31 +1845,26 @@
 
 
 DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(object) == kLibraryCid;
 }
 
 
 DART_EXPORT bool Dart_IsType(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kTypeCid;
 }
 
 
 DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kFunctionCid;
 }
 
 
 DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kFieldCid;
 }
 
 
 DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kTypeParameterCid;
 }
 
@@ -1875,7 +1882,6 @@
 
 
 DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   intptr_t cid = Api::ClassId(handle);
   return RawObject::IsTypedDataClassId(cid) ||
          RawObject::IsExternalTypedDataClassId(cid) ||
@@ -1884,13 +1890,12 @@
 
 
 DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
   return Api::ClassId(handle) == kByteBufferCid;
 }
 
 
 DART_EXPORT bool Dart_IsFuture(Dart_Handle handle) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
@@ -1914,6 +1919,7 @@
 // --- Instances ----
 
 DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(instance));
@@ -1932,6 +1938,7 @@
 
 DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer,
                                                   bool* fits) {
+  API_TIMELINE_DURATION;
   // Fast path for Smis and Mints.
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
@@ -1959,6 +1966,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Api::IsSmi(integer)) {
     *fits = (Api::SmiValue(integer) >= 0);
     return Api::Success();
@@ -1984,6 +1992,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Smi::IsValid(value)) {
     NOHANDLESCOPE(thread);
     return Api::NewHandle(thread, Smi::New(static_cast<intptr_t>(value)));
@@ -1998,6 +2007,7 @@
 DART_EXPORT Dart_Handle Dart_NewIntegerFromUint64(uint64_t value) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
   return Api::NewHandle(T, Integer::NewFromUint64(value));
 }
 
@@ -2005,6 +2015,7 @@
 DART_EXPORT Dart_Handle Dart_NewIntegerFromHexCString(const char* str) {
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_DURATION;
   const String& str_obj = String::Handle(Z, String::New(str));
   return Api::NewHandle(T, Integer::New(str_obj));
 }
@@ -2016,6 +2027,7 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   CHECK_ISOLATE(isolate);
+  API_TIMELINE_DURATION;
   if (Api::IsSmi(integer)) {
     *value = Api::SmiValue(integer);
     return Api::Success();
@@ -2044,6 +2056,7 @@
 
 DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer,
                                              uint64_t* value) {
+  API_TIMELINE_DURATION;
   // Fast path for Smis.
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
@@ -2085,6 +2098,7 @@
 
 DART_EXPORT Dart_Handle Dart_IntegerToHexCString(Dart_Handle integer,
                                                  const char** value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Integer& int_obj = Api::UnwrapIntegerHandle(Z, integer);
   if (int_obj.IsNull()) {
@@ -2102,6 +2116,7 @@
 
 
 DART_EXPORT Dart_Handle Dart_NewDouble(double value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
   return Api::NewHandle(T, Double::New(value));
@@ -2110,6 +2125,7 @@
 
 DART_EXPORT Dart_Handle Dart_DoubleValue(Dart_Handle double_obj,
                                          double* value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Double& obj = Api::UnwrapDoubleHandle(Z, double_obj);
   if (obj.IsNull()) {
@@ -2170,6 +2186,7 @@
 
 
 DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char* str) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (str == NULL) {
     RETURN_NULL_ERROR(str);
@@ -2181,6 +2198,7 @@
 
 DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t* utf8_array,
                                                intptr_t length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf8_array == NULL && length != 0) {
     RETURN_NULL_ERROR(utf8_array);
@@ -2209,6 +2227,7 @@
 
 DART_EXPORT Dart_Handle Dart_NewStringFromUTF32(const int32_t* utf32_array,
                                                 intptr_t length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf32_array == NULL && length != 0) {
     RETURN_NULL_ERROR(utf32_array);
@@ -2224,6 +2243,7 @@
     intptr_t length,
     void* peer,
     Dart_PeerFinalizer cback) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (latin1_array == NULL && length != 0) {
     RETURN_NULL_ERROR(latin1_array);
@@ -2259,6 +2279,7 @@
 
 DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object,
                                              const char** cstr) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (cstr == NULL) {
     RETURN_NULL_ERROR(cstr);
@@ -2283,6 +2304,7 @@
 DART_EXPORT Dart_Handle Dart_StringToUTF8(Dart_Handle str,
                                           uint8_t** utf8_array,
                                           intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (utf8_array == NULL) {
     RETURN_NULL_ERROR(utf8_array);
@@ -2308,6 +2330,7 @@
 DART_EXPORT Dart_Handle Dart_StringToLatin1(Dart_Handle str,
                                             uint8_t* latin1_array,
                                             intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   if (latin1_array == NULL) {
     RETURN_NULL_ERROR(latin1_array);
@@ -2335,6 +2358,7 @@
 DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str,
                                            uint16_t* utf16_array,
                                            intptr_t* length) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const String& str_obj = Api::UnwrapStringHandle(Z, str);
   if (str_obj.IsNull()) {
@@ -2897,7 +2921,7 @@
 
 DART_EXPORT Dart_Handle Dart_ListSetAsBytes(Dart_Handle list,
                                             intptr_t offset,
-                                            uint8_t* native_array,
+                                            const uint8_t* native_array,
                                             intptr_t length) {
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(list));
@@ -3096,7 +3120,7 @@
 
 
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfTypedData(Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   intptr_t class_id = Api::ClassId(object);
   if (RawObject::IsTypedDataClassId(class_id) ||
       RawObject::IsTypedDataViewClassId(class_id)) {
@@ -3108,7 +3132,7 @@
 
 DART_EXPORT Dart_TypedData_Type Dart_GetTypeOfExternalTypedData(
     Dart_Handle object) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   intptr_t class_id = Api::ClassId(object);
   if (RawObject::IsExternalTypedDataClassId(class_id)) {
     return GetType(class_id);
@@ -3857,6 +3881,7 @@
                                                Dart_Handle name,
                                                int number_of_arguments,
                                                Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -3935,6 +3960,7 @@
                                     Dart_Handle name,
                                     int number_of_arguments,
                                     Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4061,6 +4087,7 @@
 DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure,
                                            int number_of_arguments,
                                            Dart_Handle* arguments) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
   const Instance& closure_obj = Api::UnwrapInstanceHandle(Z, closure);
@@ -4090,6 +4117,7 @@
 
 
 DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4210,6 +4238,7 @@
 DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container,
                                       Dart_Handle name,
                                       Dart_Handle value) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   CHECK_CALLBACK_STATE(T);
 
@@ -4661,7 +4690,7 @@
 
 DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
                                                int index) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4674,7 +4703,7 @@
 
 
 DART_EXPORT int Dart_GetNativeArgumentCount(Dart_NativeArguments args) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   return arguments->NativeArgCount();
 }
@@ -4733,7 +4762,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeIntegerArgument(Dart_NativeArguments args,
                                                       int index,
                                                       int64_t* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4751,7 +4780,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeBooleanArgument(Dart_NativeArguments args,
                                                       int index,
                                                       bool* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4769,7 +4798,7 @@
 DART_EXPORT Dart_Handle Dart_GetNativeDoubleArgument(Dart_NativeArguments args,
                                                      int index,
                                                      double* value) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   if ((index < 0) || (index >= arguments->NativeArgCount())) {
     return Api::NewError(
@@ -4857,7 +4886,7 @@
 // --- Scripts and Libraries ---
 DART_EXPORT void Dart_SetBooleanReturnValue(Dart_NativeArguments args,
                                             bool retval) {
-  TRACE_API_CALL(CURRENT_FUNC);
+  API_TIMELINE_DURATION;
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   arguments->SetReturn(Bool::Get(retval));
 }
@@ -4926,6 +4955,7 @@
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const String& url_str = Api::UnwrapStringHandle(Z, url);
@@ -4971,6 +5001,7 @@
 
 DART_EXPORT Dart_Handle Dart_LoadScriptFromSnapshot(const uint8_t* buffer,
                                                     intptr_t buffer_len) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   StackZone zone(T);
@@ -5186,6 +5217,7 @@
                                          Dart_Handle source,
                                          intptr_t line_offset,
                                          intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const String& url_str = Api::UnwrapStringHandle(Z, url);
@@ -5291,6 +5323,7 @@
                                         Dart_Handle source,
                                         intptr_t line_offset,
                                         intptr_t column_offset) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const Library& lib = Api::UnwrapLibraryHandle(Z, library);
@@ -5330,6 +5363,7 @@
 DART_EXPORT Dart_Handle Dart_LibraryLoadPatch(Dart_Handle library,
                                               Dart_Handle url,
                                               Dart_Handle patch_source) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const Library& lib = Api::UnwrapLibraryHandle(Z, library);
@@ -5360,6 +5394,7 @@
 // Finalizes classes and invokes Dart core library function that completes
 // futures of loadLibrary calls (deferred library loading).
 DART_EXPORT Dart_Handle Dart_FinalizeLoading(bool complete_futures) {
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   CHECK_CALLBACK_STATE(T);
@@ -5865,6 +5900,7 @@
 DART_EXPORT Dart_Handle Dart_Precompile(
     Dart_QualifiedFunctionName entry_points[],
     bool reset_fields) {
+  API_TIMELINE_BEGIN_END;
   DARTSCOPE(Thread::Current());
   if (!FLAG_precompilation) {
     return Dart_NewApiError("Flag --precompilation was not specified.");
@@ -5891,6 +5927,7 @@
     uint8_t** instructions_snapshot_buffer,
     intptr_t* instructions_snapshot_size) {
   ASSERT(FLAG_load_deferred_eagerly);
+  API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   if (I->compilation_allowed()) {
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index ccd8fa1..6172e1a 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -11,8 +11,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, trace_api);
-
 class ApiLocalScope;
 class ApiState;
 class FinalizablePersistentHandle;
@@ -24,20 +22,9 @@
 
 #define CURRENT_FUNC CanonicalFunction(__FUNCTION__)
 
-#if defined(DEBUG)
-#define TRACE_API_CALL(name)                                                   \
-  if (FLAG_trace_api) {                                                        \
-    OS::Print("Calling API func: %s\n", name);                                 \
-  }
-#else
-#define TRACE_API_CALL(name)
-#endif
-
-
 // Checks that the current isolate is not NULL.
 #define CHECK_ISOLATE(isolate)                                                 \
   do {                                                                         \
-    TRACE_API_CALL(CURRENT_FUNC);                                              \
     if ((isolate) == NULL) {                                                   \
       FATAL1("%s expects there to be a current isolate. Did you "              \
              "forget to call Dart_CreateIsolate or Dart_EnterIsolate?",        \
@@ -48,7 +35,6 @@
 // Checks that the current isolate is NULL.
 #define CHECK_NO_ISOLATE(isolate)                                              \
   do {                                                                         \
-    TRACE_API_CALL(CURRENT_FUNC);                                              \
     if ((isolate) != NULL) {                                                   \
       FATAL1("%s expects there to be no current isolate. Did you "             \
              "forget to call Dart_ExitIsolate?", CURRENT_FUNC);                \
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 1499f37..3cbf287 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6980,6 +6980,7 @@
                            Dart_CObject* message) {
   // Gets a null message.
   EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
   EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
 
   // Post integer value.
@@ -7067,6 +7068,194 @@
 }
 
 
+void NewNativePort_sendInteger123(Dart_Port dest_port_id,
+                                  Dart_CObject *message) {
+  // Gets a send port message.
+  EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
+  EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
+
+  // Post integer value.
+  Dart_PostInteger(
+      message->value.as_array.values[0]->value.as_send_port.id, 123);
+}
+
+
+void NewNativePort_sendInteger321(Dart_Port dest_port_id,
+                                  Dart_CObject* message) {
+  // Gets a null message.
+  EXPECT_NOTNULL(message);
+  EXPECT_EQ(Dart_CObject_kArray, message->type);
+  EXPECT_EQ(Dart_CObject_kSendPort, message->value.as_array.values[0]->type);
+
+  // Post integer value.
+  Dart_PostInteger(
+      message->value.as_array.values[0]->value.as_send_port.id, 321);
+}
+
+
+TEST_CASE(NativePortPostInteger) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("Port123", NewNativePort_sendInteger123, true);
+  Dart_Port port_id2 =
+      Dart_NewNativePort("Port321", NewNativePort_sendInteger321, true);
+
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+  Dart_Handle send_port2 = Dart_NewSendPort(port_id2);
+  EXPECT_VALID(send_port2);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  // result second port.
+  dart_args[0] = send_port2;
+  result = Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 321\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+  EXPECT(Dart_CloseNativePort(port_id2));
+}
+
+
+void NewNativePort_nativeReceiveNull(Dart_Port dest_port_id,
+                                     Dart_CObject *message) {
+  EXPECT_NOTNULL(message);
+
+  if ((message->type == Dart_CObject_kArray) &&
+      (message->value.as_array.values[0]->type == Dart_CObject_kSendPort)) {
+    // Post integer value.
+    Dart_PostInteger(
+        message->value.as_array.values[0]->value.as_send_port.id, 123);
+  } else {
+    EXPECT_EQ(message->type, Dart_CObject_kNull);
+  }
+}
+
+
+TEST_CASE(NativePortReceiveNull) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send(null);\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("PortNull", NewNativePort_nativeReceiveNull, true);
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+}
+
+
+void NewNativePort_nativeReceiveInteger(Dart_Port dest_port_id,
+                                        Dart_CObject *message) {
+  EXPECT_NOTNULL(message);
+
+  if ((message->type == Dart_CObject_kArray) &&
+      (message->value.as_array.values[0]->type == Dart_CObject_kSendPort)) {
+    // Post integer value.
+    Dart_PostInteger(
+        message->value.as_array.values[0]->value.as_send_port.id, 123);
+  } else {
+    EXPECT_EQ(message->type, Dart_CObject_kInt32);
+    EXPECT_EQ(message->value.as_int32, 321);
+  }
+}
+
+
+TEST_CASE(NativePortReceiveInteger) {
+  const char* kScriptChars =
+      "import 'dart:isolate';\n"
+      "void callPort(SendPort port) {\n"
+      "  var receivePort = new RawReceivePort();\n"
+      "  var replyPort = receivePort.sendPort;\n"
+      "  port.send(321);\n"
+      "  port.send([replyPort]);\n"
+      "  receivePort.handler = (message) {\n"
+      "    receivePort.close();\n"
+      "    throw new Exception(message);\n"
+      "  };\n"
+      "}\n";
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
+  Dart_EnterScope();
+
+  Dart_Port port_id1 =
+      Dart_NewNativePort("PortNull", NewNativePort_nativeReceiveInteger, true);
+  Dart_Handle send_port1 = Dart_NewSendPort(port_id1);
+  EXPECT_VALID(send_port1);
+
+  // Test first port.
+  Dart_Handle dart_args[1];
+  dart_args[0] = send_port1;
+  Dart_Handle result =
+      Dart_Invoke(lib, NewString("callPort"), 1, dart_args);
+  EXPECT_VALID(result);
+  result = Dart_RunLoop();
+  EXPECT(Dart_IsError(result));
+  EXPECT(Dart_ErrorHasException(result));
+  EXPECT_SUBSTRING("Exception: 123\n", Dart_GetError(result));
+
+  Dart_ExitScope();
+
+  // Delete the native ports.
+  EXPECT(Dart_CloseNativePort(port_id1));
+}
+
+
 static Dart_Isolate RunLoopTestCallback(const char* script_name,
                                         const char* main,
                                         const char* package_root,
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index a4e47bb..182fc7d 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -18,15 +18,26 @@
       backward_references_(kNumInitialReferences),
       vm_isolate_references_(kNumInitialReferences),
       vm_symbol_references_(NULL) {
-  // We need to have an enclosing ApiNativeScope.
-  ASSERT(ApiNativeScope::Current() != NULL);
-  zone_ = ApiNativeScope::Current()->zone();
-  ASSERT(zone_ != NULL);
-  Init();
+}
+
+
+ApiMessageReader::ApiMessageReader(Message* msg)
+    : BaseReader(msg->IsRaw() ? reinterpret_cast<uint8_t*>(msg->raw_obj())
+                              : msg->data(),
+                 msg->len()),
+      zone_(NULL),
+      backward_references_(kNumInitialReferences),
+      vm_isolate_references_(kNumInitialReferences),
+      vm_symbol_references_(NULL) {
 }
 
 
 void ApiMessageReader::Init() {
+  // We need to have an enclosing ApiNativeScope.
+  ASSERT(ApiNativeScope::Current() != NULL);
+  zone_ = ApiNativeScope::Current()->zone();
+  ASSERT(zone_ != NULL);
+
   // Initialize marker objects used to handle Lists.
   // TODO(sjesse): Remove this when message serialization format is
   // updated.
@@ -40,8 +51,19 @@
 
 
 Dart_CObject* ApiMessageReader::ReadMessage() {
-  // Read the object out of the message.
-  return ReadObject();
+  Init();
+  if (PendingBytes() > 0) {
+    // Read the object out of the message.
+    return ReadObject();
+  } else {
+    const RawObject* raw_obj =
+        reinterpret_cast<const RawObject*>(CurrentBufferAddress());
+    ASSERT(ApiObjectConverter::CanConvert(raw_obj));
+    Dart_CObject* cobj =
+      reinterpret_cast<Dart_CObject*>(allocator(sizeof(Dart_CObject)));
+    ApiObjectConverter::Convert(raw_obj, cobj);
+    return cobj;
+  }
 }
 
 
@@ -210,7 +232,7 @@
       for (intptr_t i = 0; i < vm_isolate_references_.length(); i++) {
         object = vm_isolate_references_.At(i);
         if (object->type == Dart_CObject_kString) {
-          if (strcmp(str, const_cast<char*>(object->value.as_string)) == 0) {
+          if (strcmp(str, object->value.as_string) == 0) {
             return object;
           }
         }
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index 16a138b..f4675c4 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -6,7 +6,11 @@
 #define VM_DART_API_MESSAGE_H_
 
 #include "include/dart_native_api.h"
+#include "platform/utils.h"
+#include "vm/allocation.h"
 #include "vm/dart_api_state.h"
+#include "vm/message.h"
+#include "vm/raw_object.h"
 #include "vm/snapshot.h"
 
 namespace dart {
@@ -45,6 +49,7 @@
   // Allocation of all C Heap objects is done in the zone associated with
   // the enclosing ApiNativeScope.
   ApiMessageReader(const uint8_t* buffer, intptr_t length);
+  explicit ApiMessageReader(Message* message);
   ~ApiMessageReader() { }
 
   Dart_CObject* ReadMessage();
@@ -201,6 +206,48 @@
   DISALLOW_COPY_AND_ASSIGN(ApiMessageWriter);
 };
 
+
+// This class handles translation of certain RawObjects to CObjects for
+// NativeMessageHandlers.
+//
+// TODO(zra): Expand to support not only null, but also other VM heap objects
+// as well.
+class ApiObjectConverter : public AllStatic {
+ public:
+  static bool CanConvert(const RawObject* raw_obj) {
+    return !raw_obj->IsHeapObject() || (raw_obj == Object::null());
+  }
+
+  static bool Convert(const RawObject* raw_obj, Dart_CObject* c_obj) {
+    if (!raw_obj->IsHeapObject()) {
+      ConvertSmi(reinterpret_cast<const RawSmi*>(raw_obj), c_obj);
+    } else if (raw_obj == Object::null()) {
+      ConvertNull(c_obj);
+    } else {
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  static void ConvertSmi(const RawSmi* raw_smi, Dart_CObject* c_obj) {
+    ASSERT(!raw_smi->IsHeapObject());
+    intptr_t value = Smi::Value(raw_smi);
+    if (Utils::IsInt(31, value)) {
+      c_obj->type = Dart_CObject_kInt32;
+      c_obj->value.as_int32 = static_cast<int32_t>(value);
+    } else {
+      c_obj->type = Dart_CObject_kInt64;
+      c_obj->value.as_int64 = static_cast<int64_t>(value);
+    }
+  }
+
+  static void ConvertNull(Dart_CObject* c_obj) {
+    c_obj->type = Dart_CObject_kNull;
+    c_obj->value.as_int64 = 0;
+  }
+};
+
 }  // namespace dart
 
 #endif  // VM_DART_API_MESSAGE_H_
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 4ae6851..de926bf 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -168,9 +168,9 @@
       function ^= cls.LookupDynamicFunction(getter_name);
       if (!function.IsNull()) {
         Isolate* isolate = Isolate::Current();
-        uword c_stack_pos = Isolate::GetCurrentStackPointer();
-        uword c_stack_limit = OSThread::Current()->stack_base() -
-                              OSThread::GetSpecifiedStackSize();
+        volatile uword c_stack_pos = Isolate::GetCurrentStackPointer();
+        volatile uword c_stack_limit = OSThread::Current()->stack_base() -
+                                       OSThread::GetSpecifiedStackSize();
 #if !defined(USING_SIMULATOR)
         ASSERT(c_stack_limit == isolate->saved_stack_limit());
 #endif
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index aea2178..a9efd83 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1017,7 +1017,7 @@
       return value.raw();
     }
   }
-  return Object::null();
+  return Symbols::OptimizedOut().raw();
 }
 
 
@@ -1054,8 +1054,8 @@
                         Array::Handle(Array::MakeArray(param_values)));
   } else {
     const Object& receiver = Object::Handle(GetReceiver());
-    ASSERT(receiver.IsInstance());
-    if (!receiver.IsInstance()) {
+    ASSERT(receiver.IsInstance() || receiver.IsNull());
+    if (!(receiver.IsInstance() || receiver.IsNull())) {
       return Object::null();
     }
     const Instance& inst = Instance::Cast(receiver);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 309ad04..57b5d65 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3492,7 +3492,7 @@
         LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
             receiver,
             Array::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             node->token_pos());
         data_load->set_result_cid(kArrayCid);
         Value* data = Bind(data_load);
@@ -3520,7 +3520,7 @@
       case MethodRecognizer::kBigint_getDigits: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, Bigint::digits_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kTypedDataUint32ArrayCid));
       }
       case MethodRecognizer::kBigint_getUsed: {
@@ -3531,7 +3531,7 @@
       case MethodRecognizer::kLinkedHashMap_getIndex: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, LinkedHashMap::index_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kDynamicCid));
       }
       case MethodRecognizer::kLinkedHashMap_setIndex: {
@@ -3541,7 +3541,7 @@
       case MethodRecognizer::kLinkedHashMap_getData: {
         return ReturnDefinition(BuildNativeGetter(
             node, kind, LinkedHashMap::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             kArrayCid));
       }
       case MethodRecognizer::kLinkedHashMap_setData: {
@@ -4030,7 +4030,7 @@
           LocalVariable* temp_local = new(Z) LocalVariable(
               0,  // Token index.
               temp_name,
-              Type::ZoneHandle(Z, Type::DynamicType()));  // Type.
+              Object::dynamic_type());  // Type.
           temp_local->set_index(param_frame_index);
 
           // Mark this local as captured parameter so that the optimizer
@@ -4339,7 +4339,7 @@
     ASSERT(!for_finally.is_open());
 
     const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
-    types.SetAt(0, Type::Handle(Z, Type::DynamicType()));
+    types.SetAt(0, Object::dynamic_type());
     CatchBlockEntryInstr* finally_entry =
         new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                     original_handler_index,
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 6d47957..8c6fa8e 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -25,6 +25,7 @@
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
+#include "vm/timeline.h"
 
 namespace dart {
 
@@ -55,7 +56,7 @@
 DECLARE_FLAG(bool, disassemble_optimized);
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(bool, fields_may_be_reset);
-DECLARE_FLAG(bool, guess_other_cid);
+DECLARE_FLAG(bool, guess_icdata_cid);
 DECLARE_FLAG(bool, ic_range_profiling);
 DECLARE_FLAG(bool, intrinsify);
 DECLARE_FLAG(bool, load_deferred_eagerly);
@@ -97,7 +98,6 @@
     FLAG_load_deferred_eagerly = true;
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;     // Used in some tests.
-    FLAG_guess_other_cid = true;
     Compiler::set_always_optimize(true);
     // Triggers assert if we try to recompile (e.g., because of deferred
     // loading, deoptimization, ...). Noopt mode simulates behavior
@@ -250,6 +250,9 @@
 
 
 void FlowGraphCompiler::InitCompiler() {
+  TimelineDurationScope tds(thread(),
+                            isolate()->GetCompilerStream(),
+                            "InitCompiler");
   pc_descriptors_list_ = new(zone()) DescriptorList(64);
   exception_handlers_list_ = new(zone())ExceptionHandlerList();
   block_info_.Clear();
@@ -1769,16 +1772,17 @@
   } else {
     // Instead of deoptimizing, do a megamorphic call when no matching
     // cid found.
-    Label megamorphic, ok;
+    Label ok;
+    MegamorphicSlowPath* slow_path =
+        new MegamorphicSlowPath(ic_data, argument_count, deopt_id,
+                                token_pos, locs, CurrentTryIndex());
+    AddSlowPathCode(slow_path);
     EmitTestAndCall(ic_data, argument_count, argument_names,
-                    &megamorphic,  // No cid match.
-                    &ok,           // Found cid.
+                    slow_path->entry_label(),  // No cid match.
+                    &ok,                       // Found cid.
                     deopt_id, token_pos, locs);
-    // Fall through if last test is match.
-    assembler()->Jump(&ok);
-    assembler()->Bind(&megamorphic);
-    EmitMegamorphicInstanceCall(ic_data, argument_count, deopt_id,
-                                token_pos, locs);
+
+    assembler()->Bind(slow_path->exit_label());
     assembler()->Bind(&ok);
   }
 }
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 075e239..b6d4c4c 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -214,6 +214,37 @@
 };
 
 
+class MegamorphicSlowPath : public SlowPathCode {
+ public:
+  MegamorphicSlowPath(const ICData& ic_data,
+                      intptr_t argument_count,
+                      intptr_t deopt_id,
+                      intptr_t token_pos,
+                      LocationSummary* locs,
+                      intptr_t try_index)
+    : SlowPathCode(),
+      ic_data_(ic_data),
+      argument_count_(argument_count),
+      deopt_id_(deopt_id),
+      token_pos_(token_pos),
+      locs_(locs),
+      try_index_(try_index) {}
+  virtual ~MegamorphicSlowPath() {}
+
+ private:
+  virtual void EmitNativeCode(FlowGraphCompiler* comp);
+
+  const ICData& ic_data_;
+  intptr_t argument_count_;
+  intptr_t deopt_id_;
+  intptr_t token_pos_;
+  LocationSummary* locs_;
+  const intptr_t try_index_;  // For try/catch ranges.
+
+  DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath);
+};
+
+
 struct CidTarget {
   intptr_t cid;
   Function* target;
@@ -414,11 +445,14 @@
                                    intptr_t token_pos,
                                    LocationSummary* locs);
 
-  void EmitMegamorphicInstanceCall(const ICData& ic_data,
-                                   intptr_t argument_count,
-                                   intptr_t deopt_id,
-                                   intptr_t token_pos,
-                                   LocationSummary* locs);
+  // Pass a value for try-index where block is not available (e.g. slow path).
+  void EmitMegamorphicInstanceCall(
+      const ICData& ic_data,
+      intptr_t argument_count,
+      intptr_t deopt_id,
+      intptr_t token_pos,
+      LocationSummary* locs,
+      intptr_t try_index = CatchClauseNode::kInvalidTryIndex);
 
   void EmitSwitchableInstanceCall(const ICData& ic_data,
                                   intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index a11916d..1d18f03 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -31,6 +31,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -191,7 +203,7 @@
   __ Push(CODE_REG);
   __ mov(IP, Operand(LR));
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -460,7 +472,7 @@
         FieldAddress(R1, TypeArguments::type_at_offset(type_param.index())));
     // R2: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(R2, Object::dynamic_type());
     __ b(is_instance_lbl, EQ);
     __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ b(is_instance_lbl, EQ);
@@ -1258,7 +1270,8 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
@@ -1276,12 +1289,26 @@
   }
   __ blx(R1);
 
-  AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (is_optimizing()) {
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+                         Thread::kNoDeoptId, token_pos);
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt,
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 53429c8..44f1463 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -28,6 +28,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -172,8 +184,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -183,7 +195,7 @@
   ASSERT(deopt_env() != NULL);
   __ Push(CODE_REG);
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -452,7 +464,7 @@
         R2, R1, TypeArguments::type_at_offset(type_param.index()));
     // R2: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(R2, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(R2, Object::dynamic_type());
     __ b(is_instance_lbl, EQ);
     __ CompareObject(R2, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ b(is_instance_lbl, EQ);
@@ -1248,7 +1260,8 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
@@ -1266,13 +1279,26 @@
   }
   __ blr(R1);
 
-  AddCurrentDescriptor(RawPcDescriptors::kOther,
-      Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (is_optimizing()) {
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index c6094fe..af8e5b7 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -33,6 +33,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ jmp(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -186,7 +198,7 @@
   ASSERT(deopt_env() != NULL);
   __ pushl(CODE_REG);
   __ Call(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
   __ int3();
 #undef __
 }
@@ -468,7 +480,7 @@
         FieldAddress(EDX, TypeArguments::type_at_offset(type_param.index())));
     // EDI: concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(EDI, Object::dynamic_type());
     __ j(EQUAL,  is_instance_lbl);
     __ CompareObject(EDI, Type::ZoneHandle(zone(), Type::ObjectType()));
     __ j(EQUAL,  is_instance_lbl);
@@ -1278,7 +1290,8 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
@@ -1300,6 +1313,8 @@
       Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
+  // Precompilation not implemented on ia32 platform.
+  ASSERT(!Compiler::always_optimize());
   if (is_optimizing()) {
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index ded5e74..b569456 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -26,6 +26,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ b(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -172,8 +184,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -183,7 +195,7 @@
   ASSERT(deopt_env() != NULL);
   __ Push(CODE_REG);
   __ BranchLink(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
 #undef __
 }
 
@@ -449,7 +461,7 @@
     // R2: concrete type of type.
     // Check if type argument is dynamic.
     __ BranchEqual(T2,
-        Type::ZoneHandle(zone(), Type::DynamicType()), is_instance_lbl);
+        Object::dynamic_type(), is_instance_lbl);
     __ BranchEqual(T2,
         Type::ZoneHandle(zone(), Type::ObjectType()), is_instance_lbl);
 
@@ -1269,7 +1281,8 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
@@ -1287,13 +1300,26 @@
   }
   __ jalr(T1);
 
-  AddCurrentDescriptor(RawPcDescriptors::kOther,
-      Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (is_optimizing()) {
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 42b3677..5f38396 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -29,6 +29,18 @@
 DECLARE_FLAG(bool, use_megamorphic_stub);
 
 
+void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
+  __ Bind(entry_label());
+  __ Comment("MegamorphicSlowPath");
+  compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
+                                        token_pos_, locs_, try_index_);
+  __ jmp(exit_label());
+#undef __
+}
+
+
 FlowGraphCompiler::~FlowGraphCompiler() {
   // BlockInfos are zone-allocated, so their destructors are not called.
   // Verify the labels explicitly here.
@@ -175,8 +187,8 @@
                                              intptr_t stub_ix) {
   // Calls do not need stubs, they share a deoptimization trampoline.
   ASSERT(reason() != ICData::kDeoptAtCall);
-  Assembler* assem = compiler->assembler();
-#define __ assem->
+  Assembler* assembler = compiler->assembler();
+#define __ assembler->
   __ Comment("%s", Name());
   __ Bind(entry_label());
   if (FLAG_trap_on_deoptimization) {
@@ -187,7 +199,7 @@
 
   __ pushq(CODE_REG);
   __ Call(*StubCode::Deoptimize_entry());
-  set_pc_offset(assem->CodeSize());
+  set_pc_offset(assembler->CodeSize());
   __ int3();
 #undef __
 }
@@ -461,7 +473,7 @@
         FieldAddress(RDX, TypeArguments::type_at_offset(type_param.index())));
     // RDI: Concrete type of type.
     // Check if type argument is dynamic.
-    __ CompareObject(RDI, Type::ZoneHandle(zone(), Type::DynamicType()));
+    __ CompareObject(RDI, Object::dynamic_type());
     __ j(EQUAL,  is_instance_lbl);
     const Type& object_type = Type::ZoneHandle(zone(), Type::ObjectType());
     __ CompareObject(RDI, object_type);
@@ -1279,7 +1291,8 @@
     intptr_t argument_count,
     intptr_t deopt_id,
     intptr_t token_pos,
-    LocationSummary* locs) {
+    LocationSummary* locs,
+    intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
   const Array& arguments_descriptor =
       Array::ZoneHandle(zone(), ic_data.arguments_descriptor());
@@ -1297,13 +1310,26 @@
   }
   __ call(RCX);
 
-  AddCurrentDescriptor(RawPcDescriptors::kOther,
-      Thread::kNoDeoptId, token_pos);
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (is_optimizing()) {
+  if (Compiler::always_optimize()) {
+    // Megamorphic calls may occur in slow path stubs.
+    // If valid use try_index argument.
+    if (try_index == CatchClauseNode::kInvalidTryIndex) {
+      try_index = CurrentTryIndex();
+    }
+    pc_descriptors_list()->AddDescriptor(RawPcDescriptors::kOther,
+                                         assembler()->CodeSize(),
+                                         Thread::kNoDeoptId,
+                                         token_pos,
+                                         try_index);
+  } else if (is_optimizing()) {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
+    AddCurrentDescriptor(RawPcDescriptors::kOther,
+        Thread::kNoDeoptId, token_pos);
     // Add deoptimization continuation point after the call and before the
     // arguments are removed.
     AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after, token_pos);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 15642fc..8a20b88 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -28,7 +28,7 @@
 
 DEFINE_FLAG(int, getter_setter_ratio, 13,
     "Ratio of getter/setter usage used for double field unboxing heuristics");
-DEFINE_FLAG(bool, guess_other_cid, true,
+DEFINE_FLAG(bool, guess_icdata_cid, true,
     "Artificially create type feedback for arithmetic etc. operations"
     " by guessing the other unknown argument cid");
 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
@@ -196,7 +196,7 @@
       Token::IsBinaryOperator(op_kind)) {
     // Guess cid: if one of the inputs is a number assume that the other
     // is a number of same type.
-    if (FLAG_guess_other_cid) {
+    if (FLAG_guess_icdata_cid) {
       const intptr_t cid_0 = class_ids[0];
       const intptr_t cid_1 = class_ids[1];
       if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
@@ -254,9 +254,31 @@
     return true;
   }
 
+  if (Compiler::always_optimize() &&
+      (isolate()->object_store()->unique_dynamic_targets() != Array::null())) {
+    // Check if the target is unique.
+    Function& target_function = Function::Handle(Z);
+    Precompiler::GetUniqueDynamicTarget(
+        isolate(), call->function_name(), &target_function);
+    // Calls with named arguments must be resolved/checked at runtime.
+    String& error_message = String::Handle(Z);
+    if (!target_function.IsNull() &&
+        !target_function.HasOptionalNamedParameters() &&
+        target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
+                                               &error_message)) {
+      const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
+      const ICData& ic_data = ICData::ZoneHandle(Z,
+          ICData::NewFrom(*call->ic_data(), 1));
+      ic_data.AddReceiverCheck(cid, target_function);
+      call->set_ic_data(&ic_data);
+      return true;
+    }
+  }
+
   // Check if getter or setter in function's class and class is currently leaf.
-  if ((call->token_kind() == Token::kGET) ||
-      (call->token_kind() == Token::kSET)) {
+  if (FLAG_guess_icdata_cid &&
+      ((call->token_kind() == Token::kGET) ||
+          (call->token_kind() == Token::kSET))) {
     const Class& owner_class = Class::Handle(Z, function().Owner());
     if (!owner_class.is_abstract() &&
         !CHA::HasSubclasses(owner_class) &&
@@ -279,27 +301,6 @@
     }
   }
 
-  if (FLAG_precompilation &&
-      (isolate()->object_store()->unique_dynamic_targets() != Array::null())) {
-    // Check if the target is unique.
-    Function& target_function = Function::Handle(Z);
-    Precompiler::GetUniqueDynamicTarget(
-        isolate(), call->function_name(), &target_function);
-    // Calls with named arguments must be resolved/checked at runtime.
-    String& error_message = String::Handle(Z);
-    if (!target_function.IsNull() &&
-        !target_function.HasOptionalNamedParameters() &&
-        target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
-                                               &error_message)) {
-      const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
-      const ICData& ic_data = ICData::ZoneHandle(Z,
-          ICData::NewFrom(*call->ic_data(), 1));
-      ic_data.AddReceiverCheck(cid, target_function);
-      call->set_ic_data(&ic_data);
-      return true;
-    }
-  }
-
   return false;
 }
 
@@ -1726,7 +1727,7 @@
         new(Z) LoadFieldInstr(
             new(Z) Value(*array),
             GrowableObjectArray::data_offset(),
-            Type::ZoneHandle(Z, Type::DynamicType()),
+            Object::dynamic_type(),
             call->token_pos());
     elements->set_result_cid(kArrayCid);
     *cursor = flow_graph()->AppendTo(*cursor,
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 60c20aef..3c3725c 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -21,6 +21,12 @@
 
 
 void FlowGraphTypePropagator::Propagate(FlowGraph* flow_graph) {
+  Thread* thread = flow_graph->thread();
+  Isolate* const isolate = flow_graph->isolate();
+  TimelineStream* compiler_timeline = isolate->GetCompilerStream();
+  TimelineDurationScope tds2(thread,
+                             compiler_timeline,
+                             "FlowGraphTypePropagator");
   FlowGraphTypePropagator propagator(flow_graph);
   propagator.Propagate();
 }
@@ -413,7 +419,7 @@
   // Nothing to do.
   } else {
   // Can't unify.
-  type_ = &Type::ZoneHandle(Type::DynamicType());
+  type_ = &Object::dynamic_type();
   }
 }
 
@@ -441,7 +447,7 @@
 
 
 CompileType CompileType::Dynamic() {
-  return Create(kDynamicCid, Type::ZoneHandle(Type::DynamicType()));
+  return Create(kDynamicCid, Object::dynamic_type());
 }
 
 
@@ -534,14 +540,14 @@
   if (type_ == NULL) {
     // Type propagation has not run. Return dynamic-type.
     if (cid_ == kIllegalCid) {
-      type_ = &Type::ZoneHandle(Type::DynamicType());
+      type_ = &Object::dynamic_type();
       return type_;
     }
 
     // VM-internal objects don't have a compile-type. Return dynamic-type
     // in this case.
     if (cid_ < kInstanceCid) {
-      type_ = &Type::ZoneHandle(Type::DynamicType());
+      type_ = &Object::dynamic_type();
       return type_;
     }
 
@@ -549,7 +555,7 @@
         Class::Handle(Isolate::Current()->class_table()->At(cid_));
 
     if (type_class.NumTypeArguments() > 0) {
-      type_ = &Type::ZoneHandle(Type::DynamicType());
+      type_ = &Object::dynamic_type();
       return type_;
     }
 
@@ -859,28 +865,28 @@
 CompileType CurrentContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType CloneContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType AllocateContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
 CompileType AllocateUninitializedContextInstr::ComputeType() const {
   return CompileType(CompileType::kNonNullable,
                      kContextCid,
-                     &AbstractType::ZoneHandle(Type::DynamicType()));
+                     &Object::dynamic_type());
 }
 
 
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 45e84d2..6b2a946 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -18,6 +18,7 @@
 #include "vm/store_buffer.h"
 #include "vm/thread_barrier.h"
 #include "vm/thread_pool.h"
+#include "vm/thread_registry.h"
 #include "vm/visitor.h"
 #include "vm/object_id_ring.h"
 
@@ -484,7 +485,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  Thread::PrepareForGC();
+  isolate->thread_registry()->PrepareForGC();
   // The store buffers will be rebuilt as part of marking, reset them now.
   isolate->store_buffer()->Reset();
 }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 52d5ce9..852efd4 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -630,7 +630,7 @@
 }
 
 
-BlockEntryInstr* Instruction::GetBlock() const {
+BlockEntryInstr* Instruction::GetBlock() {
   // TODO(fschneider): Implement a faster way to get the block of an
   // instruction.
   ASSERT(previous() != NULL);
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 2b9b762..897ee3f 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -810,7 +810,7 @@
   }
 
   // Get the block entry for this instruction.
-  virtual BlockEntryInstr* GetBlock() const;
+  virtual BlockEntryInstr* GetBlock();
 
   // Place identifiers used by the load optimization pass.
   intptr_t place_id() const { return place_id_; }
@@ -1181,8 +1181,8 @@
     loop_info_ = loop_info;
   }
 
-  virtual BlockEntryInstr* GetBlock() const {
-    return const_cast<BlockEntryInstr*>(this);
+  virtual BlockEntryInstr* GetBlock() {
+    return this;
   }
 
   // Helper to mutate the graph during inlining. This block should be
@@ -1886,7 +1886,7 @@
   }
 
   // Get the block entry for that instruction.
-  virtual BlockEntryInstr* GetBlock() const { return block(); }
+  virtual BlockEntryInstr* GetBlock() { return block(); }
   JoinEntryInstr* block() const { return block_; }
 
   virtual CompileType ComputeType() const;
@@ -1981,7 +1981,7 @@
   Register base_reg() const { return base_reg_; }
 
   // Get the block entry for that instruction.
-  virtual BlockEntryInstr* GetBlock() const { return block_; }
+  virtual BlockEntryInstr* GetBlock() { return block_; }
 
   intptr_t InputCount() const { return 0; }
   Value* InputAt(intptr_t i) const {
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 577775e..61620c8 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -77,7 +77,7 @@
     // Check if it's dynamic.
     // Get type at index 0.
     __ movl(EAX, FieldAddress(EBX, TypeArguments::type_at_offset(0)));
-    __ CompareObject(EAX, Type::ZoneHandle(Type::DynamicType()));
+    __ CompareObject(EAX, Object::dynamic_type());
     __ j(EQUAL,  &checked_ok, Assembler::kNearJump);
     // Check for int and num.
     __ testl(EDI, Immediate(kSmiTagMask));  // Value is Smi?
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index f8133ef..0199af5 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -134,6 +134,19 @@
   *obj_len = writer.BytesWritten();
 }
 
+// TODO(zra): Allocation of Message objects should be centralized.
+static Message* SerializeMessage(
+    Dart_Port dest_port, const Instance& obj) {
+  if (ApiObjectConverter::CanConvert(obj.raw())) {
+    return new Message(dest_port, obj.raw(), Message::kNormalPriority);
+  } else {
+    uint8_t* obj_data;
+    intptr_t obj_len;
+    SerializeObject(obj, &obj_data, &obj_len, false);
+    return new Message(dest_port, obj_data, obj_len, Message::kNormalPriority);
+  }
+}
+
 
 void Isolate::RegisterClass(const Class& cls) {
   class_table()->Register(cls);
@@ -260,12 +273,8 @@
       const Instance& response =
           obj4.IsNull() ? Instance::null_instance() : Instance::Cast(obj4);
       if (priority == Isolate::kImmediateAction) {
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(response, &data, &len, false);
-        PortMap::PostMessage(new Message(send_port.Id(),
-                                         data, len,
-                                         Message::kNormalPriority));
+        PortMap::PostMessage(SerializeMessage(
+            send_port.Id(), response));
       } else {
         ASSERT((priority == Isolate::kBeforeNextEventAction) ||
                (priority == Isolate::kAsEventAction));
@@ -275,13 +284,8 @@
             Smi::New(Message::kDelayedIsolateLibOOBMsg)));
         message.SetAt(3, Smi::Handle(zone,
             Smi::New(Isolate::kImmediateAction)));
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(message, &data, &len, false);
-        this->PostMessage(
-            new Message(Message::kIllegalPort,
-                        data, len,
-                        Message::kNormalPriority),
+        this->PostMessage(SerializeMessage(
+            Message::kIllegalPort, message),
             priority == Isolate::kBeforeNextEventAction /* at_head */);
       }
       break;
@@ -334,13 +338,8 @@
             Smi::New(Message::kDelayedIsolateLibOOBMsg)));
         message.SetAt(3, Smi::Handle(zone,
             Smi::New(Isolate::kImmediateAction)));
-        uint8_t* data = NULL;
-        intptr_t len = 0;
-        SerializeObject(message, &data, &len, false);
-        this->PostMessage(
-            new Message(Message::kIllegalPort,
-                        data, len,
-                        Message::kNormalPriority),
+        this->PostMessage(SerializeMessage(
+            Message::kIllegalPort, message),
             priority == Isolate::kBeforeNextEventAction /* at_head */);
       }
       break;
@@ -468,8 +467,15 @@
   }
 
   // Parse the message.
-  MessageSnapshotReader reader(message->data(), message->len(), thread);
-  const Object& msg_obj = Object::Handle(zone, reader.ReadObject());
+  Object& msg_obj = Object::Handle(zone);
+  if (message->IsRaw()) {
+    msg_obj = message->raw_obj();
+    // We should only be sending RawObjects that can be converted to CObjects.
+    ASSERT(ApiObjectConverter::CanConvert(msg_obj.raw()));
+  } else {
+    MessageSnapshotReader reader(message->data(), message->len(), thread);
+    msg_obj = reader.ReadObject();
+  }
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
     delete message;
@@ -483,7 +489,6 @@
     // always true for now, then this should never occur.
     UNREACHABLE();
   }
-
   Instance& msg = Instance::Handle(zone);
   msg ^= msg_obj.raw();  // Can't use Instance::Cast because may be null.
 
@@ -1203,12 +1208,8 @@
     listener ^= listeners.At(i);
     if (!listener.IsNull()) {
       Dart_Port port_id = listener.Id();
-      uint8_t* data = NULL;
-      intptr_t len = 0;
       response ^= listeners.At(i + 1);
-      SerializeObject(response, &data, &len, false);
-      Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
-      PortMap::PostMessage(msg);
+      PortMap::PostMessage(SerializeMessage(port_id, response));
     }
   }
 }
@@ -1276,11 +1277,7 @@
     listener ^= listeners.At(i);
     if (!listener.IsNull()) {
       Dart_Port port_id = listener.Id();
-      uint8_t* data = NULL;
-      intptr_t len = 0;
-      SerializeObject(arr, &data, &len, false);
-      Message* msg = new Message(port_id, data, len, Message::kNormalPriority);
-      PortMap::PostMessage(msg);
+      PortMap::PostMessage(SerializeMessage(port_id, arr));
     }
   }
   return listeners.Length() > 0;
@@ -1862,6 +1859,19 @@
     JSONObject jssettings(&jsobj, "_debuggerSettings");
     debugger()->PrintSettingsToJSONObject(&jssettings);
   }
+
+  {
+    GrowableObjectArray& handlers =
+        GrowableObjectArray::Handle(registered_service_extension_handlers());
+    if (!handlers.IsNull()) {
+      JSONArray extensions(&jsobj, "extensionRPCs");
+      String& handler_name = String::Handle();
+      for (intptr_t i = 0; i < handlers.Length(); i += kRegisteredEntrySize) {
+        handler_name ^= handlers.At(i + kRegisteredNameIndex);
+        extensions.AddValue(handler_name.ToCString());
+      }
+    }
+  }
 }
 
 
@@ -2045,6 +2055,12 @@
   handlers.Add(name, Heap::kOld);
   ASSERT(kRegisteredHandlerIndex == 1);
   handlers.Add(closure, Heap::kOld);
+  {
+    // Fire off an event.
+    ServiceEvent event(this, ServiceEvent::kServiceExtensionAdded);
+    event.set_extension_rpc(&name);
+    Service::HandleEvent(&event);
+  }
 }
 
 
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 9f94205..4851875 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -161,16 +161,8 @@
 
 
 void JSONStream::PostNullReply(Dart_Port port) {
-  const Object& reply = Object::Handle(Object::null());
-  ASSERT(reply.IsNull());
-
-  uint8_t* data = NULL;
-  MessageWriter writer(&data, &allocator, false);
-  writer.WriteMessage(reply);
-  PortMap::PostMessage(new Message(port,
-                                   data,
-                                   writer.BytesWritten(),
-                                   Message::kNormalPriority));
+  PortMap::PostMessage(new Message(
+      port, Object::null(), Message::kNormalPriority));
 }
 
 
@@ -270,6 +262,13 @@
 }
 
 
+void JSONStream::AppendSerializedObject(const char* property_name,
+                                        const char* serialized_object) {
+  PrintCommaIfNeeded();
+  PrintPropertyName(property_name);
+  buffer_.AddString(serialized_object);
+}
+
 void JSONStream::Clear() {
   buffer_.Clear();
   open_objects_ = 0;
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 92cbc4e..239c4e7 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -126,6 +126,10 @@
   // Append |serialized_object| to the stream.
   void AppendSerializedObject(const char* serialized_object);
 
+  // Append |serialized_object| to the stream with |property_name|.
+  void AppendSerializedObject(const char* property_name,
+                              const char* serialized_object);
+
  private:
   void Clear();
   void PostNullReply(Dart_Port port);
diff --git a/runtime/vm/message.h b/runtime/vm/message.h
index 42a1eb1..aaa14c7 100644
--- a/runtime/vm/message.h
+++ b/runtime/vm/message.h
@@ -8,6 +8,7 @@
 #include "platform/assert.h"
 #include "vm/allocation.h"
 #include "vm/globals.h"
+#include "vm/raw_object.h"
 
 // Duplicated from dart_api.h to avoid including the whole header.
 typedef int64_t Dart_Port;
@@ -57,17 +58,46 @@
     ASSERT((priority == kNormalPriority) ||
            (delivery_failure_port == kIllegalPort));
   }
+
+  // Message objects can also carry RawObject pointers for Smis and objects in
+  // the VM heap. This is indicated by setting the len_ field to 0.
+  Message(Dart_Port dest_port,
+          RawObject* raw_obj,
+          Priority priority,
+          Dart_Port delivery_failure_port = kIllegalPort)
+      : next_(NULL),
+        dest_port_(dest_port),
+        delivery_failure_port_(delivery_failure_port),
+        data_(reinterpret_cast<uint8_t*>(raw_obj)),
+        len_(0),
+        priority_(priority) {
+    ASSERT(!raw_obj->IsHeapObject() || raw_obj->IsVMHeapObject());
+    ASSERT((priority == kNormalPriority) ||
+           (delivery_failure_port == kIllegalPort));
+  }
   ~Message() {
     ASSERT(delivery_failure_port_ == kIllegalPort);
-    free(data_);
+    if (len_ > 0) {
+      free(data_);
+    }
   }
 
   Dart_Port dest_port() const { return dest_port_; }
-  uint8_t* data() const { return data_; }
-  intptr_t len() const { return len_; }
+  uint8_t* data() const {
+    ASSERT(len_ > 0);
+    return data_;
+  }
+  intptr_t len() const {
+    return len_;
+  }
+  RawObject* raw_obj() const {
+    ASSERT(len_ == 0);
+    return reinterpret_cast<RawObject*>(data_);
+  }
   Priority priority() const { return priority_; }
 
   bool IsOOB() const { return priority_ == Message::kOOBPriority; }
+  bool IsRaw() const { return len_ == 0; }
 
   bool RedirectToDeliveryFailurePort();
 
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index c707c9e..8a546e4 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -43,7 +43,7 @@
 };
 
 
-DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
+static bool PostCObjectHelper(Dart_Port port_id, Dart_CObject* message) {
   uint8_t* buffer = NULL;
   ApiMessageWriter writer(&buffer, allocator);
   bool success = writer.WriteCMessage(message);
@@ -56,6 +56,23 @@
 }
 
 
+DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject* message) {
+  return PostCObjectHelper(port_id, message);
+}
+
+
+DART_EXPORT bool Dart_PostInteger(Dart_Port port_id, int64_t message) {
+  if (Smi::IsValid(message)) {
+    return PortMap::PostMessage(new Message(
+        port_id, Smi::New(message), Message::kNormalPriority));
+  }
+  Dart_CObject cobj;
+  cobj.type = Dart_CObject_kInt64;
+  cobj.value.as_int64 = message;
+  return PostCObjectHelper(port_id, &cobj);
+}
+
+
 DART_EXPORT Dart_Port Dart_NewNativePort(const char* name,
                                          Dart_NativeMessageHandler handler,
                                          bool handle_concurrently) {
diff --git a/runtime/vm/native_message_handler.cc b/runtime/vm/native_message_handler.cc
index 8f8d7a6..7779e95 100644
--- a/runtime/vm/native_message_handler.cc
+++ b/runtime/vm/native_message_handler.cc
@@ -42,8 +42,9 @@
   // All allocation of objects for decoding the message is done in the
   // zone associated with this scope.
   ApiNativeScope scope;
-  ApiMessageReader reader(message->data(), message->len());
-  Dart_CObject* object = reader.ReadMessage();
+  Dart_CObject* object;
+  ApiMessageReader reader(message);
+  object = reader.ReadMessage();
   (*func())(message->dest_port(), object);
   delete message;
   return kOK;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2799c1b..f44c365 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -15684,13 +15684,9 @@
     }
     const AbstractType& bound = AbstractType::Handle(type_param.bound());
     // We may be checking bounds at finalization time and can encounter
-    // a still unfinalized bound.
-    if (!bound.IsFinalized() && !bound.IsBeingFinalized()) {
-      ClassFinalizer::FinalizeType(
-          Class::Handle(type_param.parameterized_class()),
-          bound,
-          ClassFinalizer::kCanonicalize);
-      type_param.set_bound(bound);
+    // a still unfinalized bound. Finalizing the bound here may lead to cycles.
+    if (!bound.IsFinalized()) {
+      return false;    // TODO(regis): Return "maybe after instantiation".
     }
     if (bound.IsMoreSpecificThan(other, bound_error)) {
       return true;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 89cf988..217354a 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -138,7 +138,7 @@
     LocalVariable* temp =
         new (Z) LocalVariable(function_.token_pos(),
                               Symbols::ExprTemp(),
-                              Type::ZoneHandle(Type::DynamicType()));
+                              Object::dynamic_type());
     ASSERT(temp != NULL);
     set_expression_temp_var(temp);
   }
@@ -152,7 +152,7 @@
     LocalVariable* temp = new(Z) LocalVariable(
         function_.token_pos(),
         String::ZoneHandle(Z, Symbols::New(":finally_ret_val")),
-        Type::ZoneHandle(Z, Type::DynamicType()));
+        Object::dynamic_type());
     ASSERT(temp != NULL);
     temp->set_is_final();
     if (is_async) {
@@ -458,10 +458,7 @@
                             "CompileTopLevel");
   if (tds.enabled()) {
     tds.SetNumArguments(1);
-    tds.CopyArgument(
-        0,
-        "script",
-        const_cast<char*>(String::Handle(script.url()).ToCString()));
+    tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString());
   }
 
   Parser parser(script, library, 0);
@@ -610,6 +607,7 @@
   MemberDesc() {
     Clear();
   }
+
   void Clear() {
     has_abstract = false;
     has_external = false;
@@ -631,6 +629,7 @@
     kind = RawFunction::kRegularFunction;
     field_ = NULL;
   }
+
   bool IsConstructor() const {
     return (kind == RawFunction::kConstructor) && !has_static;
   }
@@ -817,6 +816,16 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   const int64_t num_tokes_before = STAT_VALUE(thread, num_tokens_consumed);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "ParseClass");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(
+        0,
+        "class",
+        const_cast<char*>(String::Handle(cls.Name()).ToCString()));
+  }
   if (!cls.is_synthesized_class()) {
     ASSERT(thread->long_jump_base()->IsSafeToJump());
     CSTAT_TIMER_SCOPE(thread, parser_timer);
@@ -926,12 +935,21 @@
   INC_STAT(thread, num_functions_parsed, 1);
   VMTagScope tagScope(thread, VMTag::kCompileParseFunctionTagId,
                       FLAG_profile_vm);
-
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "ParseFunction");
   ASSERT(thread->long_jump_base()->IsSafeToJump());
   ASSERT(parsed_function != NULL);
   const Function& func = parsed_function->function();
   const Script& script = Script::Handle(zone, func.script());
   Parser parser(script, parsed_function, func.token_pos());
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(
+        0,
+        "function",
+        const_cast<char*>(String::Handle(func.name()).ToCString()));
+  }
   SequenceNode* node_sequence = NULL;
   switch (func.kind()) {
     case RawFunction::kClosureFunction:
@@ -1047,6 +1065,7 @@
         new ParsedFunction(thread, fake_function);
     Parser parser(script, parsed_function, token_pos);
     parser.set_current_class(owner_class);
+    parser.OpenFunctionBlock(fake_function);
 
     RawObject* metadata = parser.EvaluateMetadata();
     return metadata;
@@ -1358,7 +1377,7 @@
   // argument.
   params.AddFinalParameter(token_pos,
                            &Symbols::ClosureParameter(),
-                           &Type::ZoneHandle(Z, Type::DynamicType()));
+                           &Object::dynamic_type());
   bool params_ok = ParseFormalParameters(constructor, &params);
   USE(params_ok);
   ASSERT(params_ok);
@@ -1408,7 +1427,7 @@
   params.AddFinalParameter(
       token_pos,
       &Symbols::ClosureParameter(),
-      &Type::ZoneHandle(Type::DynamicType()));
+      &Object::dynamic_type());
 
   const Function& parent = Function::ZoneHandle(func.parent_function());
   if (parent.IsImplicitSetterFunction()) {
@@ -1506,7 +1525,7 @@
     char name[64];
     OS::SNPrint(name, 64, ":p%" Pd, i);
     p.name = &String::ZoneHandle(Z, Symbols::New(name));
-    p.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    p.type = &Object::dynamic_type();
     params.parameters->Add(p);
     params.num_fixed_parameters++;
   }
@@ -1517,7 +1536,7 @@
     ParamDesc p;
     intptr_t index = i - desc.PositionalCount();
     p.name = &String::ZoneHandle(Z, desc.NameAt(index));
-    p.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    p.type = &Object::dynamic_type();
     p.default_value = &Object::null_instance();
     params.parameters->Add(p);
     params.num_optional_parameters++;
@@ -1768,7 +1787,7 @@
     // The parameter type is the 'dynamic' type.
     // If this is an initializing formal, its type will be set to the type of
     // the respective field when the constructor is fully parsed.
-    parameter.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    parameter.type = &Object::dynamic_type();
   }
   if (CurrentToken() == Token::kTHIS) {
     ConsumeToken();
@@ -1781,7 +1800,7 @@
     // This must later be changed to a closure type if we recognize
     // a closure/function type parameter. We check this at the end
     // of ParseFormalParameter.
-    parameter.type = &Type::ZoneHandle(Z, Type::VoidType());
+    parameter.type = &Object::void_type();
   }
   if (parameter.type == NULL) {
     // At this point, we must see an identifier for the type or the
@@ -1808,7 +1827,7 @@
     } else {
       // If this is an initializing formal, its type will be set to the type of
       // the respective field when the constructor is fully parsed.
-      parameter.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      parameter.type = &Object::dynamic_type();
     }
   }
   if (!this_seen && (CurrentToken() == Token::kTHIS)) {
@@ -1857,7 +1876,7 @@
       func_params.AddFinalParameter(
           TokenPos(),
           &Symbols::ClosureParameter(),
-          &Type::ZoneHandle(Z, Type::DynamicType()));
+          &Object::dynamic_type());
 
       const bool no_explicit_default_values = false;
       ParseFormalParameterList(no_explicit_default_values, false, &func_params);
@@ -2563,8 +2582,7 @@
 
   set_current_class(Class::Handle(Z, field.origin()));
   set_library(Library::Handle(Z, current_class().library()));
-  SetScript(Script::Handle(Z, current_class().script()),
-            field.token_pos());
+  SetScript(Script::Handle(Z, current_class().script()), field.token_pos());
 
   ASSERT(IsIdentifier());
   ConsumeToken();
@@ -2930,7 +2948,7 @@
       LocalVariable* param = new LocalVariable(
           Scanner::kNoSourcePos,
           String::ZoneHandle(Z, func.ParameterNameAt(i)),
-          Type::ZoneHandle(Z, Type::DynamicType()));
+          Object::dynamic_type());
       current_block_->scope->InsertParameterAt(i, param);
       forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param));
     }
@@ -3315,7 +3333,7 @@
     params.AddFinalParameter(
         TokenPos(),
         &Symbols::ClosureParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
+        &Object::dynamic_type());
   } else if (!func.is_static()) {
     // Static functions do not have a receiver.
     ASSERT(current_class().raw() == func.Owner());
@@ -3326,7 +3344,7 @@
     params.AddFinalParameter(
         TokenPos(),
         &Symbols::TypeArgumentsParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
+        &Object::dynamic_type());
   }
   // Expect the parameter list unless this is a getter function, or the
   // body closure of an async or generator getter function.
@@ -3689,7 +3707,7 @@
     method->params.AddFinalParameter(
         formal_param_pos,
         &Symbols::TypeArgumentsParameter(),
-        &Type::ZoneHandle(Z, Type::DynamicType()));
+        &Object::dynamic_type());
   }
   // Constructors have an implicit parameter for the construction phase.
   if (method->IsConstructor()) {
@@ -4156,7 +4174,7 @@
         params.AddFinalParameter(TokenPos(),
                                  &Symbols::Value(),
                                  field->type);
-        setter.set_result_type(Type::Handle(Z, Type::VoidType()));
+        setter.set_result_type(Object::void_type());
         setter.set_is_debuggable(false);
         if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) {
           setter.set_is_reflectable(false);
@@ -4260,7 +4278,7 @@
     ConsumeToken();
     member.has_var = true;
     // The member type is the 'dynamic' type.
-    member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+    member.type = &Object::dynamic_type();
   } else if (CurrentToken() == Token::kFACTORY) {
     ConsumeToken();
     if (member.has_static) {
@@ -4277,7 +4295,7 @@
     }
     ConsumeToken();
     ASSERT(member.type == NULL);
-    member.type = &Type::ZoneHandle(Z, Type::VoidType());
+    member.type = &Object::void_type();
   } else if (CurrentToken() == Token::kIDENT) {
     // This is either a type name or the name of a method/constructor/field.
     if ((member.type == NULL) && !member.has_factory) {
@@ -4372,7 +4390,7 @@
     // The grammar allows a return type, so member.type is not always NULL here.
     // If no return type is specified, the return type of the setter is dynamic.
     if (member.type == NULL) {
-      member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      member.type = &Object::dynamic_type();
     }
   } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var &&
              (LookaheadToken(1) != Token::kLPAREN) &&
@@ -4405,7 +4423,7 @@
   if (CurrentToken() == Token::kLPAREN || member.IsGetter()) {
     // Constructor or method.
     if (member.type == NULL) {
-      member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+      member.type = &Object::dynamic_type();
     }
     ASSERT(member.IsFactory() == member.has_factory);
     ParseMethodOrConstructor(members, &member);
@@ -4419,7 +4437,7 @@
     }
     if (member.type == NULL) {
       if (member.has_final) {
-        member.type = &Type::ZoneHandle(Z, Type::DynamicType());
+        member.type = &Object::dynamic_type();
       } else {
         ReportError("missing 'var', 'final', 'const' or type"
                     " in field declaration");
@@ -5146,7 +5164,7 @@
   func_params.AddFinalParameter(
       TokenPos(),
       &Symbols::ClosureParameter(),
-      &Type::ZoneHandle(Z, Type::DynamicType()));
+      &Object::dynamic_type());
 
   const bool no_explicit_default_values = false;
   ParseFormalParameterList(no_explicit_default_values, false, &func_params);
@@ -6640,7 +6658,7 @@
                                         innermost_function(),
                                         func_pos);
     body.set_is_generated_body(true);
-    body.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    body.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
 
@@ -6778,7 +6796,7 @@
         innermost_function(),
         async_func_pos);
     closure.set_is_generated_body(true);
-    closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    closure.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
   // Create the parameter list for the async body closure.
@@ -6912,7 +6930,7 @@
         innermost_function(),
         async_func_pos);
     closure.set_is_generated_body(true);
-    closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+    closure.set_result_type(Object::dynamic_type());
     is_new_closure = true;
   }
 
@@ -8694,7 +8712,7 @@
                               TypeArguments::ZoneHandle(Z),
                               iterator_ctor,
                               ctor_args);
-  const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
+  const AbstractType& iterator_type = Object::dynamic_type();
   LocalVariable* iterator_var = new(Z) LocalVariable(
       stream_expr_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
@@ -8959,7 +8977,7 @@
   // would refer to the compiler generated iterator and could confuse the user.
   // It is better to leave the iterator untyped and postpone the type error
   // until the loop variable is assigned to.
-  const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
+  const AbstractType& iterator_type = Object::dynamic_type();
   LocalVariable* iterator_var = new(Z) LocalVariable(
       collection_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
@@ -9388,7 +9406,7 @@
       exception_param.type = &AbstractType::ZoneHandle(Z,
           ParseType(ClassFinalizer::kCanonicalize));
     } else {
-      exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType());
+      exception_param.type = &Object::dynamic_type();
     }
     if (CurrentToken() == Token::kCATCH) {
       ConsumeToken();  // Consume the 'catch'.
@@ -9397,8 +9415,7 @@
       exception_param.name = ExpectIdentifier("identifier expected");
       if (CurrentToken() == Token::kCOMMA) {
         ConsumeToken();
-        stack_trace_param.type =
-            &AbstractType::ZoneHandle(Z, Type::DynamicType());
+        stack_trace_param.type = &Object::dynamic_type();
         stack_trace_param.token_pos = TokenPos();
         stack_trace_param.name = ExpectIdentifier("identifier expected");
       }
@@ -9579,7 +9596,7 @@
   LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
       Scanner::kNoSourcePos,
       async_saved_try_ctx_name,
-      Type::ZoneHandle(Z, Type::DynamicType()));
+      Object::dynamic_type());
   ASSERT(async_temp_scope_ != NULL);
   async_temp_scope_->AddVariable(async_saved_try_ctx);
   ASSERT(saved_try_context != NULL);
@@ -10543,7 +10560,7 @@
   LocalVariable* temp = new(Z) LocalVariable(
       token_pos,
       String::ZoneHandle(Z, Symbols::New(name)),
-      Type::ZoneHandle(Z, Type::DynamicType()));
+      Object::dynamic_type());
   temp->set_is_final();
   current_block_->scope->AddVariable(temp);
   return temp;
@@ -13178,7 +13195,7 @@
   ParamList params;
   params.AddFinalParameter(token_pos,
                            &Symbols::ClosureParameter(),
-                           &Type::ZoneHandle(Z, Type::DynamicType()));
+                           &Object::dynamic_type());
 
   ParseFormalParameters(ctr, &params);
   // Per language spec, the type of the closure parameters is dynamic.
@@ -13191,7 +13208,7 @@
   closure.set_is_generated_body(true);
   closure.set_is_debuggable(false);
   closure.set_is_visible(false);
-  closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
+  closure.set_result_type(Object::dynamic_type());
   AddFormalParamsToFunction(&params, closure);
 
   // Create and set the signature class of the closure.
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 98bb8a0..03333d5 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -63,7 +63,7 @@
     LocalVariable* temp = new(zone()) LocalVariable(
         function.token_pos(),
         Symbols::CurrentContextVar(),
-        Type::ZoneHandle(zone(), Type::DynamicType()));
+        Object::dynamic_type());
     ASSERT(temp != NULL);
     current_context_var_ = temp;
   }
diff --git a/runtime/vm/port_test.cc b/runtime/vm/port_test.cc
index 165d19c..ee443cd 100644
--- a/runtime/vm/port_test.cc
+++ b/runtime/vm/port_test.cc
@@ -151,6 +151,34 @@
 }
 
 
+TEST_CASE(PortMap_PostIntegerMessage) {
+  PortTestMessageHandler handler;
+  Dart_Port port = PortMap::CreatePort(&handler);
+  EXPECT_EQ(0, handler.notify_count);
+
+  EXPECT(PortMap::PostMessage(new Message(
+      port, Smi::New(42), Message::kNormalPriority)));
+
+  // Check that the message notify callback was called.
+  EXPECT_EQ(1, handler.notify_count);
+  PortMap::ClosePorts(&handler);
+}
+
+
+TEST_CASE(PortMap_PostNullMessage) {
+  PortTestMessageHandler handler;
+  Dart_Port port = PortMap::CreatePort(&handler);
+  EXPECT_EQ(0, handler.notify_count);
+
+  EXPECT(PortMap::PostMessage(new Message(
+      port, Object::null(), Message::kNormalPriority)));
+
+  // Check that the message notify callback was called.
+  EXPECT_EQ(1, handler.notify_count);
+  PortMap::ClosePorts(&handler);
+}
+
+
 TEST_CASE(PortMap_PostMessageClosedPort) {
   // Create a port id and make it invalid.
   PortTestMessageHandler handler;
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 9f820b0..ff01393 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -1193,9 +1193,9 @@
       continue;
     }
     if (!sample->head_sample()) {
-        // An inner sample in a chain of samples.
-        continue;
-      }
+      // An inner sample in a chain of samples.
+      continue;
+    }
     if (sample->isolate() != filter->isolate()) {
       // Another isolate.
       continue;
@@ -1228,6 +1228,7 @@
 
   // Copy state bits from sample.
   processed_sample->set_timestamp(sample->timestamp());
+  processed_sample->set_tid(sample->tid());
   processed_sample->set_vm_tag(sample->vm_tag());
   processed_sample->set_user_tag(sample->user_tag());
   if (sample->is_allocation_sample()) {
@@ -1287,7 +1288,8 @@
       vm_tag_(0),
       user_tag_(0),
       allocation_cid_(-1),
-      truncated_(false) {
+      truncated_(false),
+      timeline_trie_(NULL) {
 }
 
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index f4b481e..e598e70 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -25,6 +25,7 @@
 
 class Sample;
 class SampleBuffer;
+class ProfileTrieNode;
 
 class Profiler : public AllStatic {
  public:
@@ -533,6 +534,9 @@
   int64_t timestamp() const { return timestamp_; }
   void set_timestamp(int64_t timestamp) { timestamp_ = timestamp; }
 
+  ThreadId tid() const { return tid_; }
+  void set_tid(ThreadId tid) { tid_ = tid; }
+
   // The VM tag.
   uword vm_tag() const { return vm_tag_; }
   void set_vm_tag(uword tag) { vm_tag_ = tag; }
@@ -559,6 +563,12 @@
     first_frame_executing_ = first_frame_executing;
   }
 
+  ProfileTrieNode* timeline_trie() const { return timeline_trie_; }
+  void set_timeline_trie(ProfileTrieNode* trie) {
+    ASSERT(timeline_trie_ == NULL);
+    timeline_trie_ = trie;
+  }
+
  private:
   void FixupCaller(const CodeLookupTable& clt,
                    uword pc_marker,
@@ -571,11 +581,13 @@
 
   ZoneGrowableArray<uword> pcs_;
   int64_t timestamp_;
+  ThreadId tid_;
   uword vm_tag_;
   uword user_tag_;
   intptr_t allocation_cid_;
   bool truncated_;
   bool first_frame_executing_;
+  ProfileTrieNode* timeline_trie_;
 
   friend class SampleBuffer;
   DISALLOW_COPY_AND_ASSIGN(ProcessedSample);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 40b7bdc..9a0d5fc 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -253,9 +253,9 @@
     name_ = NULL;
   }
   intptr_t len = strlen(name);
-  name_ = Thread::Current()->zone()->Alloc<const char>(len + 1);
-  strncpy(const_cast<char*>(name_), name, len);
-  const_cast<char*>(name_)[len] = '\0';
+  name_ = Thread::Current()->zone()->Alloc<char>(len + 1);
+  strncpy(name_, name, len);
+  name_[len] = '\0';
 }
 
 
@@ -797,7 +797,8 @@
 ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
     : table_index_(table_index),
       count_(0),
-      children_(0) {
+      children_(0),
+      frame_id_(-1) {
   ASSERT(table_index_ >= 0);
 }
 
@@ -1056,6 +1057,7 @@
       return;
     }
     samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
+    profile_->samples_ = samples_;
     profile_->sample_count_ = samples_->length();
   }
 
@@ -1333,6 +1335,8 @@
         ASSERT(sample->At(frame_index) != 0);
         current = ProcessFrame(current, sample_index, sample, frame_index);
       }
+
+      sample->set_timeline_trie(current);
     }
   }
 
@@ -1973,6 +1977,8 @@
 
 Profile::Profile(Isolate* isolate)
     : isolate_(isolate),
+      zone_(Thread::Current()->zone()),
+      samples_(NULL),
       live_code_(NULL),
       dead_code_(NULL),
       tag_code_(NULL),
@@ -2034,16 +2040,90 @@
 }
 
 
-void Profile::PrintJSON(JSONStream* stream) {
-  ScopeTimer sw("Profile::PrintJSON", FLAG_trace_profiler);
+void Profile::PrintHeaderJSON(JSONObject* obj) {
+  obj->AddProperty("samplePeriod",
+                   static_cast<intptr_t>(FLAG_profile_period));
+  obj->AddProperty("stackDepth",
+                   static_cast<intptr_t>(FLAG_max_profile_depth));
+  obj->AddProperty("sampleCount", sample_count());
+  obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+}
+
+
+void Profile::PrintTimelineFrameJSON(JSONObject* frames,
+                                     ProfileTrieNode* current,
+                                     ProfileTrieNode* parent,
+                                     intptr_t* next_id) {
+  ASSERT(current->frame_id() == -1);
+  const intptr_t id = *next_id;
+  *next_id = id + 1;
+  current->set_frame_id(id);
+  ASSERT(current->frame_id() != -1);
+
+  {
+    // The samples from many isolates may be merged into a single timeline,
+    // so prefix frames id with the isolate.
+    intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+    const char* key = zone_->PrintToString("%" Pd "-%" Pd,
+                                           isolate_id, current->frame_id());
+    JSONObject frame(frames, key);
+    frame.AddProperty("category", "Dart");
+    ProfileFunction* func = GetFunction(current->table_index());
+    frame.AddProperty("name", func->Name());
+    if (parent != NULL) {
+      ASSERT(parent->frame_id() != -1);
+      frame.AddPropertyF("parent", "%" Pd "-%" Pd,
+                         isolate_id, parent->frame_id());
+    }
+  }
+
+  for (intptr_t i = 0; i < current->NumChildren(); i++) {
+    ProfileTrieNode* child = current->At(i);
+    PrintTimelineFrameJSON(frames, child, current, next_id);
+  }
+}
+
+
+void Profile::PrintTimelineJSON(JSONStream* stream) {
+  ScopeTimer sw("Profile::PrintTimelineJSON", FLAG_trace_profiler);
+  JSONObject obj(stream);
+  obj.AddProperty("type", "_CpuProfileTimeline");
+  PrintHeaderJSON(&obj);
+  {
+    JSONObject frames(&obj, "stackFrames");
+    ProfileTrieNode* root = GetTrieRoot(kInclusiveFunction);
+    intptr_t next_id = 0;
+    PrintTimelineFrameJSON(&frames, root, NULL, &next_id);
+  }
+  {
+    JSONArray events(&obj, "traceEvents");
+    intptr_t pid = OS::ProcessId();
+    intptr_t isolate_id = reinterpret_cast<intptr_t>(isolate_);
+    for (intptr_t sample_index = 0;
+         sample_index < samples_->length();
+         sample_index++) {
+      ProcessedSample* sample = samples_->At(sample_index);
+      JSONObject event(&events);
+      event.AddProperty("ph", "P");  // kind = sample event
+      event.AddProperty64("pid", pid);
+      event.AddProperty64("tid", OSThread::ThreadIdToIntPtr(sample->tid()));
+      event.AddPropertyTimeMicros("ts", sample->timestamp());
+      event.AddProperty("cat", "Dart");
+
+      ProfileTrieNode* trie = sample->timeline_trie();
+      ASSERT(trie->frame_id() != -1);
+      event.AddPropertyF("sf", "%" Pd "-%" Pd,
+                         isolate_id, trie->frame_id());
+    }
+  }
+}
+
+
+void Profile::PrintProfileJSON(JSONStream* stream) {
+  ScopeTimer sw("Profile::PrintProfileJSON", FLAG_trace_profiler);
   JSONObject obj(stream);
   obj.AddProperty("type", "_CpuProfile");
-  obj.AddProperty("samplePeriod",
-                  static_cast<intptr_t>(FLAG_profile_period));
-  obj.AddProperty("stackDepth",
-                  static_cast<intptr_t>(FLAG_max_profile_depth));
-  obj.AddProperty("sampleCount", sample_count());
-  obj.AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+  PrintHeaderJSON(&obj);
   {
     JSONArray codes(&obj, "codes");
     for (intptr_t i = 0; i < live_code_->length(); i++) {
@@ -2196,7 +2276,8 @@
                                     JSONStream* stream,
                                     Profile::TagOrder tag_order,
                                     intptr_t extra_tags,
-                                    SampleFilter* filter) {
+                                    SampleFilter* filter,
+                                    bool as_timeline) {
   Isolate* isolate = thread->isolate();
   // Disable thread interrupts while processing the buffer.
   DisableThreadInterruptsScope dtis(thread);
@@ -2212,7 +2293,11 @@
     HANDLESCOPE(thread);
     Profile profile(isolate);
     profile.Build(thread, filter, tag_order, extra_tags);
-    profile.PrintJSON(stream);
+    if (as_timeline) {
+      profile.PrintTimelineJSON(stream);
+    } else {
+      profile.PrintProfileJSON(stream);
+    }
   }
 }
 
@@ -2235,7 +2320,8 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   NoAllocationSampleFilter filter(isolate);
-  PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter);
+  const bool as_timeline = false;
+  PrintJSONImpl(thread, stream, tag_order, extra_tags, &filter, as_timeline);
 }
 
 
@@ -2263,7 +2349,18 @@
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   ClassAllocationSampleFilter filter(isolate, cls);
-  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter);
+  const bool as_timeline = false;
+  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
+}
+
+
+void ProfilerService::PrintTimelineJSON(JSONStream* stream,
+                                        Profile::TagOrder tag_order) {
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+  NoAllocationSampleFilter filter(isolate);
+  const bool as_timeline = true;
+  PrintJSONImpl(thread, stream, tag_order, kNoExtraTags, &filter, as_timeline);
 }
 
 
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 83df5e7..e931598 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -28,6 +28,7 @@
 class RawCode;
 class RawFunction;
 class SampleFilter;
+class ProcessedSampleBuffer;
 
 // Profile data related to a |Function|.
 class ProfileFunction : public ZoneAllocated {
@@ -207,7 +208,7 @@
   intptr_t inclusive_serial_;
 
   const Code& code_;
-  const char* name_;
+  char* name_;
   int64_t compile_timestamp_;
   ProfileFunction* function_;
   intptr_t code_table_index_;
@@ -250,6 +251,12 @@
 
   intptr_t IndexOf(ProfileTrieNode* node);
 
+  intptr_t frame_id() const { return frame_id_; }
+  void set_frame_id(intptr_t id) {
+    ASSERT(frame_id_ == -1);
+    frame_id_ = id;
+  }
+
  protected:
   void SortChildren();
 
@@ -264,6 +271,7 @@
   intptr_t table_index_;
   intptr_t count_;
   ZoneGrowableArray<ProfileTrieNode*> children_;
+  intptr_t frame_id_;
 
   friend class ProfileBuilder;
 };
@@ -315,10 +323,19 @@
   ProfileCode* GetCode(intptr_t index);
   ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
 
-  void PrintJSON(JSONStream* stream);
+  void PrintProfileJSON(JSONStream* stream);
+  void PrintTimelineJSON(JSONStream* stream);
 
  private:
+  void PrintHeaderJSON(JSONObject* obj);
+  void PrintTimelineFrameJSON(JSONObject* frames,
+                              ProfileTrieNode* current,
+                              ProfileTrieNode* parent,
+                              intptr_t* next_id);
+
   Isolate* isolate_;
+  Zone* zone_;
+  ProcessedSampleBuffer* samples_;
   ProfileCodeTable* live_code_;
   ProfileCodeTable* dead_code_;
   ProfileCodeTable* tag_code_;
@@ -385,6 +402,9 @@
                                   Profile::TagOrder tag_order,
                                   const Class& cls);
 
+  static void PrintTimelineJSON(JSONStream* stream,
+                                Profile::TagOrder tag_order);
+
   static void ClearSamples();
 
  private:
@@ -392,7 +412,8 @@
                             JSONStream* stream,
                             Profile::TagOrder tag_order,
                             intptr_t extra_tags,
-                            SampleFilter* filter);
+                            SampleFilter* filter,
+                            bool as_timline);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 74013a6..ba53d37 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -165,7 +165,7 @@
       break;
     }
     case kFreeListElement: {
-      uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
+      uword addr = RawObject::ToAddr(this);
       FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
       instance_size = element->Size();
       break;
@@ -277,7 +277,7 @@
       }
 #undef RAW_VISITPOINTERS
       case kFreeListElement: {
-        uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
+        uword addr = RawObject::ToAddr(this);
         FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
         size = element->Size();
         break;
@@ -303,7 +303,7 @@
 
 bool RawObject::FindObject(FindObjectVisitor* visitor) {
   ASSERT(visitor != NULL);
-  return visitor->FindObject(const_cast<RawObject*>(this));
+  return visitor->FindObject(this);
 }
 
 
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index b178fed..df2902c 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -868,7 +868,6 @@
     RawInstance* static_value_;  // Value for static fields.
     RawSmi* offset_;  // Offset in words for instance fields.
   } value_;
-  RawArray* dependent_code_;
   union {
     // When precompiling we need to save the static initializer function here
     // so that code for it can be generated.
@@ -878,6 +877,10 @@
     // restore the value back to the original initial value.
     RawInstance* saved_value_;  // Saved initial value - static fields.
   } initializer_;
+  RawObject** to_precompiled_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->initializer_);
+  }
+  RawArray* dependent_code_;
   RawSmi* guarded_list_length_;
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 38e1f17..87305ba 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -13,6 +13,7 @@
 namespace dart {
 
 DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, use_field_guards);
 
 #define NEW_OBJECT(type)                                                       \
   ((kind == Snapshot::kFull) ? reader->New##type() : type::New())
@@ -796,17 +797,33 @@
   reader->AddBackRef(object_id, &field, kIsDeserialized);
 
   // Set all non object fields.
-  field.set_token_pos(reader->Read<int32_t>());
-  field.set_guarded_cid(reader->Read<int32_t>());
-  field.set_is_nullable(reader->Read<int32_t>());
+  if (reader->snapshot_code()) {
+    field.set_token_pos(0);
+    ASSERT(!FLAG_use_field_guards);
+    field.set_guarded_cid(kDynamicCid);
+    field.set_is_nullable(true);
+  } else {
+    field.set_token_pos(reader->Read<int32_t>());
+    field.set_guarded_cid(reader->Read<int32_t>());
+    field.set_is_nullable(reader->Read<int32_t>());
+  }
   field.set_kind_bits(reader->Read<uint8_t>());
 
   // Set all the object fields.
+  RawObject** toobj = reader->snapshot_code()
+      ? field.raw()->to_precompiled_snapshot()
+      : field.raw()->to();
   READ_OBJECT_FIELDS(field,
-                     field.raw()->from(), field.raw()->to(),
+                     field.raw()->from(), toobj,
                      kAsReference);
 
-  field.InitializeGuardedListLengthInObjectOffset();
+  if (reader->snapshot_code()) {
+    ASSERT(!FLAG_use_field_guards);
+    field.set_guarded_list_length(Field::kNoFixedLength);
+    field.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
+  } else {
+    field.InitializeGuardedListLengthInObjectOffset();
+  }
 
   return field.raw();
 }
@@ -827,9 +844,11 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
-  writer->Write<int32_t>(ptr()->guarded_cid_);
-  writer->Write<int32_t>(ptr()->is_nullable_);
+  if (!writer->snapshot_code()) {
+    writer->Write<int32_t>(ptr()->token_pos_);
+    writer->Write<int32_t>(ptr()->guarded_cid_);
+    writer->Write<int32_t>(ptr()->is_nullable_);
+  }
   writer->Write<uint8_t>(ptr()->kind_bits_);
 
   // Write out the name.
@@ -851,16 +870,18 @@
   } else {
     writer->WriteObjectImpl(ptr()->value_.offset_, kAsReference);
   }
-  // Write out the dependent code.
-  writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
   // Write out the initializer function or saved initial value.
   if (writer->snapshot_code()) {
     writer->WriteObjectImpl(ptr()->initializer_.precompiled_, kAsReference);
   } else {
     writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
   }
-  // Write out the guarded list length.
-  writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
+  if (!writer->snapshot_code()) {
+    // Write out the dependent code.
+    writer->WriteObjectImpl(ptr()->dependent_code_, kAsReference);
+    // Write out the guarded list length.
+    writer->WriteObjectImpl(ptr()->guarded_list_length_, kAsReference);
+  }
 }
 
 
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index f58137c..46122bd 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -5276,15 +5276,15 @@
   fn.set_parameter_names(Array::Handle(zone, Array::New(kParamCount,
                                                            Heap::kOld)));
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamRegExpIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamRegExpIndex,
                         Symbols::This());
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamStringIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamStringIndex,
                         Symbols::string_param());
   fn.SetParameterTypeAt(RegExpMacroAssembler::kParamStartOffsetIndex,
-                        Type::Handle(zone, Type::DynamicType()));
+                        Object::dynamic_type());
   fn.SetParameterNameAt(RegExpMacroAssembler::kParamStartOffsetIndex,
                         Symbols::start_index_param());
   fn.set_result_type(Type::Handle(zone, Type::ArrayType()));
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 7d4cff2..a41db46 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -382,9 +382,8 @@
 
 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name,
                                                  intptr_t index) const {
-  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(Z) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, Object::dynamic_type());
 
   intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index;
   local->set_index(param_frame_index);
@@ -394,9 +393,8 @@
 
 
 LocalVariable* IRRegExpMacroAssembler::Local(const String& name) {
-  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(Z) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, Object::dynamic_type());
   local->set_index(GetNextLocalIndex());
 
   return local;
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index 4004e4f..fe8d2898 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -47,7 +47,6 @@
         next_(NULL) {
     VMTag::RegisterRuntimeEntry(this);
   }
-  ~RuntimeEntry() {}
 
   const char* name() const { return name_; }
   RuntimeFunction function() const { return function_; }
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 6d9799e..60478d3 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -449,7 +449,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  Thread::PrepareForGC();
+  isolate->thread_registry()->PrepareForGC();
   // Flip the two semi-spaces so that to_ is always the space for allocating
   // objects.
   SemiSpace* from = to_;
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 0881b87..d325b5b 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -576,7 +576,7 @@
     if (context_scope.IsConstAt(i)) {
       variable = new LocalVariable(context_scope.TokenIndexAt(i),
           String::ZoneHandle(context_scope.NameAt(i)),
-          AbstractType::ZoneHandle(Type::DynamicType()));
+          Object::dynamic_type());
       variable->SetConstValue(
           Instance::ZoneHandle(context_scope.ConstValueAt(i)));
     } else {
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index ccc2d58..c8c4249 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -113,6 +113,7 @@
 StreamInfo Service::echo_stream("_Echo");
 StreamInfo Service::graph_stream("_Graph");
 StreamInfo Service::logging_stream("_Logging");
+StreamInfo Service::extension_stream("Extension");
 
 static StreamInfo* streams_[] = {
   &Service::vm_stream,
@@ -122,6 +123,7 @@
   &Service::echo_stream,
   &Service::graph_stream,
   &Service::logging_stream,
+  &Service::extension_stream,
 };
 
 
@@ -1445,10 +1447,14 @@
     // The user may try to load an expired message.
     return Object::sentinel().raw();
   }
-  MessageSnapshotReader reader(message->data(),
-                               message->len(),
-                               thread);
-  return reader.ReadObject();
+  if (message->len() > 0) {
+    MessageSnapshotReader reader(message->data(),
+                                 message->len(),
+                                 thread);
+    return reader.ReadObject();
+  } else {
+    return message->raw_obj();
+  }
 }
 
 
@@ -2613,7 +2619,6 @@
   ASSERT(timeline_recorder != NULL);
   TimelineEventFilter filter;
   timeline_recorder->PrintJSON(js, &filter);
-
   return true;
 }
 
@@ -2745,6 +2750,21 @@
 }
 
 
+static const MethodParameter* get_cpu_profile_timeline_params[] = {
+  ISOLATE_PARAMETER,
+  new EnumParameter("tags", true, tags_enum_names),
+  NULL,
+};
+
+
+static bool GetCpuProfileTimeline(Thread* thread, JSONStream* js) {
+  Profile::TagOrder tag_order =
+      EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
+  ProfilerService::PrintTimelineJSON(js, tag_order);
+  return true;
+}
+
+
 static const MethodParameter* get_allocation_samples_params[] = {
   ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
@@ -2934,6 +2954,9 @@
                            const Instance& zone,
                            const Object& error,
                            const Instance& stack_trace) {
+  if (!Service::logging_stream.enabled()) {
+    return;
+  }
   ServiceEvent::LogRecord log_record;
   log_record.sequence_number = sequence_number;
   log_record.timestamp = timestamp;
@@ -2949,6 +2972,21 @@
 }
 
 
+void Service::SendExtensionEvent(Isolate* isolate,
+                                 const String& event_kind,
+                                 const String& event_data) {
+  if (!Service::extension_stream.enabled()) {
+    return;
+  }
+  ServiceEvent::ExtensionEvent extension_event;
+  extension_event.event_kind = &event_kind;
+  extension_event.event_data = &event_data;
+  ServiceEvent event(isolate, ServiceEvent::kExtension);
+  event.set_extension_event(extension_event);
+  Service::HandleEvent(&event);
+}
+
+
 class ContainsAddressVisitor : public FindObjectVisitor {
  public:
   ContainsAddressVisitor(Isolate* isolate, uword addr)
@@ -3224,7 +3262,7 @@
   jsobj.AddProperty("targetCPU", CPU::Id());
   jsobj.AddProperty("hostCPU", HostCPUFeatures::hardware());
   jsobj.AddProperty("version", Version::String());
-  jsobj.AddProperty("pid", OS::ProcessId());
+  jsobj.AddProperty64("pid", OS::ProcessId());
   int64_t start_time_millis = (vm_isolate->start_time() /
                                kMicrosecondsPerMillisecond);
   jsobj.AddPropertyTimeMillis("startTime", start_time_millis);
@@ -3477,6 +3515,8 @@
     get_coverage_params },
   { "_getCpuProfile", GetCpuProfile,
     get_cpu_profile_params },
+  { "_getCpuProfileTimeline", GetCpuProfileTimeline,
+    get_cpu_profile_timeline_params },
   { "getFlagList", GetFlagList,
     get_flag_list_params },
   { "_getHeapMap", GetHeapMap,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 4d99bed..164a94f 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -124,6 +124,10 @@
                            const Object& error,
                            const Instance& stack_trace);
 
+  static void SendExtensionEvent(Isolate* isolate,
+                                 const String& event_kind,
+                                 const String& event_data);
+
   static void PostError(const String& method_name,
                         const Array& parameter_keys,
                         const Array& parameter_values,
@@ -139,6 +143,7 @@
   static StreamInfo echo_stream;
   static StreamInfo graph_stream;
   static StreamInfo logging_stream;
+  static StreamInfo extension_stream;
 
   static bool ListenStream(const char* stream_id);
   static void CancelStream(const char* stream_id);
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index e71169d..6d2d894 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -58,6 +58,7 @@
 	- [ErrorKind](#errorkind)
 	- [Event](#event)
 	- [EventKind](#eventkind)
+	- [ExtensionData](#extensiondata)
 	- [Field](#field)
 	- [Flag](#flag)
 	- [FlagList](#flaglist)
@@ -715,9 +716,10 @@
 streamId | event types provided
 -------- | -----------
 VM | VMUpdate
-Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate
+Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, ServiceExtensionAdded
 Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect
 GC | GC
+Extension | Extension
 
 Additionally, some embedders provide the _Stdout_ and _Stderr_
 streams.  These streams allow the client to subscribe to writes to
@@ -1139,6 +1141,21 @@
   //
   // This is provided for the Inspect event.
   @Instance inspectee [optional];
+
+  // The RPC name of the extension that was added.
+  //
+  // This is provided for the ServiceExtensionAdded event.
+  string extensionRPC [optional];
+
+  // The extension event kind.
+  //
+  // This is provided for the Extension event.
+  string extensionKind [optional];
+
+  // The extension event data.
+  //
+  // This is provided for the Extension event.
+  ExtensionData extensionData [optional];
 }
 ```
 
@@ -1170,6 +1187,9 @@
   // via setName.
   IsolateUpdate,
 
+  // Notification that an extension RPC was registered on an isolate.
+  ServiceExtensionAdded,
+
   // An isolate has paused at start, before executing code.
   PauseStart,
 
@@ -1204,13 +1224,25 @@
   WriteEvent,
 
   // Notification from dart:developer.inspect.
-  Inspect
+  Inspect,
+
+  // Event from dart:developer.postEvent.
+  Extension
 }
 ```
 
 Adding new values to _EventKind_ is considered a backwards compatible
 change. Clients should ignore unrecognized events.
 
+### ExtensionData
+
+```
+class ExtensionData {
+}
+```
+
+An _ExtensionData_ is an arbitrary map that can have any contents.
+
 ### Field
 
 ```
@@ -1554,7 +1586,7 @@
   //   List
   (@Instance|Sentinel)[] elements [optional];
 
-  // The elements of a List instance.
+  // The elements of a Map instance.
   //
   // Provided for instance kinds:
   //   Map
@@ -1815,6 +1847,9 @@
 
   // The current pause on exception mode for this isolate.
   ExceptionPauseMode exceptionPauseMode;
+
+  // The list of service extension RPCs that are registered for this isolate.
+  string[] extensionRPCs;
 }
 ```
 
@@ -2281,7 +2316,7 @@
 ------- | --------
 1.0 | initial revision
 2.0 | Describe protocol version 2.0.
-3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance.
+3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
 
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index bad3583..92b6f43 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -40,6 +40,7 @@
       embedder_stream_id_(NULL),
       breakpoint_(NULL),
       top_frame_(NULL),
+      extension_rpc_(NULL),
       exception_(NULL),
       async_continuation_(NULL),
       at_async_jump_(false),
@@ -62,6 +63,7 @@
       kind_(TranslateEventKind(debugger_event->type())),
       breakpoint_(NULL),
       top_frame_(NULL),
+      extension_rpc_(NULL),
       exception_(NULL),
       async_continuation_(NULL),
       inspectee_(NULL),
@@ -101,6 +103,8 @@
       return "IsolateExit";
     case kIsolateUpdate:
       return "IsolateUpdate";
+    case kServiceExtensionAdded:
+      return "ServiceExtensionAdded";
     case kPauseStart:
       return "PauseStart";
     case kPauseExit:
@@ -131,6 +135,8 @@
       return "_DebuggerSettingsUpdate";
     case kIllegal:
       return "Illegal";
+    case kExtension:
+      return "Extension";
     default:
       UNREACHABLE();
       return "Unknown";
@@ -147,6 +153,7 @@
     case kIsolateRunnable:
     case kIsolateExit:
     case kIsolateUpdate:
+    case kServiceExtensionAdded:
       return Service::isolate_stream.id();
 
     case kPauseStart:
@@ -171,6 +178,9 @@
     case kLogging:
       return Service::logging_stream.id();
 
+    case kExtension:
+      return Service::extension_stream.id();
+
     default:
       UNREACHABLE();
       return NULL;
@@ -181,6 +191,10 @@
 void ServiceEvent::PrintJSON(JSONStream* js) const {
   JSONObject jsobj(js);
   PrintJSONHeader(&jsobj);
+  if (kind() == kServiceExtensionAdded) {
+    ASSERT(extension_rpc_ != NULL);
+    jsobj.AddProperty("extensionRPC", extension_rpc_->ToCString());
+  }
   if (kind() == kPauseBreakpoint) {
     JSONArray jsarr(&jsobj, "pauseBreakpoints");
     // TODO(rmacnak): If we are paused at more than one breakpoint,
@@ -232,6 +246,10 @@
     logRecord.AddProperty("error", *(log_record_.error));
     logRecord.AddProperty("stackTrace", *(log_record_.stack_trace));
   }
+  if (kind() == kExtension) {
+    js->AppendSerializedObject("extensionData",
+                               extension_event_.event_data->ToCString());
+  }
 }
 
 
@@ -239,6 +257,11 @@
   ASSERT(jsobj != NULL);
   jsobj->AddProperty("type", "Event");
   jsobj->AddProperty("kind", KindAsCString());
+  if (kind() == kExtension) {
+    ASSERT(extension_event_.event_kind != NULL);
+    jsobj->AddProperty("extensionKind",
+                       extension_event_.event_kind->ToCString());
+  }
   if (kind() == kVMUpdate) {
     jsobj->AddPropertyVM("vm");
   } else {
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index 71516a6..ed4153b 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -21,6 +21,8 @@
     kIsolateExit,        // Isolate has exited
     kIsolateUpdate,      // Isolate identity information has changed
 
+    kServiceExtensionAdded,  // A service extension was registered
+
     kPauseStart,         // --pause-isolates-on-start
     kPauseExit,          // --pause-isolates-on-exit
     kPauseBreakpoint,
@@ -39,6 +41,8 @@
 
     kLogging,
 
+    kExtension,
+
     kIllegal,
   };
 
@@ -53,6 +57,11 @@
     const Instance* stack_trace;
   };
 
+  struct ExtensionEvent {
+    const String* event_kind;
+    const String* event_data;
+  };
+
   ServiceEvent(Isolate* isolate, EventKind event_kind);
 
   explicit ServiceEvent(const DebuggerEvent* debugger_event);
@@ -97,6 +106,13 @@
     top_frame_ = frame;
   }
 
+  const String* extension_rpc() const {
+    return extension_rpc_;
+  }
+  void set_extension_rpc(const String* extension_rpc) {
+    extension_rpc_ = extension_rpc;
+  }
+
   const Object* exception() const {
     return exception_;
   }
@@ -153,6 +169,10 @@
     log_record_ = log_record;
   }
 
+  void set_extension_event(const ExtensionEvent& extension_event) {
+    extension_event_ = extension_event;
+  }
+
   int64_t timestamp() const {
     return timestamp_;
   }
@@ -168,6 +188,7 @@
   const char* embedder_stream_id_;
   Breakpoint* breakpoint_;
   ActivationFrame* top_frame_;
+  const String* extension_rpc_;
   const Object* exception_;
   const Object* async_continuation_;
   bool at_async_jump_;
@@ -176,6 +197,7 @@
   const uint8_t* bytes_;
   intptr_t bytes_length_;
   LogRecord log_record_;
+  ExtensionEvent extension_event_;
   int64_t timestamp_;
 };
 
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index eddb622..d55fe3b 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -35,10 +35,15 @@
     }
 
     // Parse the message.
-    Thread* thread = Thread::Current();
-    MessageSnapshotReader reader(message->data(), message->len(), thread);
-    const Object& response_obj = Object::Handle(reader.ReadObject());
     String& response = String::Handle();
+    Object& response_obj = Object::Handle();
+    if (message->IsRaw()) {
+      response_obj = message->raw_obj();
+    } else {
+      Thread* thread = Thread::Current();
+      MessageSnapshotReader reader(message->data(), message->len(), thread);
+      response_obj = reader.ReadObject();
+    }
     response ^= response_obj.raw();
     _msg = strdup(response.ToCString());
     return kOK;
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index db6f42e..134b759 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -236,16 +236,14 @@
 }
 
 
-// TODO(koda): Make non-static and invoke in SafepointThreads.
 void Thread::PrepareForGC() {
-  Thread* thread = Thread::Current();
-  // Prevent scheduling another GC.
-  thread->StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
+  ASSERT(isolate()->thread_registry()->AtSafepoint());
+  // Prevent scheduling another GC by ignoring the threshold.
+  StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
   // Make sure to get an *empty* block; the isolate needs all entries
   // at GC time.
   // TODO(koda): Replace with an epilogue (PrepareAfterGC) that acquires.
-  thread->store_buffer_block_ =
-      thread->isolate()->store_buffer()->PopEmptyBlock();
+  store_buffer_block_ = isolate()->store_buffer()->PopEmptyBlock();
 }
 
 
@@ -274,7 +272,7 @@
 void Thread::StoreBufferRelease(StoreBuffer::ThresholdPolicy policy) {
   StoreBufferBlock* block = store_buffer_block_;
   store_buffer_block_ = NULL;
-  isolate_->store_buffer()->PushBlock(block, policy);
+  isolate()->store_buffer()->PushBlock(block, policy);
 }
 
 
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 15483cb..281ac84 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -134,10 +134,8 @@
                                    bool bypass_safepoint = false);
   static void ExitIsolateAsHelper(bool bypass_safepoint = false);
 
-  // Called when the current thread transitions from mutator to collector.
   // Empties the store buffer block into the isolate.
-  // TODO(koda): Always run GC in separate thread.
-  static void PrepareForGC();
+  void PrepareForGC();
 
   // OSThread corresponding to this thread.
   OSThread* os_thread() const { return os_thread_; }
@@ -414,7 +412,7 @@
   int32_t no_callback_scope_depth_;
 #if defined(DEBUG)
   HandleScope* top_handle_scope_;
-  intptr_t no_handle_scope_depth_;
+  int32_t no_handle_scope_depth_;
   int32_t no_safepoint_scope_depth_;
 #endif
   VMHandles reusable_handles_;
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 0d36e0d..5148808 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -13,12 +13,10 @@
   // Go over the free thread list and delete the thread objects.
   {
     MonitorLocker ml(monitor_);
-    // At this point the mutator thread should be the only thread
-    // in the active list, delete it.
-    ASSERT(active_list_->next_ == NULL);
-    ASSERT(active_list_ == mutator_thread_);
+    // At this point the active list should be empty.
+    ASSERT(active_list_ == NULL);
+    // We have cached the mutator thread, delete it.
     delete mutator_thread_;
-    active_list_ = NULL;
     mutator_thread_ = NULL;
     // Now delete all the threads in the free list.
     while (free_list_ != NULL) {
@@ -48,7 +46,6 @@
   Isolate* isolate = Isolate::Current();
   // We only expect this method to be called from within the isolate itself.
   ASSERT(isolate->thread_registry() == this);
-  // TODO(koda): Rename Thread::PrepareForGC and call it here?
   --remaining_;  // Exclude this thread from the count.
   // Ensure the main mutator will reach a safepoint (could be running Dart).
   if (!Thread::Current()->IsMutatorThread()) {
@@ -80,6 +77,8 @@
   OSThread* os_thread = OSThread::Current();
   ASSERT(os_thread != NULL);
   ASSERT(isolate->heap() != NULL);
+  // First get a Thread structure. (we special case the mutator thread
+  // by reusing the cached structure, see comment in 'thread_registry.h').
   if (is_mutator) {
     if (mutator_thread_ == NULL) {
       mutator_thread_ = GetThreadFromFreelist(isolate);
@@ -89,6 +88,9 @@
     thread = GetThreadFromFreelist(isolate);
     ASSERT(thread->api_top_scope() == NULL);
   }
+  // Now add this Thread to the active list for the isolate.
+  AddThreadToActiveList(thread);
+  // Set up other values and set the TLS value.
   thread->isolate_ = isolate;
   thread->heap_ = isolate->heap();
   thread->set_os_thread(os_thread);
@@ -111,6 +113,10 @@
   thread->isolate_ = NULL;
   thread->heap_ = NULL;
   thread->set_os_thread(NULL);
+  // Remove thread from the active list for the isolate.
+  RemoveThreadFromActiveList(thread);
+  // Return thread to the free list (we special case the mutator
+  // thread by holding on to it, see comment in 'thread_registry.h').
   if (!is_mutator) {
     ASSERT(thread->api_top_scope() == NULL);
     ReturnThreadToFreelist(thread);
@@ -147,29 +153,27 @@
 }
 
 
-Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
-  ASSERT(monitor_->IsOwnedByCurrentThread());
-  Thread* thread = NULL;
-  // Get thread structure from free list or create a new one.
-  if (free_list_ == NULL) {
-    thread = new Thread(isolate);
-  } else {
-    thread = free_list_;
-    free_list_ = thread->next_;
+void ThreadRegistry::PrepareForGC() {
+  MonitorLocker ml(monitor_);
+  Thread* thread = active_list_;
+  while (thread != NULL) {
+    thread->PrepareForGC();
+    thread = thread->next_;
   }
-  // Add thread to active list.
-  thread->next_ = active_list_;
-  active_list_ = thread;
-  return thread;
 }
 
-void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
+
+void ThreadRegistry::AddThreadToActiveList(Thread* thread) {
   ASSERT(thread != NULL);
-  ASSERT(thread->os_thread_ == NULL);
-  ASSERT(thread->isolate_ == NULL);
-  ASSERT(thread->heap_ == NULL);
   ASSERT(monitor_->IsOwnedByCurrentThread());
-  // First remove the thread from the active list.
+  thread->next_ = active_list_;
+  active_list_ = thread;
+}
+
+
+void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(monitor_->IsOwnedByCurrentThread());
   Thread* prev = NULL;
   Thread* current = active_list_;
   while (current != NULL) {
@@ -184,7 +188,29 @@
     prev = current;
     current = current->next_;
   }
-  // Now add thread to the free list.
+}
+
+
+Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  Thread* thread = NULL;
+  // Get thread structure from free list or create a new one.
+  if (free_list_ == NULL) {
+    thread = new Thread(isolate);
+  } else {
+    thread = free_list_;
+    free_list_ = thread->next_;
+  }
+  return thread;
+}
+
+void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
+  ASSERT(thread != NULL);
+  ASSERT(thread->os_thread_ == NULL);
+  ASSERT(thread->isolate_ == NULL);
+  ASSERT(thread->heap_ == NULL);
+  ASSERT(monitor_->IsOwnedByCurrentThread());
+  // Add thread to the free list.
   thread->next_ = free_list_;
   free_list_ = thread;
 }
@@ -198,7 +224,6 @@
       ASSERT((last_round == -1) || (round_ == (last_round + 1)));
       last_round = round_;
       // Participate in this round.
-      // TODO(koda): Rename Thread::PrepareForGC and call it here?
       if (--remaining_ == 0) {
         // Ensure the organizing thread is notified.
         // TODO(koda): Use separate condition variables and plain 'Notify'.
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index f077c51..555e513 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -56,8 +56,11 @@
   Thread* Schedule(Isolate* isolate, bool is_mutator, bool bypass_safepoint);
   void Unschedule(Thread* thread, bool is_mutator, bool bypass_safepoint);
   void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
+  void PrepareForGC();
 
  private:
+  void AddThreadToActiveList(Thread* thread);
+  void RemoveThreadFromActiveList(Thread* thread);
   Thread* GetThreadFromFreelist(Isolate* isolate);
   void ReturnThreadToFreelist(Thread* thread);
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index ec998f8..f619d51 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -566,11 +566,6 @@
   Monitor done_monitor;
   bool done = false;
   Isolate* isolate = Thread::Current()->isolate();
-  // Flush store buffers, etc.
-  // TODO(koda): Currently, the GC only does this for the current thread, (i.e,
-  // the helper, in this test), but it should be done for all *threads*
-  // while reaching a safepoint.
-  Thread::PrepareForGC();
   Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done));
   {
     while (true) {
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 60cde39..ab28bee 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -82,6 +82,10 @@
   }
   vm_stream_ = new TimelineStream();
   vm_stream_->Init("VM", EnableStreamByDefault("VM"), NULL);
+  vm_api_stream_ = new TimelineStream();
+  vm_api_stream_->Init("API",
+                       EnableStreamByDefault("API"),
+                       &stream_API_enabled_);
   // Global overrides.
 #define ISOLATE_TIMELINE_STREAM_FLAG_DEFAULT(name, not_used)                   \
   stream_##name##_enabled_ = EnableStreamByDefault(#name);
@@ -99,6 +103,8 @@
   recorder_ = NULL;
   delete vm_stream_;
   vm_stream_ = NULL;
+  delete vm_api_stream_;
+  vm_api_stream_ = NULL;
 }
 
 
@@ -119,6 +125,12 @@
 }
 
 
+TimelineStream* Timeline::GetVMApiStream() {
+  ASSERT(vm_api_stream_ != NULL);
+  return vm_api_stream_;
+}
+
+
 void Timeline::ReclaimCachedBlocksFromThreads() {
   TimelineEventRecorder* recorder = Timeline::recorder();
   if (recorder == NULL) {
@@ -153,6 +165,7 @@
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
 TimelineStream* Timeline::vm_stream_ = NULL;
+TimelineStream* Timeline::vm_api_stream_ = NULL;
 
 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default)          \
   bool Timeline::stream_##name##_enabled_ = enabled_by_default;
@@ -490,10 +503,9 @@
 }
 
 
-TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
-                                             const char* label)
+TimelineEventScope::TimelineEventScope(TimelineStream* stream,
+                                       const char* label)
     : StackResource(reinterpret_cast<Thread*>(NULL)),
-      timestamp_(0),
       stream_(stream),
       label_(label),
       arguments_(NULL),
@@ -503,42 +515,25 @@
 }
 
 
-TimelineDurationScope::TimelineDurationScope(Thread* thread,
-                                             TimelineStream* stream,
-                                             const char* label)
+TimelineEventScope::TimelineEventScope(Thread* thread,
+                                       TimelineStream* stream,
+                                       const char* label)
     : StackResource(thread),
-      timestamp_(0),
       stream_(stream),
       label_(label),
       arguments_(NULL),
       arguments_length_(0),
       enabled_(false) {
-  ASSERT(thread != NULL);
   Init();
 }
 
 
-TimelineDurationScope::~TimelineDurationScope() {
-  if (!enabled_) {
-    FreeArguments();
-    return;
-  }
-  TimelineEvent* event = stream_->StartEvent();
-  if (event == NULL) {
-    // Stream is now disabled.
-    FreeArguments();
-    return;
-  }
-  ASSERT(event != NULL);
-  event->Duration(label_, timestamp_, OS::GetCurrentMonotonicMicros());
-  event->StealArguments(arguments_length_, arguments_);
-  event->Complete();
-  arguments_length_ = 0;
-  arguments_ = NULL;
+TimelineEventScope::~TimelineEventScope() {
+  FreeArguments();
 }
 
 
-void TimelineDurationScope::Init() {
+void TimelineEventScope::Init() {
   ASSERT(enabled_ == false);
   ASSERT(label_ != NULL);
   ASSERT(stream_ != NULL);
@@ -546,12 +541,11 @@
     // Stream is not enabled, do nothing.
     return;
   }
-  timestamp_ = OS::GetCurrentMonotonicMicros();
   enabled_ = true;
 }
 
 
-void TimelineDurationScope::SetNumArguments(intptr_t length) {
+void TimelineEventScope::SetNumArguments(intptr_t length) {
   if (!enabled()) {
     return;
   }
@@ -567,9 +561,9 @@
 
 
 // |name| must be a compile time constant. Takes ownership of |argumentp|.
-void TimelineDurationScope::SetArgument(intptr_t i,
-                                        const char* name,
-                                        char* argument) {
+void TimelineEventScope::SetArgument(intptr_t i,
+                                     const char* name,
+                                     char* argument) {
   if (!enabled()) {
     return;
   }
@@ -581,9 +575,9 @@
 
 
 // |name| must be a compile time constant. Copies |argument|.
-void TimelineDurationScope::CopyArgument(intptr_t i,
-                                         const char* name,
-                                         const char* argument) {
+void TimelineEventScope::CopyArgument(intptr_t i,
+                                      const char* name,
+                                      const char* argument) {
   if (!enabled()) {
     return;
   }
@@ -591,9 +585,9 @@
 }
 
 
-void TimelineDurationScope::FormatArgument(intptr_t i,
-                                           const char* name,
-                                           const char* fmt, ...) {
+void TimelineEventScope::FormatArgument(intptr_t i,
+                                        const char* name,
+                                        const char* fmt, ...) {
   if (!enabled()) {
     return;
   }
@@ -612,7 +606,7 @@
 }
 
 
-void TimelineDurationScope::FreeArguments() {
+void TimelineEventScope::FreeArguments() {
   if (arguments_ == NULL) {
     return;
   }
@@ -625,6 +619,101 @@
 }
 
 
+void TimelineEventScope::StealArguments(TimelineEvent* event) {
+  if (event == NULL) {
+    return;
+  }
+  event->StealArguments(arguments_length_, arguments_);
+  arguments_length_ = 0;
+  arguments_ = NULL;
+}
+
+
+TimelineDurationScope::TimelineDurationScope(TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(stream, label) {
+  timestamp_ = OS::GetCurrentMonotonicMicros();
+}
+
+
+TimelineDurationScope::TimelineDurationScope(Thread* thread,
+                                             TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(thread, stream, label) {
+  timestamp_ = OS::GetCurrentMonotonicMicros();
+}
+
+
+TimelineDurationScope::~TimelineDurationScope() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit a duration event.
+  event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros());
+  StealArguments(event);
+  event->Complete();
+}
+
+
+TimelineBeginEndScope::TimelineBeginEndScope(TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(stream, label) {
+  EmitBegin();
+}
+
+
+TimelineBeginEndScope::TimelineBeginEndScope(Thread* thread,
+                                             TimelineStream* stream,
+                                             const char* label)
+    : TimelineEventScope(thread, stream, label) {
+  EmitBegin();
+}
+
+
+TimelineBeginEndScope::~TimelineBeginEndScope() {
+  EmitEnd();
+}
+
+
+void TimelineBeginEndScope::EmitBegin() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit a begin event.
+  event->Begin(label());
+  event->Complete();
+}
+
+
+void TimelineBeginEndScope::EmitEnd() {
+  if (!ShouldEmitEvent()) {
+    return;
+  }
+  TimelineEvent* event = stream()->StartEvent();
+  if (event == NULL) {
+    // Stream is now disabled.
+    return;
+  }
+  ASSERT(event != NULL);
+  // Emit an end event.
+  event->End(label());
+  StealArguments(event);
+  event->Complete();
+}
+
+
 TimelineEventFilter::TimelineEventFilter() {
 }
 
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index fa55f75..40040a4 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -50,6 +50,8 @@
 
   static TimelineStream* GetVMStream();
 
+  static TimelineStream* GetVMApiStream();
+
   // Reclaim all |TimelineEventBlocks|s that are cached by threads.
   static void ReclaimCachedBlocksFromThreads();
 
@@ -68,6 +70,7 @@
  private:
   static TimelineEventRecorder* recorder_;
   static TimelineStream* vm_stream_;
+  static TimelineStream* vm_api_stream_;
 
 #define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used)                   \
   static bool stream_##name##_enabled_;
@@ -330,21 +333,13 @@
     tds.CopyArgument(                                                          \
         0,                                                                     \
         "function",                                                            \
-        const_cast<char*>(function.ToLibNamePrefixedQualifiedCString()));      \
+        function.ToLibNamePrefixedQualifiedCString());                         \
   }
 
 
-class TimelineDurationScope : public StackResource {
+// See |TimelineDurationScope| and |TimelineBeginEndScope|.
+class TimelineEventScope : public StackResource {
  public:
-  TimelineDurationScope(TimelineStream* stream,
-                        const char* label);
-
-  TimelineDurationScope(Thread* thread,
-                        TimelineStream* stream,
-                        const char* label);
-
-  ~TimelineDurationScope();
-
   bool enabled() const {
     return enabled_;
   }
@@ -359,21 +354,81 @@
                       const char* name,
                       const char* fmt, ...)  PRINTF_ATTRIBUTE(4, 5);
 
+ protected:
+  TimelineEventScope(TimelineStream* stream,
+                     const char* label);
+
+  TimelineEventScope(Thread* thread,
+                     TimelineStream* stream,
+                     const char* label);
+
+  bool ShouldEmitEvent() const {
+    return enabled_;
+  }
+
+  const char* label() const {
+    return label_;
+  }
+
+  TimelineStream* stream() const {
+    return stream_;
+  }
+
+  virtual ~TimelineEventScope();
+
+  void StealArguments(TimelineEvent* event);
+
  private:
   void Init();
   void FreeArguments();
 
-  int64_t timestamp_;
   TimelineStream* stream_;
   const char* label_;
   TimelineEventArgument* arguments_;
   intptr_t arguments_length_;
   bool enabled_;
 
+  DISALLOW_COPY_AND_ASSIGN(TimelineEventScope);
+};
+
+
+class TimelineDurationScope : public TimelineEventScope {
+ public:
+  TimelineDurationScope(TimelineStream* stream,
+                        const char* label);
+
+  TimelineDurationScope(Thread* thread,
+                        TimelineStream* stream,
+                        const char* label);
+
+  ~TimelineDurationScope();
+
+ private:
+  int64_t timestamp_;
+
   DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope);
 };
 
 
+class TimelineBeginEndScope : public TimelineEventScope {
+ public:
+  TimelineBeginEndScope(TimelineStream* stream,
+                        const char* label);
+
+  TimelineBeginEndScope(Thread* thread,
+                        TimelineStream* stream,
+                        const char* label);
+
+  ~TimelineBeginEndScope();
+
+ private:
+  void EmitBegin();
+  void EmitEnd();
+
+  DISALLOW_COPY_AND_ASSIGN(TimelineBeginEndScope);
+};
+
+
 // A block of |TimelineEvent|s. Not thread safe.
 class TimelineEventBlock {
  public:
diff --git a/samples-dev/samples-dev.status b/samples-dev/samples-dev.status
index c477c13..956b798 100644
--- a/samples-dev/samples-dev.status
+++ b/samples-dev/samples-dev.status
@@ -2,36 +2,37 @@
 # 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.
 
-[ $compiler == dart2js && $runtime == drt ]	
+[ $compiler == dart2js && $runtime == drt ]
 swarm/test/swarm_test: Pass, Crash, Fail # Issue 10950
 
-[ $runtime == safari ]	
+[ $runtime == safari ]
 swarm/test/swarm_test: Pass, Fail # Issue 14523
 
-[ $runtime == opera ]	
-swarm/test/swarm_ui_lib/touch/touch_test: Fail	
+[ $runtime == opera ]
+swarm/test/swarm_ui_lib/touch/touch_test: Fail
 swarm/test/swarm_test: Fail
 
 [ $runtime == vm ]
 swarm: Skip
 
-[ $compiler == dart2js && $runtime == chromeOnAndroid ]	
+[ $compiler == dart2js && $runtime == chromeOnAndroid ]
 swarm/test/swarm_test: Fail # TODO(kasperl): Please triage.	
-swarm/test/swarm_ui_lib/layout/layout_test: Fail # TODO(kasperl): Please triage.	
-[ $browser ]	
-# This may be related to issue 157	
+swarm/test/swarm_ui_lib/layout/layout_test: Fail # TODO(kasperl): Please triage.
+
+[ $browser ]
+# This may be related to issue 157
 swarm/test/swarm_ui_lib/touch/touch_test: Fail # Expectation: Solver. Expect.approxEquals(expected:9, actual:8.990625000000001, tolerance:0.0009) fails
 
- [ $compiler == dart2js && $runtime == ff ]	
+ [ $compiler == dart2js && $runtime == ff ]
 swarm/test/swarm_test: Fail # Issue 5633
 
-[ $compiler == dart2js && $runtime == drt && $system == windows ]	
+[ $compiler == dart2js && $runtime == drt && $system == windows ]
 swarm/test/swarm_test: Fail # Issue 4517
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]	
-swarm/test/swarm_test: StaticWarning	
-swarm/test/swarm_ui_lib/layout/layout_test: StaticWarning	
-swarm/test/swarm_ui_lib/observable/observable_test: StaticWarning	
-swarm/test/swarm_ui_lib/touch/touch_test: StaticWarning	
-swarm/test/swarm_ui_lib/util/util_test: StaticWarning	
+[ $compiler == dart2analyzer ]
+swarm/test/swarm_test: StaticWarning
+swarm/test/swarm_ui_lib/layout/layout_test: StaticWarning
+swarm/test/swarm_ui_lib/observable/observable_test: StaticWarning
+swarm/test/swarm_ui_lib/touch/touch_test: StaticWarning
+swarm/test/swarm_ui_lib/util/util_test: StaticWarning
 swarm/test/swarm_ui_lib/view/view_test: StaticWarning
diff --git a/sdk/bin/dart b/sdk/bin/dart
index 3de8c25..999034c 100755
--- a/sdk/bin/dart
+++ b/sdk/bin/dart
@@ -29,7 +29,7 @@
 then
   DIRS=$( ls "$OUT_DIR" )
   # list of possible configurations in decreasing desirability
-  CONFIGS=("ReleaseIA32" "ReleaseX64" "DebugIA32" "DebugX64"
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
     "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
     "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
   DART_CONFIGURATION="None"
diff --git a/sdk/bin/dart.bat b/sdk/bin/dart.bat
index eee051c..9458999 100644
--- a/sdk/bin/dart.bat
+++ b/sdk/bin/dart.bat
@@ -8,8 +8,8 @@
 REM Does the path have a trailing slash? If so, remove it.
 if %SCRIPTPATH:~-1%== set SCRIPTPATH=%SCRIPTPATH:~0,-1%
 
-REM DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+REM DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set arguments=%*
 
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 9e765d9..19f9ddb 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -39,8 +39,8 @@
 
 set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index c793551..0c23848 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -56,7 +56,7 @@
 then
   DIRS=$( ls "$OUT_DIR" )
   # list of possible configurations in decreasing desirability
-  CONFIGS=("ReleaseIA32" "ReleaseX64" "DebugIA32" "DebugX64"
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
     "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
     "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
   DART_CONFIGURATION="None"
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index 0e0cb10..a73427e 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -40,8 +40,8 @@
 
 set ANALYZER=%DART_ROOT%\pkg\analyzer_cli\bin\analyzer.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/dartanalyzer_java b/sdk/bin/dartanalyzer_java
deleted file mode 100755
index d2839b5..0000000
--- a/sdk/bin/dartanalyzer_java
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This file is used to execute the analyzer by running the jar file.
-# It is a simple wrapper enabling us to have simpler command lines in
-# the testing infrastructure.
-set -e
-
-FOUND_BATCH=0
-for ARG in "$@"
-do
-  case $ARG in
-    -batch|--batch)
-      FOUND_BATCH=1
-      ;;
-    *)
-      ;;
-  esac
-done
-
-function follow_links() {
-  file="$1"
-  while [ -h "$file" ]; do
-    # On Mac OS, readlink -f doesn't work.
-    file="$(readlink "$file")"
-  done
-  echo "$file"
-}
-
-# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
-PROG_NAME="$(follow_links "$BASH_SOURCE")"
-
-# Handle the case where dart-sdk/bin has been symlinked to.
-BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-
-SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
-
-if [ -z "$DART_CONFIGURATION" ];
-then
-  DART_CONFIGURATION="ReleaseIA32"
-fi
-
-if [ `uname` == 'Darwin' ];
-then
-  JAR_DIR="$BIN_DIR"/../../xcodebuild/$DART_CONFIGURATION/dartanalyzer
-else
-  JAR_DIR="$BIN_DIR"/../../out/$DART_CONFIGURATION/dartanalyzer
-fi
-
-JAR_FILE="$JAR_DIR/dartanalyzer.jar"
-
-EXTRA_JVMARGS="-Xss2M "
-OS=`uname | tr "[A-Z]" "[a-z]"`
-if [ "$OS" == "darwin" ] ; then
-  # Bump up the heap on Mac VMs, some of which default to 128M or less.
-  EXTRA_JVMARGS+=" -Xmx512M -client "
-else
-  # On other architectures
-  # -batch invocations will do better with a server vm
-  # invocations for analyzing a single file do better with a client vm
-  if [ $FOUND_BATCH -eq 0 ] ; then
-    EXTRA_JVMARGS+=" -client "
-  fi
-fi
-
-exec java $EXTRA_JVMARGS -jar "$JAR_FILE" --dart-sdk "$SDK_DIR" "$@"
diff --git a/sdk/bin/dartanalyzer_java.bat b/sdk/bin/dartanalyzer_java.bat
deleted file mode 100644
index 86f47a8..0000000
--- a/sdk/bin/dartanalyzer_java.bat
+++ /dev/null
@@ -1,27 +0,0 @@
-@echo off

-rem Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

-rem for details. All rights reserved. Use of this source code is governed by a

-rem BSD-style license that can be found in the LICENSE file.

-rem 

-

-rem This file is used to execute the analyzer by running the jar file.

-rem It is a simple wrapper enabling us to have simpler command lines in

-rem the testing infrastructure.

-

-set SCRIPTPATH=%~dp0

-

-rem Does the path have a trailing slash? If so, remove it.

-if %SCRIPTPATH:~-1%==\ set SCRIPTPATH=%SCRIPTPATH:~0,-1%

-

-rem DART_CONFIGURATION defaults to ReleaseIA32

-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32

-

-set arguments=%*

-

-set "SDK_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dart-sdk"

-

-set "JAR_DIR=%SCRIPTPATH%\..\..\build\%DART_CONFIGURATION%\dartanalyzer"

-

-set "JAR_FILE=%JAR_DIR%\dartanalyzer.jar"

-

-java -jar "%JAR_FILE%" --dart-sdk "%SDK_DIR%" %arguments%

diff --git a/sdk/bin/dartfmt b/sdk/bin/dartfmt
index e4de89c..bc53f36 100755
--- a/sdk/bin/dartfmt
+++ b/sdk/bin/dartfmt
@@ -30,7 +30,7 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseIA32"
+  DART_CONFIGURATION="ReleaseX64"
 fi
 
 if [[ `uname` == 'Darwin' ]]; then
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index 5613b3a..321efe5 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -27,8 +27,8 @@
 
 set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart
 
-rem DART_CONFIGURATION defaults to ReleaseIA32
-if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseIA32
+rem DART_CONFIGURATION defaults to ReleaseX64
+if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
 
 set BUILD_DIR=%DART_ROOT%\build\%DART_CONFIGURATION%
 
diff --git a/sdk/bin/pub b/sdk/bin/pub
index e927731..a03070e 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -37,7 +37,7 @@
 
 if [ -z "$DART_CONFIGURATION" ];
 then
-  DART_CONFIGURATION="ReleaseIA32"
+  DART_CONFIGURATION="ReleaseX64"
 fi
 
 if [[ `uname` == 'Darwin' ]];
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 1326b57..06ba5f3 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -30,7 +30,7 @@
 
 rem Use the Dart binary in the built SDK so pub can find the version file next
 rem to it.
-set BUILD_DIR=%SDK_DIR%\..\build\ReleaseIA32
+set BUILD_DIR=%SDK_DIR%\..\build\ReleaseX64
 set PACKAGES_DIR=%BUILD_DIR%\packages
 set DART=%BUILD_DIR%\dart-sdk\bin\dart
 
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index 003f2696..d56f946 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -46,6 +46,12 @@
 }
 
 @patch
+_postEvent(String eventKind, String eventData) {
+  // TODO.
+}
+
+
+@patch
 int _getTraceClock() {
   // TODO.
   return _clockValue++;
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 23f4708..350ab96 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -233,6 +233,10 @@
     throw new UnsupportedError("Platform._packageRoot");
   }
   @patch
+  static String _packageConfig() {
+    throw new UnsupportedError("Platform._packageConfig");
+  }
+  @patch
   static _environment() {
     throw new UnsupportedError("Platform._environment");
   }
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index f27b34d..68dbbc0 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -95,11 +95,6 @@
         errorCallback = null,
         state = STATE_WHENCOMPLETE;
 
-  _FutureListener.chain(this.result)
-      : callback = null,
-        errorCallback = null,
-        state = STATE_CHAIN;
-
   Zone get _zone => result._zone;
 
   bool get handlesValue => (state & MASK_VALUE != 0);
@@ -133,8 +128,7 @@
   static const int _PENDING_COMPLETE = 1;
   /// The future has been chained to another future. The result of that
   /// other future becomes the result of this future as well.
-  // TODO(floitsch): we don't really need a special "_CHAINED" state. We could
-  // just use the PENDING_COMPLETE state instead.
+  /// [resultOrListeners] contains the source future.
   static const int _CHAINED = 2;
   /// The future has been completed with a value result.
   static const int _VALUE = 4;
@@ -167,11 +161,6 @@
    * is waiting for the other future to complete, and when it does, this future
    * will complete with the same result.
    * All listeners are forwarded to the other future.
-   *
-   * The cases are disjoint - incomplete and unchained ([_INCOMPLETE]),
-   * incomplete and chained ([_CHAINED]), or completed with value or error
-   * ([_VALUE] or [_ERROR]) - so the field only needs to hold
-   * one value at a time.
    */
   var _resultOrListeners;
 
@@ -189,14 +178,15 @@
 
   bool get _mayComplete       => _state == _INCOMPLETE;
   bool get _isPendingComplete => _state == _PENDING_COMPLETE;
+  bool get _mayAddListener    => _state <= _PENDING_COMPLETE;
   bool get _isChained         => _state == _CHAINED;
   bool get _isComplete        => _state >= _VALUE;
-  bool get _hasValue          => _state == _VALUE;
   bool get _hasError          => _state == _ERROR;
 
-  void _setChained() {
-    assert(!_isComplete);
+  void _setChained(_Future source) {
+    assert(_mayAddListener);
     _state = _CHAINED;
+    _resultOrListeners = source;
   }
 
   Future then(f(T value), { Function onError }) {
@@ -238,18 +228,18 @@
 
   Stream<T> asStream() => new Stream<T>.fromFuture(this);
 
-  void _markPendingCompletion() {
-    if (!_mayComplete) throw new StateError("Future already completed");
+  void _setPendingComplete() {
+    assert(_mayComplete);
     _state = _PENDING_COMPLETE;
   }
 
-  T get _value {
-    assert(_isComplete && _hasValue);
+  AsyncError get _error {
+    assert(_hasError);
     return _resultOrListeners;
   }
 
-  AsyncError get _error {
-    assert(_isComplete && _hasError);
+  _Future get _chainSource {
+    assert(_isChained);
     return _resultOrListeners;
   }
 
@@ -270,16 +260,70 @@
     _setErrorObject(new AsyncError(error, stackTrace));
   }
 
+  /// Copy the completion result of [source] into this future.
+  ///
+  /// Used when a chained future notices that its source is completed.
+  void _cloneResult(_Future source) {
+    assert(!_isComplete);
+    assert(source._isComplete);
+    _state = source._state;
+    _resultOrListeners = source._resultOrListeners;
+  }
+
   void _addListener(_FutureListener listener) {
     assert(listener._nextListener == null);
-    if (_isComplete) {
+    if (_mayAddListener) {
+      listener._nextListener = _resultOrListeners;
+      _resultOrListeners = listener;
+    } else {
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._addListener(listener);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
       // Handle late listeners asynchronously.
       _zone.scheduleMicrotask(() {
         _propagateToListeners(this, listener);
       });
+    }
+  }
+
+  void _prependListeners(_FutureListener listeners) {
+    if (listeners == null) return;
+    if (_mayAddListener) {
+      _FutureListener existingListeners = _resultOrListeners;
+      _resultOrListeners = listeners;
+      if (existingListeners != null) {
+        _FutureListener cursor = listeners;
+        while (cursor._nextListener != null) {
+          cursor = cursor._nextListener;
+        }
+        cursor._nextListener = existingListeners;
+      }
     } else {
-      listener._nextListener = _resultOrListeners;
-      _resultOrListeners = listener;
+      if (_isChained) {
+        // Delegate listeners to chained source future.
+        // If the source is complete, instead copy its values and
+        // drop the chaining.
+        _Future source = _chainSource;
+        if (!source._isComplete) {
+          source._prependListeners(listeners);
+          return;
+        }
+        _cloneResult(source);
+      }
+      assert(_isComplete);
+      listeners = _reverseListeners(listeners);
+      _zone.scheduleMicrotask(() {
+        _propagateToListeners(this, listeners);
+      });
     }
   }
 
@@ -289,7 +333,12 @@
     assert(!_isComplete);
     _FutureListener current = _resultOrListeners;
     _resultOrListeners = null;
+    return _reverseListeners(current);
+  }
+
+  _FutureListener _reverseListeners(_FutureListener listeners) {
     _FutureListener prev = null;
+    _FutureListener current = listeners;
     while (current != null) {
       _FutureListener next = current._nextListener;
       current._nextListener = prev;
@@ -308,10 +357,10 @@
     assert(source is! _Future);
 
     // Mark the target as chained (and as such half-completed).
-    target._setChained();
+    target._setPendingComplete();
     try {
       source.then((value) {
-          assert(target._isChained);
+          assert(target._isPendingComplete);
           target._completeWithValue(value);
         },
         // TODO(floitsch): eventually we would like to make this non-optional
@@ -319,7 +368,7 @@
         // the target future's listeners want to have the stack trace we don't
         // need a trace.
         onError: (error, [stackTrace]) {
-          assert(target._isChained);
+          assert(target._isPendingComplete);
           target._completeError(error, stackTrace);
         });
     } catch (e, s) {
@@ -336,16 +385,18 @@
   // Take the value (when completed) of source and complete target with that
   // value (or error). This function expects that source is a _Future.
   static void _chainCoreFuture(_Future source, _Future target) {
-    assert(!target._isComplete);
-    assert(source is _Future);
-
-    // Mark the target as chained (and as such half-completed).
-    target._setChained();
-    _FutureListener listener = new _FutureListener.chain(target);
+    assert(target._mayAddListener);  // Not completed, not already chained.
+    while (source._isChained) {
+      source = source._chainSource;
+    }
     if (source._isComplete) {
-      _propagateToListeners(source, listener);
+      _FutureListener listeners = target._removeListeners();
+      target._cloneResult(source);
+      _propagateToListeners(target, listeners);
     } else {
-      source._addListener(listener);
+      _FutureListener listeners = target._resultOrListeners;
+      target._setChained(source);
+      source._prependListeners(listeners);
     }
   }
 
@@ -404,7 +455,7 @@
         if (coreFuture._hasError) {
           // Case 1 from above. Delay completion to enable the user to register
           // callbacks.
-          _markPendingCompletion();
+          _setPendingComplete();
           _zone.scheduleMicrotask(() {
             _chainCoreFuture(coreFuture, this);
           });
@@ -420,9 +471,10 @@
       return;
     } else {
       T typedValue = value;
+      assert(typedValue is T);  // Avoid warning that typedValue is unused.
     }
 
-    _markPendingCompletion();
+    _setPendingComplete();
     _zone.scheduleMicrotask(() {
       _completeWithValue(value);
     });
@@ -431,7 +483,7 @@
   void _asyncCompleteError(error, StackTrace stackTrace) {
     assert(!_isComplete);
 
-    _markPendingCompletion();
+    _setPendingComplete();
     _zone.scheduleMicrotask(() {
       _completeError(error, stackTrace);
     });
@@ -463,11 +515,15 @@
         _propagateToListeners(source, listener);
       }
       _FutureListener listener = listeners;
+      final sourceResult = source._resultOrListeners;
       // Do the actual propagation.
       // Set initial state of listenerHasError and listenerValueOrError. These
       // variables are updated with the outcome of potential callbacks.
+      // Non-error results, including futures, are stored in
+      // listenerValueOrError and listenerHasError is set to false. Errors
+      // are stored in listenerValueOrError as an [AsyncError] and
+      // listenerHasError is set to true.
       bool listenerHasError = hasError;
-      final sourceResult = source._resultOrListeners;
       var listenerValueOrError = sourceResult;
 
       // Only if we either have an error or callbacks, go into this, somewhat
@@ -598,10 +654,9 @@
           _Future result = listener.result;
           if (chainSource is _Future) {
             if (chainSource._isComplete) {
-              // propagate the value (simulating a tail call).
-              result._setChained();
+              listeners = result._removeListeners();
+              result._cloneResult(chainSource);
               source = chainSource;
-              listeners = new _FutureListener.chain(result);
               continue;
             } else {
               _chainCoreFuture(chainSource, result);
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index dff5b18..e3f3aa4 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -313,9 +313,17 @@
    * Creates a new stream that converts each element of this stream
    * to a new value using the [convert] function.
    *
+   * For each data event, `o`, in this stream, the returned stream
+   * provides a data event with the value `convert(o)`.
+   * If [convert] throws, the returned stream reports the exception as an error
+   * event instead.
+   *
+   * Error and done events are passed through unchanged to the returned stream.
+   *
    * The returned stream is a broadcast stream if this stream is.
+   * The [convert] function is called once per data event per listener.
    * If a broadcast stream is listened to more than once, each subscription
-   * will individually execute `map` for each event.
+   * will individually call [convert] on each data event.
    */
   Stream/*<S>*/ map/*<S>*/(/*=S*/ convert(T event)) {
     return new _MapStream<T, dynamic/*=S*/>(this, convert);
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index 722819c..435c50d 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -13,7 +13,6 @@
 
 import 'dart:async';
 import 'dart:convert';
-import 'dart:isolate' show SendPort;
 
 part 'extension.dart';
 part 'profiler.dart';
diff --git a/sdk/lib/developer/extension.dart b/sdk/lib/developer/extension.dart
index 05eeae7..309dca2 100644
--- a/sdk/lib/developer/extension.dart
+++ b/sdk/lib/developer/extension.dart
@@ -81,13 +81,17 @@
 ///
 /// Must complete to a [ServiceExtensionResponse].
 ///
-/// [method] - the method name.
-/// [parameters] - the parameters.
+/// [method] - the method name of the service protocol request.
+/// [parameters] - A map holding the parameters to the service protocol request.
+///
+/// *NOTE*: All parameter names and values are **encoded as strings**.
 typedef Future<ServiceExtensionResponse>
-    ServiceExtensionHandler(String method, Map parameters);
+    ServiceExtensionHandler(String method, Map<String, String> parameters);
 
 /// Register a [ServiceExtensionHandler] that will be invoked in this isolate
-/// for [method].
+/// for [method]. *NOTE*: Service protocol extensions must be registered
+/// in each isolate and users of extensions must always specify a target
+/// isolate.
 void registerExtension(String method, ServiceExtensionHandler handler) {
   if (method is! String) {
     throw new ArgumentError.value(method,
@@ -105,6 +109,25 @@
   _registerExtension(method, handler);
 }
 
+/// Post an event of [eventKind] with payload of [eventData] to the `Extension`
+/// event stream.
+void postEvent(String eventKind, Map eventData) {
+  if (eventKind is! String) {
+    throw new ArgumentError.value(eventKind,
+                                  'eventKind',
+                                  'Must be a String');
+  }
+  if (eventData is! Map) {
+    throw new ArgumentError.value(eventData,
+                                  'eventData',
+                                  'Must be a Map');
+  }
+  String eventDataAsString = JSON.encode(eventData);
+  _postEvent(eventKind, eventDataAsString);
+}
+
+external _postEvent(String eventKind, String eventData);
+
 // Both of these functions are written inside C++ to avoid updating the data
 // structures in Dart, getting an OOB, and observing stale state. Do not move
 // these into Dart code unless you can ensure that the operations will can be
@@ -112,80 +135,3 @@
 // LookupServiceExtensionHandler and RegisterServiceExtensionHandler.
 external ServiceExtensionHandler _lookupExtension(String method);
 external _registerExtension(String method, ServiceExtensionHandler handler);
-
-// This code is only invoked when there is no other Dart code on the stack.
-_runExtension(ServiceExtensionHandler handler,
-              String method,
-              List<String> parameterKeys,
-              List<String> parameterValues,
-              SendPort replyPort,
-              Object id) {
-  var parameters = {};
-  for (var i = 0; i < parameterKeys.length; i++) {
-    parameters[parameterKeys[i]] = parameterValues[i];
-  }
-  var response;
-  try {
-    response = handler(method, parameters);
-  } catch (e, st) {
-    var errorDetails = (st == null) ? '$e' : '$e\n$st';
-    response = new ServiceExtensionResponse.error(
-        ServiceExtensionResponse.kExtensionError,
-        errorDetails);
-    _postResponse(replyPort, id, response);
-    return;
-  }
-  if (response is! Future) {
-    response = new ServiceExtensionResponse.error(
-          ServiceExtensionResponse.kExtensionError,
-          "Extension handler must return a Future");
-    _postResponse(replyPort, id, response);
-    return;
-  }
-  response.catchError((e, st) {
-    // Catch any errors eagerly and wrap them in a ServiceExtensionResponse.
-    var errorDetails = (st == null) ? '$e' : '$e\n$st';
-    return new ServiceExtensionResponse.error(
-        ServiceExtensionResponse.kExtensionError,
-        errorDetails);
-  }).then((response) {
-    // Post the valid response or the wrapped error after verifying that
-    // the response is a ServiceExtensionResponse.
-    if (response is! ServiceExtensionResponse) {
-      response = new ServiceExtensionResponse.error(
-          ServiceExtensionResponse.kExtensionError,
-          "Extension handler must complete to a ServiceExtensionResponse");
-    }
-    _postResponse(replyPort, id, response);
-  }).catchError((e, st) {
-    // We do not expect any errors to occur in the .then or .catchError blocks
-    // but, suppress them just in case.
-  });
-}
-
-// This code is only invoked by _runExtension.
-_postResponse(SendPort replyPort,
-              Object id,
-              ServiceExtensionResponse response) {
-  assert(replyPort != null);
-  if (id == null) {
-    // No id -> no response.
-    replyPort.send(null);
-    return;
-  }
-  assert(id != null);
-  StringBuffer sb = new StringBuffer();
-  sb.write('{"jsonrpc":"2.0",');
-  if (response._isError()) {
-    sb.write('"error":');
-  } else {
-    sb.write('"result":');
-  }
-  sb.write('${response._toString()},');
-  if (id is String) {
-    sb.write('"id":"$id"}');
-  } else {
-    sb.write('"id":$id}');
-  }
-  replyPort.send(sb.toString());
-}
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index 2d6719d..b1c05a0 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -5,20 +5,27 @@
 part of dart.io;
 
 /**
- * Helper class to wrap a [StreamConsumer<List<int>>] and provide
- * utility functions for writing to the StreamConsumer directly. The
- * [IOSink] buffers the input given by all [StringSink] methods and will delay
- * an [addStream] until the buffer is flushed.
+ * A combined byte and text output.
  *
- * When the [IOSink] is bound to a stream (through [addStream]) any call
- * to the [IOSink] will throw a [StateError]. When the [addStream] completes,
- * the [IOSink] will again be open for all calls.
+ * An [IOSink] combines a [StreamSink] of bytes with a [StringSink],
+ * and allows easy output of both bytes and text.
+ *
+ * Writing text ([write]) and adding bytes ([add]) may be interleaved freely.
+ *
+ * While a stream is being added using [addStream], any further attempts
+ * to add or write to the [IOSink] will fail until the [addStream] completes.
  *
  * If data is added to the [IOSink] after the sink is closed, the data will be
  * ignored. Use the [done] future to be notified when the [IOSink] is closed.
  */
 abstract class IOSink implements StreamSink<List<int>>, StringSink {
-  // TODO(ajohnsen): Make _encodingMutable an argument.
+
+  /**
+   * Create an [IOSink] that outputs to a [target] [StreamConsumer] of bytes.
+   *
+   * Text written to [StreamSink] methods is encoded to bytes using [encoding]
+   * before being output on [target].
+   */
   factory IOSink(StreamConsumer<List<int>> target,
                  {Encoding encoding: UTF8})
       => new _IOSinkImpl(target, encoding);
@@ -30,7 +37,7 @@
   Encoding encoding;
 
   /**
-   * Adds [data] to the target consumer, ignoring [encoding].
+   * Adds byte [data] to the target consumer, ignoring [encoding].
    *
    * The [encoding] does not apply to this method, and the `data` list is passed
    * directly to the target consumer as a stream event.
@@ -58,7 +65,7 @@
    * Iterates over the given [objects] and [write]s them in sequence.
    *
    * If [separator] is provided, a `write` with the `separator` is performed
-   * between any two elements of `objects`.
+   * between any two elements of objects`.
    *
    * This operation is non-blocking. See [flush] or [done] for how to get any
    * errors generated by this call.
@@ -75,7 +82,7 @@
   void writeln([Object obj = ""]);
 
   /**
-   * Writes the [charCode] to `this`.
+   * Writes the character of [charCode].
    *
    * This method is equivalent to `write(new String.fromCharCode(charCode))`.
    *
@@ -107,7 +114,7 @@
    * Returns a [Future] that completes once all buffered data is accepted by the
    * to underlying [StreamConsumer].
    *
-   * It's an error to call this method, while an [addStream] is incomplete.
+   * This method must not be called while an [addStream] is incomplete.
    *
    * NOTE: This is not necessarily the same as the data being flushed by the
    * operating system.
@@ -129,17 +136,14 @@
 
 class _StreamSinkImpl<T> implements StreamSink<T> {
   final StreamConsumer<T> _target;
-  Completer _doneCompleter = new Completer();
-  Future _doneFuture;
+  final Completer _doneCompleter = new Completer();
   StreamController<T> _controllerInstance;
   Completer _controllerCompleter;
   bool _isClosed = false;
   bool _isBound = false;
   bool _hasError = false;
 
-  _StreamSinkImpl(this._target) {
-    _doneFuture = _doneCompleter.future;
-  }
+  _StreamSinkImpl(this._target);
 
   void add(T data) {
     if (_isClosed) return;
@@ -180,8 +184,8 @@
     var future = _controllerCompleter.future;
     _controllerInstance.close();
     return future.whenComplete(() {
-          _isBound = false;
-        });
+      _isBound = false;
+    });
   }
 
   Future close() {
@@ -203,19 +207,19 @@
     _target.close().then(_completeDoneValue, onError: _completeDoneError);
   }
 
-  Future get done => _doneFuture;
+  Future get done => _doneCompleter.future;
 
   void _completeDoneValue(value) {
-    if (_doneCompleter == null) return;
-    _doneCompleter.complete(value);
-    _doneCompleter = null;
+    if (!_doneCompleter.isCompleted) {
+      _doneCompleter.complete(value);
+    }
   }
 
   void _completeDoneError(error, StackTrace stackTrace) {
-    if (_doneCompleter == null) return;
-    _hasError = true;
-    _doneCompleter.completeError(error, stackTrace);
-    _doneCompleter = null;
+    if (!_doneCompleter.isCompleted) {
+      _hasError = true;
+      _doneCompleter.completeError(error, stackTrace);
+    }
   }
 
   StreamController<T> get _controller {
@@ -228,32 +232,29 @@
     if (_controllerInstance == null) {
       _controllerInstance = new StreamController<T>(sync: true);
       _controllerCompleter = new Completer();
-      _target.addStream(_controller.stream)
-          .then(
-              (_) {
-                if (_isBound) {
-                  // A new stream takes over - forward values to that stream.
-                  _controllerCompleter.complete(this);
-                  _controllerCompleter = null;
-                  _controllerInstance = null;
-                } else {
-                  // No new stream, .close was called. Close _target.
-                  _closeTarget();
-                }
-              },
-              onError: (error, stackTrace) {
-                if (_isBound) {
-                  // A new stream takes over - forward errors to that stream.
-                  _controllerCompleter.completeError(error, stackTrace);
-                  _controllerCompleter = null;
-                  _controllerInstance = null;
-                } else {
-                  // No new stream. No need to close target, as it have already
-                  // failed.
-                  _completeDoneError(error, stackTrace);
-                }
-              });
-    }
+      _target.addStream(_controller.stream).then((_) {
+        if (_isBound) {
+          // A new stream takes over - forward values to that stream.
+          _controllerCompleter.complete(this);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream, .close was called. Close _target.
+          _closeTarget();
+        }
+      }, onError: (error, stackTrace) {
+        if (_isBound) {
+          // A new stream takes over - forward errors to that stream.
+          _controllerCompleter.completeError(error, stackTrace);
+          _controllerCompleter = null;
+          _controllerInstance = null;
+        } else {
+          // No new stream. No need to close target, as it has already
+          // failed.
+          _completeDoneError(error, stackTrace);
+        }
+      });
+   }
     return _controllerInstance;
   }
 }
@@ -297,8 +298,8 @@
     }
   }
 
-  void writeln([Object obj = ""]) {
-    write(obj);
+  void writeln([Object object = ""]) {
+    write(object);
     write("\n");
   }
 
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index c9e1cc6..7cd20a1 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -185,10 +185,19 @@
    * used to run the script in this isolate.  This is the directory in which
    * Dart packages are looked up.
    *
-   * If there is no --package-root flag, then the empty string is returned.
+   * If there is no --package-root flag, then null is returned.
    */
   static String get packageRoot => _Platform.packageRoot;
 
+/**
+ * Returns the value of the --packages flag passed to the executable
+ * used to run the script in this isolate.  This is the configuration which
+ * specifies how Dart packages are looked up.
+ *
+ * If there is no --packages flag, then the null is returned.
+ */
+  static String get packageConfig => _Platform.packageConfig;
+
   /**
    * Returns the version of the current Dart runtime.
    *
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index 6380e0d..f4d7a24 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -29,11 +29,13 @@
   external static _environment();
   external static List<String> _executableArguments();
   external static String _packageRoot();
+  external static String _packageConfig();
   external static String _version();
 
   static String executable = _executable();
   static String resolvedExecutable = _resolvedExecutable();
   static String packageRoot = _packageRoot();
+  static String packageConfig = _packageConfig();
 
   // Cache the OS environemnt. This can be an OSError instance if
   // retrieving the environment failed.
diff --git a/site/try/build_try.gyp b/site/try/build_try.gyp
index ae1125b..c421c85 100644
--- a/site/try/build_try.gyp
+++ b/site/try/build_try.gyp
@@ -33,10 +33,6 @@
           'dart-iphone5.png', # iPhone 5 splash screen.
           'dart-icon-196px.png', # Android icon.
           'try-dart-screenshot.png', # Google+ screen shot.
-
-          '../../third_party/font-awesome/font-awesome-4.0.3/'
-          'fonts/fontawesome-webfont.woff',
-
           'favicon.ico',
 
           '<(SHARED_INTERMEDIATE_DIR)/leap.dart.js',
diff --git a/site/try/index.html b/site/try/index.html
index 5e05395..9b318d2 100644
--- a/site/try/index.html
+++ b/site/try/index.html
@@ -14,7 +14,7 @@
 
 See: http://www.google.com/fonts#UsePlace:use/Collection:Open+Sans:400,600,700,800,300
 -->
-<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
+
 <link href='//fonts.googleapis.com/css?family=Open+Sans:400,600,700,800,300' rel='stylesheet' type='text/css'>
 <link rel="stylesheet" type="text/css" href="dartlang-style.css">
 <link rel="alternate stylesheet" type="text/css" href="line_numbers.css" title="line_numbers">
@@ -211,7 +211,7 @@
 <a class="brand" href="//www.dartlang.org/" title="Dart Homepage" target="_blank">
 <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAVCAMAAACeyVWkAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJxQTFRFAAAAAIvMdsvDAIvMdsvDAIvMdsvDLaTJAIvMOqnHdsvDAIvMdsvDAIvMKaLJdsvDAIvMAIvMdsvDAIvMdsvDdsvDAIvMAIvMAZnFdsvDAILHAIPHAITIAIXJAIfKAIjKAIrLAIrMAIvMAJXHAJjFC5i/I6HENr2yOb6zPr+0TsK4UsO5WbnEWcW8Xsa9Yse+Zsi/asjAc8rCdsvDdt4SRQAAABp0Uk5TABAQICAwMFBgYGBwcICAgI+vr7+/z9/v7+97IXGnAAAAqUlEQVQYV13QxxaCQBBE0VZkjBgAGVEBaVEUM/P//yaTGg5vV3dZANTCZ9BvFAoR93kVC9FnthW6uIPTJ7UkdHaXvS2LXKNBURInyDXPsShbzjU7XCpxhooDVGo5QcQAJmjUco64AY/UcIrowYCTaj5KBZeTaj5JBTc6l11OlQKMf497y1ahefFb3TQfcqtM/fipJF/X9gnDon6/ah/aDDfNOgosNA2b8QdGciZlh/U93AAAAABJRU5ErkJggg==" alt="Dart">
 </a>
-<ul class="nav pull-right"><li><a href="https://code.google.com/p/dart/issues/entry?template=Try+Dart+Bug" target="_blank"><i class="fa fa-bug"></i></a></li><li><a href="#" id="settings"><i class="icon-cog"></i></a></li></ul>
+<ul class="nav pull-right"><li><a href="https://code.google.com/p/dart/issues/entry?template=Try+Dart+Bug" target="_blank"><i></i></a></li><li><a href="#" id="settings"><i class="icon-cog"></i></a></li></ul>
 
 <ul class="nav hidden-phone">
 <li class="active"><a>Try Dart!</a></li>
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
index b9f7753..be98153 100644
--- a/site/try/poi/poi.dart
+++ b/site/try/poi/poi.dart
@@ -392,8 +392,7 @@
     api.DiagnosticHandler handler) {
   Stopwatch sw = new Stopwatch()..start();
   Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${io.Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(io.Platform.packageRoot);
 
   var options = [
       '--analyze-main',
diff --git a/tests/README b/tests/README
index a9e3bb6..bbc3ee4 100644
--- a/tests/README
+++ b/tests/README
@@ -39,5 +39,5 @@
   int x = "not an int"; /// 01: static type warning
   ...
 
-as part of a test will only pass the "--compiler dartanalyzer" test if
+as part of a test will only pass the "--compiler dart2analyzer" test if
 the assignment generates a static type warning.
diff --git a/tests/co19/co19-analyzer.status b/tests/co19/co19-analyzer.status
deleted file mode 100644
index 07a8e26..0000000
--- a/tests/co19/co19-analyzer.status
+++ /dev/null
@@ -1,293 +0,0 @@
-# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $compiler == dartanalyzer ]
-
-WebPlatformTest/html/semantics/forms/the-textarea-element/textarea-type_t01: fail
-LayoutTests/fast/forms/checkValidity-001_t01: fail
-
-# TBF: infinite look: class A {const A();final m = const A();}
-Language/Expressions/Constants/depending_on_itself_t03: fail
-
-# TBF: when we override "foo([x = 0]) {}" with "foo([x]) {}" we should report warning - different default value
-Language/Classes/Instance_Methods/override_different_default_values_t02: MissingStaticWarning
-Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingStaticWarning
-
-# TBF: Static members should not be accessible via subclasses.
-Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: MissingStaticWarning
-
-# co19 issue #442, undefined name "Expect"
-Language/Types/Interface_Types/subtype_t12: fail, OK
-
-# co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/Expressions/Constants/exception_t01: fail, OK
-Language/Expressions/Constants/exception_t02: fail, OK
-
-# co19 issue #543: invocation of a non-function
-Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: fail, OK
-
-# co19 issue #564: URI can be any number adjacent string literals
-Language/Libraries_and_Scripts/URIs/syntax_t14: fail, OK
-Language/Libraries_and_Scripts/URIs/syntax_t15: fail, OK
-
-# co19 issue #615: Expect import missing
-LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
-
-LibTest/isolate/IsolateStream/any_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/contains_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/first_A02_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isBroadcast_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isBroadcast_A01_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/isEmpty_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/last_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/last_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/length_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/single_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/single_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/call_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t04: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t05: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t06: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A03_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A03_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/any_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/IsolateStream/contains_A02_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/receive_A01_t02: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/toSendPort_A01_t02: Fail # co19-roll r706: Please triage this failure.
-
-# co19 issue 642, The argument type 'int' cannot be assigned to the parameter type 'Iterable'
-LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: Fail, OK
-LibTest/collection/ListQueue/ListQueue_class_A01_t01: Fail, OK
-LibTest/collection/Queue/Queue_class_A01_t01: Fail, OK
-
-
-Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
-Language/Expressions/Assignable_Expressions/syntax_t09: MissingStaticWarning
-Language/Statements/For/For_Loop/execution_t07: MissingStaticWarning
-Language/Statements/For/For_Loop/execution_t08: MissingStaticWarning
-Language/Statements/Switch/last_statement_t03: MissingStaticWarning
-Language/Statements/Assert/type_t04: MissingStaticWarning
-
-Language/Variables/final_t04: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_t05: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_t06: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_t07: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # co19-roll r651: Please triage this failure
-Language/Expressions/Function_Invocation/Unqualified_Invocation/invocation_t18: MissingCompileTimeError # co19-roll r651: Please triage this failure
-
-Language/Classes/Superinterfaces/no_member_A07_t05: StaticWarning # co19-roll r667: Please triage this failure
-LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # co19-roll r667: Please triage this failure
-
-# co19 issue 656
-LibTest/typed_data/Float32x4/equal_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/notEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/greaterThanOrEqual_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
-LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
-
-WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
-
-# co19 roll to r706: Please triage all these issues.
-Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # co19-roll r706: Please triage this failure.
-Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # co19-roll r706: Please triage this failure.
-Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Parts/compilation_t04: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Parts/static_warning_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-Language/Libraries_and_Scripts/Scripts/syntax_t11: CompileTimeError # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/DOMImplementation/createDocumentType-err_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-zoom-and-scroll_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/dom/Element/scrollWidth_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/article-element_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/aside-element_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-LayoutTests/fast/html/text-field-input-types_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/adoptNode_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/childNodes_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/importNode_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Document/securityPolicy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/HttpRequest/responseText_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/HttpRequest/responseType_A01_t03: CompileTimeError # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/attributeChanged_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/contentWindow_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/enteredView_A01_t01: CompileTimeError # co19-roll r706: Please triage this failure.
-LibTest/html/IFrameElement/getNamespacedAttributes_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/document_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveBy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveTo_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/moveTo_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/postMessage_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/postMessage_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A01_t02: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/requestFileSystem_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/resizeBy_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/html/Window/resizeTo_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/isolate/ReceivePort/sendPort_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_addition_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_mult_A03_t01: StaticWarning # co19-roll r706: Please triage this failure.
-LibTest/math/Point/operator_subtraction_A02_t01: StaticWarning # co19-roll r706: Please triage this failure.
-WebPlatformTest/dom/events/event_constants/constants_A01_t01: StaticWarning # co19-roll r706: Please triage this failure.
-
-# co19-roll r722
-LayoutTests/fast/dom/HTMLAnchorElement/anchor-ismap-crash_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLAnchorElement/set-href-attribute-rebase_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLBaseElement/href-attribute-resolves-with-respect-to-document_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-does-not-match-disabled-selector_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDocument/clone-node_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLInputElement/size-attribute_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/label-control_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/IFrameElement/outerHtml_setter_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/childNodes_A01_t02: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/contains_A01_t02: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/dispatchEvent_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/Node/nodes_A01_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/isURLAttribute_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-async-attr_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: StaticWarning
-LayoutTests/fast/dom/HTMLTableElement/createCaption_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/inertContents_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTemplateElement/no-form-association_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/clear-transient-without-delivery_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/disconnect-cancel-pending_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/document-fragment-insertion_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/mutation-record-constructor_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/MutationObserver/observe-exceptions_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/NodeList/nodelist-reachable_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/missing-arguments_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/Range/surroundContents-check-boundary-points_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LayoutTests/fast/html/imports/import-element-removed-flag_t01: StaticWarning # co19-roll r722: Please triage this failure.
-LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/collections/emptyName_A01_t03: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createDocument_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/DOMImplementation-createHTMLDocument_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement-namespace_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Document-createElement_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Element-childElementCount-nochild_t01: CompileTimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-appendChild_t02: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-contains_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-isEqualNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
-WebPlatformTest/dom/nodes/Node-parentNode_t01: StaticWarning # co19-roll r722: Please triage this failure.
-
-# co19-roll r738
-Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingStaticWarning # co19-roll r738: Please triage this failure.
-Language/Classes/method_definition_t06: MissingStaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/atob-btoa_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/replaceable_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/Window/window-scroll-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/characterdata-api-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-cached-import-rule_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-insert-import-rule-twice_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-insert-import-rule_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-deleteRule-update_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-functions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-mediarule-insertRule-update_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/css-rule-functions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/destroy-selected-radio-button-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/icon-url-change_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/icon-url-list_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/implementation-api-args_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/javascript-backslash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/location-missing-arguments_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/option-properties_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/remove-named-attribute-crash_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/content-pseudo-element-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/content-pseudo-element-relative-selector-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-context-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/host-pseudo-class-css-text_t01: StaticWarning # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/Event.bubbles.false_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.head_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/documents/dom-tree-accessors/document.title_t07: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-delete_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-get_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/document-metadata/styling/LinkStyle_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/embedded-content/the-audio-element/audio_constructor_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-datalist-element/datalistelement_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: StaticWarning # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-fieldset-element/disabled_t01: StaticWarning # co19-roll r738: Please triage this failure.
-
-# co19-roll r761
-LayoutTests/fast/animation/request-animation-frame-missing-arguments_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/backgrounds/001_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: StaticWarning # Issue 20939
-LayoutTests/fast/canvas/canvas-createImageBitmap-animated_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/dom/text-api-arguments_t01: StaticWarning # co19-roll r761: Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: StaticWarning # co19-roll r761: Please triage this failure.
-
-# co19-roll r786
-LayoutTests/fast/events/initkeyboardevent-crash_t01: StaticWarning # co19-roll r786: Please triage this failure.
-
-# co19-roll r801
-LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/inline/boundingBox-with-continuation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/about-blank-hash-kept_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/hashchange-event-properties_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/media-query-list-syntax_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-append-delete_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-color-index_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-js-media-except_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-js-media-except_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/media/mq-parsing_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/mediastream/RTCPeerConnection-AddRemoveStream_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/float-truncation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/float-truncation_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/overflow/scroll-vertical-not-horizontal_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/ruby/after-doesnt-crash_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t01: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-image-margin_t02: StaticWarning # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: StaticWarning # co19-roll r801: Please triage this failure.
-
-LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t01: StaticWarning # co19 issue 703
-WebPlatformTest/dom/Node-replaceChild_t01: CompileTimeError # co19-roll r761: Please triage this failure.
-WebPlatformTest/html/semantics/forms/the-input-element/email_t02: StaticWarning # co19 issue 701
-Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22010
-Language/Expressions/Instance_Creation/Const/abstract_class_t03: MissingCompileTimeError # Issue 22010
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 3c1347e..e9249bd 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -32,7 +32,7 @@
 # These tests are broken in both Javascript and Dart (co19 folks contacted to fix).
 WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004_t01: Skip # Issue 21115
 
-[ $compiler != dartanalyzer && $compiler != dart2analyzer ]
+[ $compiler != dart2analyzer ]
 # Tests that fail on every runtime, but not on the analyzer.
 
 LibTest/async/Future/Future.error_A01_t01: RuntimeError # co19 issue 712
@@ -93,7 +93,7 @@
 
 ### CHECKED MODE FAILURES ###
 
-[ $compiler != dartanalyzer && $compiler != dart2analyzer && $checked ]
+[ $compiler != dart2analyzer && $checked ]
 LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
 LibTest/collection/LinkedList/lastWhere_A02_t01: RuntimeError # co19 issue 737
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f17ea2f..64cea7e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -134,8 +134,8 @@
 Language/Statements/Local_Function_Declaration/reference_before_declaration_t01: MissingCompileTimeError # Issue 21050
 Language/Statements/Local_Function_Declaration/reference_before_declaration_t03: MissingCompileTimeError # Issue 21050
 Language/Types/Interface_Types/subtype_t27: Skip # Times out or crashes. Issue 21174
-Language/Types/Interface_Types/subtype_t28: crash # Issue 21174
 Language/Types/Interface_Types/subtype_t30: fail # Issue 14654
+Language/Types/Interface_Types/subtype_t28: Pass, Fail # Stack overflow. Issue 25282
 Language/Variables/final_t01: fail # Issue 21093
 Language/Variables/final_t02: fail # Issue 21093
 Language/Variables/local_variable_t01: MissingCompileTimeError # Issue 21050
@@ -434,7 +434,7 @@
 LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
-LayoutTests/fast/forms/form-submission-create-crash_t01.dart: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 4062b0e..465668d 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -409,7 +409,7 @@
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/form-submission-create-crash_t01.dart: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/formmethod-attribute-input-2_t01: Skip # Test reloads itself. Issue 18558.
diff --git a/tests/compiler/dart2js/analyze_all_test.dart b/tests/compiler/dart2js/analyze_all_test.dart
index 2bb4808..7039f93 100644
--- a/tests/compiler/dart2js/analyze_all_test.dart
+++ b/tests/compiler/dart2js/analyze_all_test.dart
@@ -2,9 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import "package:expect/expect.dart";
-import "compiler_helper.dart";
-import "package:async_helper/async_helper.dart";
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
 
 const String SOURCE = """
 class Foo {
@@ -27,32 +30,85 @@
 }
 """;
 
+Future<DiagnosticCollector> run(
+    String source,
+    {bool analyzeAll,
+     bool expectSuccess}) async {
+  DiagnosticCollector collector = new DiagnosticCollector();
+
+  List<String> options = [];
+  if (analyzeAll) {
+    options.add(Flags.analyzeAll);
+  } else {
+    options.add(Flags.analyzeOnly);
+  }
+  CompilationResult result = await runCompiler(
+      memorySourceFiles: {'main.dart': source},
+      diagnosticHandler: collector,
+      options: options);
+  Expect.equals(expectSuccess, result.isSuccess);
+  return collector;
+}
+
+test1() async {
+  DiagnosticCollector collector =
+      await run(SOURCE, analyzeAll: false, expectSuccess: true);
+  Expect.isTrue(collector.warnings.isEmpty,
+      'Unexpected warnings: ${collector.warnings}');
+  Expect.isTrue(collector.errors.isEmpty,
+      'Unexpected errors: ${collector.errors}');
+}
+
+test2() async {
+  DiagnosticCollector collector =
+      await run(SOURCE, analyzeAll: true, expectSuccess: false);
+
+  Expect.isTrue(collector.warnings.isEmpty,
+                'unexpected warnings: ${collector.warnings}');
+  Expect.equals(2, collector.errors.length,
+                'expected exactly two errors, but got ${collector.errors}');
+
+  CollectedMessage first = collector.errors.first;
+  Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, first.message.kind);
+  Expect.equals("Foo", SOURCE.substring(first.begin, first.end));
+
+  CollectedMessage second = collector.errors.elementAt(1);
+  Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, second.message.kind);
+  Expect.equals("Foo", SOURCE.substring(second.begin, second.end));
+}
+
+// This is a regression test, testing that we can handle annotations on
+// malformed elements. Depending on the order of analysis, annotations on such
+// elements might not be resolved which caused a crash when trying to detect
+// a `@NoInline()` annotation.
+test3() async {
+  String source = '''
+import 'package:expect/expect.dart';
+
+class A {
+  @NoInline
+  m() {
+    => print(0);
+  }
+}
+
+@NoInline()
+main() => new A().m();
+''';
+
+  DiagnosticCollector collector =
+      await run(source, analyzeAll: true, expectSuccess: false);
+
+  Expect.isTrue(collector.warnings.isEmpty,
+                'unexpected warnings: ${collector.warnings}');
+  Expect.equals(1, collector.errors.length,
+                'expected exactly one error, but got ${collector.errors}');
+}
+
 main() {
-  Uri uri = Uri.parse('test:code');
-  var compiler1 = compilerFor(SOURCE, uri, analyzeAll: false);
-  asyncTest(() => compiler1.run(uri).then((compilationSucceded) {
-    DiagnosticCollector collector = compiler1.diagnosticCollector;
-    Expect.isTrue(compilationSucceded);
-    print(collector.warnings);
-    Expect.isTrue(collector.warnings.isEmpty, 'unexpected warnings');
-    Expect.isTrue(collector.errors.isEmpty, 'unexpected errors');
-  }));
-
-  var compiler2 = compilerFor(SOURCE, uri, analyzeAll: true);
-  asyncTest(() => compiler2.run(uri).then((compilationSucceded) {
-    DiagnosticCollector collector = compiler2.diagnosticCollector;
-    Expect.isFalse(compilationSucceded);
-    Expect.isTrue(collector.warnings.isEmpty,
-                  'unexpected warnings: ${collector.warnings}');
-    Expect.equals(2, collector.errors.length,
-                  'expected exactly two errors, but got ${collector.errors}');
-
-    CollectedMessage first = collector.errors.first;
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, first.message.kind);
-    Expect.equals("Foo", SOURCE.substring(first.begin, first.end));
-
-    CollectedMessage second = collector.errors.elementAt(1);
-    Expect.equals(MessageKind.CONSTRUCTOR_IS_NOT_CONST, second.message.kind);
-    Expect.equals("Foo", SOURCE.substring(second.begin, second.end));
-  }));
+  asyncTest(() async {
+    await test1();
+    await test2();
+    await test3();
+  });
 }
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index 2d6b604..ef6439d 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -154,7 +154,7 @@
 
   var libraryRoot = currentDirectory.resolve('sdk/');
   var packageRoot =
-      currentDirectory.resolveUri(new Uri.file('${Platform.packageRoot}/'));
+      currentDirectory.resolve(Platform.packageRoot);
   var provider = new CompilerSourceFileProvider();
   var handler = new CollectingDiagnosticHandler(whiteList, provider);
   var options = <String>[Flags.analyzeOnly, '--categories=Client,Server',
diff --git a/tests/compiler/dart2js/benign_error_test.dart b/tests/compiler/dart2js/benign_error_test.dart
new file mode 100644
index 0000000..28c84dd
--- /dev/null
+++ b/tests/compiler/dart2js/benign_error_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that benign error do not prevent compilation.
+
+import 'memory_compiler.dart';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/messages.dart';
+import 'package:compiler/src/js_backend/js_backend.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncTest(() async {
+    for (MessageKind kind in Compiler.BENIGN_ERRORS) {
+      await testExamples(kind);
+    }
+  });
+}
+
+testExamples(MessageKind kind) async {
+  MessageTemplate template = MessageTemplate.TEMPLATES[kind];
+  for (var example in template.examples) {
+    if (example is! Map) {
+      example = {'main.dart': example};
+    }
+    DiagnosticCollector collector = new DiagnosticCollector();
+    CompilationResult result = await runCompiler(
+        memorySourceFiles: example,
+        diagnosticHandler: collector);
+    Expect.isTrue(result.isSuccess);
+    Expect.isTrue(
+        collector.errors.any((message) => message.messageKind == kind));
+    Compiler compiler = result.compiler;
+    JavaScriptBackend backend = compiler.backend;
+    Expect.isNotNull(backend.generatedCode[compiler.mainFunction]);
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
index 38608d0..dc4552b 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
@@ -20,7 +20,7 @@
 """,
 r"""
 function(x) {
-  P.print(J.getInterceptor$ns(x).$add(x, "1"));
+  P.print(J.$add$ns(x, "1"));
 }"""),
 
   const TestEntry("""
@@ -37,7 +37,7 @@
 function(x) {
   var _box_0 = {}, a = new V.main_a(_box_0);
   _box_0.x = x;
-  _box_0.x = J.getInterceptor$ns(x = _box_0.x).$add(x, "1");
+  _box_0.x = J.$add$ns(_box_0.x, "1");
   P.print(a.call$0());
   return a;
 }"""),
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart
index 873afa8..27cfbae 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_gvn_test.dart
@@ -13,7 +13,8 @@
 foo(x, list) {
   var sum = 0;
   for (int k = 0; k < 10; k++) {
-    // Everything can be hoisted out, except the bounds check and sum += z.
+    // Everything can be hoisted out up to the index access which is
+    // blocked by the bounds check.
     var a = x.left.left;
     var b = x.left.right;
     var c = x.right.left;
@@ -51,10 +52,16 @@
 }
 """,r"""
 function(x, list) {
-  var v0 = x.left, a = v0.left, b = v0.right, sum = 0, k = 0, c = (v0 = x.right).left, d = v0.right, i = a.value + c.value, v1 = list[v0 = i * (b.value + d.value)];
-  for (; k < 10; sum = sum + (v1 + i), k = k + 1)
-    if (v0 < 0 || v0 >= 10)
-      return H.ioore(list, v0);
+  var v0 = x.left, a = v0.left, b = v0.right, sum = 0, k = 0, c = (v0 = x.right).left, d = v0.right, v1, v2, v3, i, v4;
+  v0 = a.value;
+  v1 = c.value;
+  v2 = b.value;
+  for (v3 = d.value; k < 10; sum = sum + (i + list[v4]), k = k + 1) {
+    i = v0 + v1;
+    v4 = i * (v2 + v3);
+    if (v4 < 0 || v4 >= 10)
+      return H.ioore(list, v4);
+  }
   return sum;
 }"""),
 ];
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 8d788f6..ce01ed0 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -115,7 +115,7 @@
   if (packageRoot == null &&
       packageConfig == null &&
       packagesDiscoveryProvider == null) {
-    packageRoot = Uri.base.resolveUri(new Uri.file('${Platform.packageRoot}/'));
+    packageRoot = Uri.base.resolve(Platform.packageRoot);
   }
 
   MemorySourceFileProvider provider;
diff --git a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
index 0aa116f..c308dae 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
@@ -24,8 +24,7 @@
 Future<MirrorSystem> analyzeUri(Uri testUri) {
   Uri repository = Platform.script.resolve('../../../../');
   Uri libraryRoot = repository.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolveUri(
-      new Uri.file('${Platform.packageRoot}/'));
+  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
   var provider = new CompilerSourceFileProvider();
   var handler = new FormattingDiagnosticHandler(provider);
   return source_mirrors.analyze(
@@ -34,4 +33,4 @@
       packageRoot,
       provider,
       handler);
-}
\ No newline at end of file
+}
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index ae06d45..11b450d 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -101,7 +101,7 @@
               trustTypeAnnotations: trustTypeAnnotations,
               trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
               diagnosticOptions:
-                  new DiagnosticOptions(showPackageWarnings: true),
+                  new DiagnosticOptions(shownPackageWarnings: const []),
               outputProvider: new LegacyCompilerOutput(outputProvider)) {
     this.disableInlining = disableInlining;
 
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/show_package_warnings_test.dart
index 6a1aa3f..cc05018 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/show_package_warnings_test.dart
@@ -20,47 +20,81 @@
 
 const SOURCE = const {
   'main.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_error2/pkg_error2.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-import 'error.dart';
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+import 'error.dart' as error;
+
+main() {
+  pkg1.m(null);
+  pkg2.m(null);
+  pkg3.m(null);
+  error.m(null);
+}
 """,
 
   'error.dart': ERROR_CODE,
 
   'pkg/pkg_error1/pkg_error1.dart': """
-import 'package:pkg_error2/pkg_error2.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-$ERROR_CODE""",
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+$ERROR_CODE
+
+main() {
+  m(null);
+  pkg2.m(null);
+  pkg3.m(null);
+}
+""",
 
   'pkg/pkg_error2/pkg_error2.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_noerror/pkg_noerror.dart';
-$ERROR_CODE""",
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_noerror/pkg_noerror.dart' as pkg3;
+$ERROR_CODE
+
+main() {
+  pkg1.m(null);
+  m(null);
+  pkg3.m(null);
+}
+""",
 
   'pkg/pkg_noerror/pkg_noerror.dart': """
-import 'package:pkg_error1/pkg_error1.dart';
-import 'package:pkg_error2/pkg_error2.dart';
+import 'package:pkg_error1/pkg_error1.dart' as pkg1;
+import 'package:pkg_error2/pkg_error2.dart' as pkg2;
+m(o) {}
+
+main() {
+  pkg1.m(null);
+  m(null);
+  pkg2.m(null);
+}
 """};
 
 Future test(Uri entryPoint,
-            {bool showPackageWarnings: false,
+            {List<String> showPackageWarnings: null,
              int warnings: 0,
              int hints: 0,
              int infos: 0}) async {
-  var options = [Flags.analyzeOnly, Flags.analyzeAll];
-  if (showPackageWarnings) {
-    options.add(Flags.showPackageWarnings);
+  var options = [Flags.analyzeOnly];
+  if (showPackageWarnings != null) {
+    if (showPackageWarnings.isEmpty) {
+      options.add(Flags.showPackageWarnings);
+    } else {
+      options.add(
+          '${Flags.showPackageWarnings}=${showPackageWarnings.join(',')}');
+    }
   }
   var collector = new DiagnosticCollector();
+  print('==================================================================');
+  print('test: $entryPoint showPackageWarnings=$showPackageWarnings');
+  print('------------------------------------------------------------------');
   await runCompiler(
       entryPoint: entryPoint,
       memorySourceFiles: SOURCE,
       options: options,
       packageRoot: Uri.parse('memory:pkg/'),
       diagnosticHandler: collector);
-  print('==================================================================');
-  print('test: $entryPoint showPackageWarnings=$showPackageWarnings');
   Expect.equals(0, collector.errors.length,
                 'Unexpected errors: ${collector.errors}');
   Expect.equals(warnings, collector.warnings.length,
@@ -72,7 +106,6 @@
   Expect.equals(infos, collector.infos.length,
                 'Unexpected infos: ${collector.infos}');
   checkUriSchemes(collector.infos);
-  print('==================================================================');
 }
 
 void checkUriSchemes(Iterable<CollectedMessage> messages) {
@@ -88,32 +121,52 @@
   asyncTest(() async {
     await test(
         Uri.parse('memory:main.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From error.dart, package:pkg_error1 and package:pkg_error2:
         warnings: 3, hints: 3, infos: 3);
     await test(
         Uri.parse('memory:main.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: ['pkg_error1'],
+        // From error.dart and package:pkg_error1:
+        warnings: 2, hints: 2 + 1 /* from summary */, infos: 2);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: ['pkg_error1', 'pkg_error2'],
+        // From error.dart, package:pkg_error1 and package:pkg_error2:
+        warnings: 3, hints: 3, infos: 3);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: [],
+        // From error.dart, package:pkg_error1 and package:pkg_error2:
+        warnings: 3, hints: 3, infos: 3);
+    await test(
+        Uri.parse('memory:main.dart'),
+        showPackageWarnings: null,
         // From error.dart only:
         warnings: 1, hints: 1 + 2 /* from summary */, infos: 1);
     await test(
         Uri.parse('package:pkg_error1/pkg_error1.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From package:pkg_error1 and package:pkg_error2:
         warnings: 2, hints: 2, infos: 2);
     await test(
         Uri.parse('package:pkg_error1/pkg_error1.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: null,
         // From package:pkg_error1/pkg_error1.dart only:
         warnings: 1, hints: 1 + 1 /* from summary */, infos: 1);
     await test(
         Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
-        showPackageWarnings: true,
+        showPackageWarnings: [],
         // From package:pkg_error1 and package:pkg_error2:
         warnings: 2, hints: 2, infos: 2);
     await test(
         Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
-        showPackageWarnings: false,
+        showPackageWarnings: ['pkg_error1'],
+        // From package:pkg_error1:
+        warnings: 1, hints: 1 + 1 /* from summary */, infos: 1);
+    await test(
+        Uri.parse('package:pkg_noerror/pkg_noerror.dart'),
+        showPackageWarnings: null,
         hints: 2 /* from summary */);
   });
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 125d665..2757d9e 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -139,35 +139,6 @@
 string_case_test/02: Fail, OK  # Bug in dartium version of V8.
 string_case_test/03: Fail, OK  # Bug in dartium version of V8.
 
-[ $compiler == dartanalyzer ]
-from_environment_const_type_test: Skip # The -D option that defines a constant
-# for the Dart vm is not accepted by the deprecated java dartanalyzer.
-int_parse_radix_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-list_insert_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-list_removeat_test: Fail, OK # Test contains errors but doesn’t mark them as expected
-
-# Issue 16391. These tests are supposed to produce a compile time
-# error in checked mode, but they don't:
-[ $compiler == dartanalyzer && $checked ]
-from_environment_const_type_test/02: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/03: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/04: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/06: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/07: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/08: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/09: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/11: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/12: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/13: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/14: MissingCompileTimeError # Issue 16391
-from_environment_const_type_test/16: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/02: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/03: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/04: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/06: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/07: MissingCompileTimeError # Issue 16391
-from_environment_const_type_undefined_test/08: MissingCompileTimeError # Issue 16391
-
 # Analyzer's implementation of fromEnvironment assumes that undefined
 # environment variables have an unspecified value (rather than being
 # null) because it is expected that the user will supply a value when
@@ -185,8 +156,6 @@
 int_parse_radix_test: fail
 list_insert_test: fail
 list_removeat_test: fail
-
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 hash_set_type_check_test: StaticWarning, OK # Tests failing type tests.
 error_stack_trace_test: StaticWarning, OK # Test generates errors on purpose.
 iterable_element_at_test: StaticWarning, OK # Test generates errors on purpose.
@@ -204,7 +173,7 @@
 [ $runtime == vm ]
 regexp/global_test: Skip # Timeout. Issue 21709 and 21708
 
-[ $runtime != vm && $compiler != dartanalyzer && $compiler != dart2analyzer]
+[ $runtime != vm && $compiler != dart2analyzer]
 package_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 data_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 file_resource_test: Skip, OK # VM specific test, uses dart:io.
@@ -245,6 +214,6 @@
 [ $noopt ]
 apply3_test: CompileTimeError # Imports dart:mirrors
 regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
-big_integer_huge_mul_vm_test: Pass, Timeout
-big_integer_parsed_mul_div_vm_test: Pass, Timeout
-int_parse_radix_test: Pass, Timeout
+big_integer_huge_mul_vm_test: Pass, Timeout # --no_intrinsify
+big_integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
+int_parse_radix_test: Pass, Timeout # --no_intrinsify
diff --git a/tests/html/html.status b/tests/html/html.status
index afe5400..faeaa01 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -411,7 +411,7 @@
 [ (($runtime == dartium || $runtime == drt) && $system == macos) || $system == windows ]
 xhr_test/xhr: Skip # Times out.  Issue 21527
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 custom/document_register_basic_test: StaticWarning
 custom/element_upgrade_test: StaticWarning
 datalistelement_test: StaticWarning
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 06e949a..04bb204 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -133,7 +133,7 @@
 exit_at_spawnuri_test: SkipByDesign  # 13921 Dom isolates don't support spawnFunction
 
 
-[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+[ $compiler == dart2analyzer ]
 browser/typed_data_message_test: StaticWarning
 mint_maker_test: StaticWarning
 
diff --git a/tests/language/language.status b/tests/language/language.status
index 0d4a45c..79d8804 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -127,16 +127,15 @@
 super_getter_setter_test: CompileTimeError
 vm/reflect_core_vm_test: CompileTimeError
 redirecting_factory_reflection_test: CompileTimeError
+deferred_constraints_constants_test: Skip # multitest gets confused
 
-# Deferred loading - Issue 24676
-deferred_load_constants_test: Skip
-deferred_constraints_constants_test: Skip
-deferred_global_test: Skip
+# Deferred loading happens eagerly
+regress_23408_test: RuntimeError
+deferred_global_test: RuntimeError
 deferred_inheritance_constraints_test: Skip
+deferred_load_constants_test: Skip # multitest gets confused
 
 deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
 tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
 vm/type_cast_vm_test: RuntimeError # Line number mismatch.
-regress_23408_test: RuntimeError
-
 stack_trace_test: Fail  # Issue 24783 - inlined frames missing
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
deleted file mode 100644
index a6eb91c..0000000
--- a/tests/language/language_analyzer.status
+++ /dev/null
@@ -1,611 +0,0 @@
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-[ $compiler == dartanalyzer ]
-async_return_types_test/wrongTypeParameter: MissingStaticWarning # Issue 22410
-async_return_types_test/wrongReturnType: MissingStaticWarning # Issue 22410
-async_or_generator_return_type_stacktrace_test/01: MissingStaticWarning # Issue 22410
-async_or_generator_return_type_stacktrace_test/02: MissingStaticWarning # Issue 22410
-async_return_types_test/nestedFuture: MissingStaticWarning # Issue 22410
-await_backwards_compatibility_test/none: CompileTimeError # Issue 22052
-await_test: CompileTimeError # Issue 22052
-async_await_test/02: CompileTimeError # Issue 22052
-regress_17382_test: Skip # don't care about the static warning.
-regress_23408_test: Skip # don't care about the warning.
-regress_23038_test/01: Skip # Issue 23038
-getter_setter_in_lib_test: Fail # issue 23286
-
-issue13179_test: CompileTimeError # Issue 13179
-tearoff_basic_test: Skip # Tear-off not supported
-tearoff_constructor_basic_test: Skip # Tear-off not supported
-
-sync_generator2_test/01: MissingCompileTimeError # Issue 22252
-sync_generator2_test/02: MissingCompileTimeError # Issue 22252
-sync_generator2_test/03: MissingCompileTimeError # Issue 22252
-sync_generator2_test/04: MissingCompileTimeError # Issue 22252
-sync_generator2_test/05: MissingCompileTimeError # Issue 22252
-sync_generator2_test/06: MissingCompileTimeError # Issue 22252
-sync_generator2_test/07: MissingCompileTimeError # Issue 22252
-sync_generator2_test/10: MissingCompileTimeError # Issue 22252
-
-async_test/type-mismatch2: MissingStaticWarning # Issue 22053
-async_test/type-mismatch3: MissingStaticWarning # Issue 22053
-async_test/type-mismatch4: MissingStaticWarning # Issue 22053
-
-async_await_syntax_test/a05c: CompileTimeError
-async_await_syntax_test/a05e: CompileTimeError
-async_await_syntax_test/a05f: MissingCompileTimeError
-async_await_syntax_test/a10a: MissingStaticWarning
-async_await_syntax_test/b10a: MissingStaticWarning
-async_await_syntax_test/c10a: MissingStaticWarning
-async_await_syntax_test/d10a: MissingStaticWarning
-
-assign_to_type_test/01: MissingStaticWarning
-assign_to_type_test/02: MissingStaticWarning
-assign_to_type_test/03: MissingStaticWarning
-assign_to_type_test/04: MissingStaticWarning
-
-# Runtime negative test. No static errors or warnings.
-closure_call_wrong_argument_count_negative_test: skip
-
-compile_time_constant_c_test/01: Fail # Issue 21000
-compile_time_constant12_test: Fail # Issue 21000
-
-enum_syntax_test/02: Fail # 21649
-enum_syntax_test/03: Fail # 21649
-enum_syntax_test/04: Fail # 21649
-enum_syntax_test/05: Fail # 21649
-enum_syntax_test/06: Fail # 21649
-
-# Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
-built_in_identifier_prefix_test: CompileTimeError # Issue 12694
-
-# TBF: we should check conflicts not only for methods, but for accessors too
-override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11497
-
-external_test/21: Fail
-external_test/24: Fail
-external_test/25: Fail
-constructor_duplicate_final_test/03: Fail
-identical_const_test: Fail # Issue 21177
-super_bound_closure_test/01: MissingStaticWarning # Issue 18914
-mixin_forwarding_constructor4_test/01: MissingCompileTimeError # Issue 19576
-mixin_forwarding_constructor4_test/02: MissingCompileTimeError # Issue 19576
-mixin_forwarding_constructor4_test/03: MissingCompileTimeError # Issue 19576
-mixin_super_constructor_named_test/01: MissingCompileTimeError # Issue 19576
-mixin_super_constructor_positionals_test/01: MissingCompileTimeError # Issue 19576
-reify_typevar_static_test/00: MissingCompileTimeError # Issue 21565
-
-multiline_newline_test/01: CompileTimeError # Issue 23888
-multiline_newline_test/02: CompileTimeError # Issue 23888
-multiline_newline_test/03: CompileTimeError # Issue 23888
-multiline_newline_test/04: MissingCompileTimeError # Issue 23888
-multiline_newline_test/05: MissingCompileTimeError # Issue 23888
-multiline_newline_test/06: MissingCompileTimeError # Issue 23888
-
-const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
-
-# Unsupported configuration specific imports.
-config_import_test: CompileTimeError # Issue 24579
-
-# Please add new failing tests before this line.
-# Section below is for invalid tests.
-#
-#
-
-ref_before_declaration_test/none: fail # test issue 14879, "P" is not defined
-bad_initializer2_negative_test: fail # Issue 14880, Analyzer reports compile-time error, but test runner is not satisfied
-
-# test issue 11124, It is warning, not error to don't initialize final field
-field3a_negative_test: Fail # Issue 11124
-final_syntax_test/01: Fail # Issue 11124
-final_syntax_test/04: Fail # Issue 11124
-final_syntax_test/02: Fail # Issue 11124
-final_syntax_test/03: Fail # Issue 11124
-
-# Test issue 11545, using not existing constructor name in annotation
-metadata_test: fail
-
-# test issue 11575, classes with abstract members are not marked as abstract
-get_set_syntax_test/none: fail # Issue 11575
-implicit_this_test/none: fail # Issue 11575
-interface_test/none: fail # Issue 11575
-syntax_test/none: fail # Issue 11575
-
-# test issue 11576
-bad_constructor_test/none: fail # Issue 11576
-
-# test issue 11577, has return type for []=
-cascade_test/none: fail # Issue 11577
-
-# test issue 11578, redirecting factory with not subtype
-factory5_test/none: fail # Issue 11578
-type_variable_bounds_test/none: fail # Issue 11578
-type_variable_scope_test/none: fail # Issue 11578
-factory_implementation_test/none: fail # Issue 11578
-malbounded_redirecting_factory_test/none: fail # Issue 11578
-malbounded_redirecting_factory2_test/none: fail # Issue 11578
-
-# test issue 11579, assignment, no setter
-getter_no_setter_test/none: fail
-
-# test issue 11584, positional arguments cannot be used for named parameters
-compile_time_constant_e_test: fail # Test Issue 11584
-
-# test issue 11585, static warning, not negative test
-constructor3_negative_test: fail
-constructor_call_wrong_argument_count_negative_test: fail
-instance_call_wrong_argument_count_negative_test: fail
-
-# test issue 11590, runtime only negative test
-field_method4_negative_test: fail
-
-# test issue 11594, Reference to a not resolve identifier is static warning
-import_combinators_negative_test: fail
-interface_static_non_final_fields_negative_test: fail
-
-# test issue 11962, it is warning, not error to reference undeclared identifier
-prefix1_negative_test: fail
-prefix2_negative_test: fail
-prefix4_negative_test: fail
-prefix5_negative_test: fail
-prefix12_negative_test: fail
-
-# test issue 11964, Any use of a malformed type gives rise to a static warning.
-prefix8_negative_test: fail
-prefix11_negative_test: fail
-
-# test issue 12156, fails only at runtime
-static_call_wrong_argument_count_negative_test: fail
-
-# test issue 12160, not annotated warnings for type variables from static member
-type_parameter_test/none: fail
-# test issue 12161, type variable in static, malformed type, static warning
-type_variable_static_context_negative_test: fail
-
-# test issue 12163, unresolved identifier is static warning in static context
-unresolved_in_factory_negative_test: fail # Issue 12163
-unresolved_top_level_var_negative_test: fail # Issue 12163
-
-# test issue 12191, ambiguous import is always warning now
-prefix3_negative_test: fail # Issue 12191
-
-# test issue 12289, assignment in assert statement
-type_error_test: fail # Issue 12289
-
-# test issue 12381, It is compile-time error to invoke not existing function
-issue11724_test: fail # Issue 12381
-
-# test issue 12541; there shouldn't be a static warning
-static_field_test/01: fail # Issue 12541
-static_field_test/02: fail # Issue 12541
-static_field_test/03: fail # Issue 12541
-static_field_test/04: fail # Issue 12541
-
-# test issue 13916, Looks as no warning should be in this redirecting factory
-redirecting_factory_infinite_steps_test/01: fail
-
-# test issue 14471, has (legitimate) static warning; but not annotated
-redirecting_factory_default_values_test/none: StaticWarning # Test issue 14471; has (legitimate) static warning; but not annotated
-
-# test issue 13956, It is a static type warning if any of the type arguments to k' are not subtypes of the bounds of the corresponding formal type parameters of type.
-default_factory2_test/none: fail
-
-# test issue 14021, it is warning, not an error to reference private (undefined) identifier
-private_member1_negative_test: fail
-private_member2_negative_test: fail
-private_member3_negative_test: fail
-
-# test issue 14079
-malformed_test/none: fail # test issue 14079, legit warnings for malformed type
-malformed_test/05: fail # test issue 14079, it is not error, but warning to instantiate malformed type
-malformed_test/06: fail # test issue 14079, it is not error, but warning to use malformed type in "try-on" clause
-regress_22438_test: fail # test issue 14079, it is not error, but warning to use malformed type in "try-on" clause
-
-# test issue 14228
-black_listed_test/none: fail # test issue 14228, warnings are required but not expected
-
-# test issue 14410, "typedef C = " is now really illegal syntax
-mixin_illegal_syntax_test/none: fail
-
-# test issue 14736, It is a static warning if a class C declares an instance method named n and has a setter named n=.
-setter4_test: StaticWarning
-
-# test issue 15467
-proxy_test/05: StaticWarning # Issue 15467
-proxy_test/06: StaticWarning # Issue 15467
-proxy3_test/03: StaticWarning # Issue 15467
-proxy3_test/04: StaticWarning # Issue 15467
-
-# test issue 18230
-factory_redirection_test/02: StaticWarning # Issue 18230
-factory_redirection_test/08: StaticWarning # Issue 18230
-factory_redirection_test/09: StaticWarning # Issue 18230
-factory_redirection_test/10: StaticWarning # Issue 18230
-factory_redirection_test/11: StaticWarning # Issue 18230
-factory_redirection_test/12: StaticWarning # Issue 18230
-factory_redirection_test/13: StaticWarning # Issue 18230
-factory_redirection_test/14: StaticWarning # Issue 18230
-factory_redirection_test/none: StaticWarning # Issue 18230
-
-# analyzer does not handle @proxy and noSuchMethod correctly
-override_inheritance_no_such_method_test/03: StaticWarning # Issue 16132
-override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132
-override_inheritance_no_such_method_test/05: StaticWarning # Issue 16132
-
-# test issue 20074
-regress_20074_test: CompileTimeError # Issue 20074
-
-# The following tests are currently assumed to be failing because the test is wrong.
-#
-application_negative_test: CompileTimeError # Test Issue 14528
-bad_constructor_test/05: CompileTimeError # Test Issue 5337
-bad_initializer1_negative_test: CompileTimeError # Test Issue 14529
-bad_named_constructor_negative_test: CompileTimeError # Test Issue 18693
-body_less_constructor_wrong_arg_negative_test: CompileTimeError # Test Issue 18695
-empty_block_case_test: StaticWarning # Test Issue 18701
-error_stacktrace_test: StaticWarning # Test Issue 18702
-
-const_counter_negative_test: CompileTimeError
-const_optional_args_negative_test: CompileTimeError
-constructor_redirect1_negative_test: CompileTimeError
-constructor_redirect2_negative_test: CompileTimeError
-constructor_setter_negative_test: CompileTimeError
-duplicate_export_negative_test: CompileTimeError
-duplicate_interface_negative_test: CompileTimeError
-export_ambiguous_main_negative_test: CompileTimeError
-extend_type_parameter2_negative_test: CompileTimeError
-extend_type_parameter_negative_test: CompileTimeError
-factory2_negative_test: CompileTimeError
-factory2_test: StaticWarning # Test Issue 18727
-factory3_negative_test: CompileTimeError
-factory3_test: StaticWarning # Test Issue 18727
-factory4_test: StaticWarning # Test Issue 18727
-factory_implementation_test/00: StaticWarning
-factory_negative_test: CompileTimeError
-factory_redirection_test/01: StaticWarning # Test Issue 11578
-factory_redirection_test/03: StaticWarning # Test Issue 11578
-factory_redirection_test/05: StaticWarning # Test Issue 11578
-factory_redirection_test/06: StaticWarning # Test Issue 11578
-factory_return_type_checked_test: StaticWarning # Test Issue 18728
-f_bounded_quantification4_test: StaticWarning
-f_bounded_quantification5_test: StaticWarning
-field1_negative_test: CompileTimeError
-field2_negative_test: CompileTimeError
-field3_negative_test: CompileTimeError
-field4_negative_test: CompileTimeError
-field5_negative_test: CompileTimeError
-field6a_negative_test: CompileTimeError
-field6_negative_test: CompileTimeError
-first_class_types_literals_test/08: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/09: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/10: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/11: MissingStaticWarning # Issue 18731
-first_class_types_literals_test/12: MissingStaticWarning # Issue 18731
-function_malformed_result_type_test: StaticWarning
-function_subtype_bound_closure7_test: StaticWarning
-function_subtype_checked0_test: StaticWarning
-function_subtype_closure0_test: StaticWarning
-function_subtype_closure1_test: StaticWarning
-function_subtype_factory1_test: StaticWarning
-function_subtype_inline1_test: StaticWarning
-function_type2_test: StaticWarning
-function_type_parameter2_negative_test: CompileTimeError
-function_type_parameter_negative_test: CompileTimeError
-generic_list_checked_test: StaticWarning
-generics_test: StaticWarning
-generic_test: StaticWarning
-getter_declaration_negative_test: CompileTimeError
-getter_no_setter2_test/01: StaticWarning
-getter_no_setter_test/01: StaticWarning
-illegal_invocation_test/01: StaticWarning
-implicit_this_test/02: StaticWarning
-implied_interface_test: StaticWarning
-import_combinators_test: StaticWarning
-import_core_prefix_test: StaticWarning
-inferrer_this_access_test: StaticWarning
-inlined_throw_test: StaticWarning
-instance_method2_negative_test: CompileTimeError
-instance_method_negative_test: CompileTimeError
-instanceof3_test: StaticWarning
-instantiate_type_variable_test/01: StaticWarning
-inst_field_initializer1_negative_test: CompileTimeError
-interceptor6_test: StaticWarning
-interface2_negative_test: CompileTimeError
-interface_inherit_field_test: StaticWarning
-interface_injection1_negative_test: CompileTimeError
-interface_injection2_negative_test: CompileTimeError
-interface_static_method_negative_test: CompileTimeError
-invocation_mirror_test: StaticWarning
-is_not_class1_negative_test: CompileTimeError
-is_not_class2_test: StaticWarning
-is_not_class4_negative_test: CompileTimeError
-isnot_malformed_type_test: StaticWarning
-issue1363_test: StaticWarning
-issue1578_negative_test: CompileTimeError
-label2_negative_test: CompileTimeError
-label3_negative_test: CompileTimeError
-label5_negative_test: CompileTimeError
-label6_negative_test: CompileTimeError
-label8_negative_test: CompileTimeError
-label_test: StaticWarning
-library_ambiguous_test/00: StaticWarning
-library_ambiguous_test/01: StaticWarning
-library_ambiguous_test/02: StaticWarning
-library_ambiguous_test/03: StaticWarning
-library_negative_test: CompileTimeError
-list_literal2_negative_test: CompileTimeError
-list_literal4_test: StaticWarning
-list_literal_negative_test: CompileTimeError
-list_test: StaticWarning
-malbounded_type_cast_test: StaticWarning
-malbounded_type_cast2_test: StaticWarning
-malbounded_type_literal_test: StaticWarning
-malbounded_type_test2_test: StaticWarning
-malformed_type_test: StaticWarning
-map_literal2_negative_test: CompileTimeError
-map_literal3_test: StaticWarning
-map_literal4_test: StaticWarning
-map_literal6_test: StaticWarning
-map_literal8_test: StaticWarning
-map_literal_negative_test: CompileTimeError
-method_override4_test: StaticWarning
-method_override5_test: StaticWarning
-method_override6_test: StaticWarning
-method_override_test: StaticWarning
-mixin_illegal_static_access_test: StaticWarning
-mixin_illegal_syntax_test/13: CompileTimeError
-mixin_type_parameters_mixin_extends_test: StaticWarning
-mixin_type_parameters_mixin_test: StaticWarning
-mixin_type_parameters_super_extends_test: StaticWarning
-mixin_type_parameters_super_test: StaticWarning
-mixin_with_two_implicit_constructors_test: StaticWarning
-mixin_invalid_bound_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_invalid_bound2_test/none: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_super_bound_test: StaticWarning # legitimate StaticWarning, cannot be annotated
-mixin_super_bound2_test: CompileTimeError # Issue 23772
-mixin_super_test: CompileTimeError # Issue 23772
-mixin_super_2_test: CompileTimeError # Issue 23772
-mixin_super_use_test: CompileTimeError # Issue 23772
-mixin_superclass_test: CompileTimeError # Issue 23772
-named_constructor_test/01: StaticWarning
-named_constructor_test/03: StaticWarning
-named_parameters2_test: StaticWarning
-named_parameters3_test: StaticWarning
-named_parameters4_test: StaticWarning
-named_parameters_test/01: StaticWarning
-named_parameters_test/02: StaticWarning
-named_parameters_test/03: StaticWarning
-named_parameters_test/04: StaticWarning
-named_parameters_test/05: StaticWarning
-named_parameters_test/06: StaticWarning
-named_parameters_test/07: StaticWarning
-named_parameters_test/08: StaticWarning
-named_parameters_test/09: StaticWarning
-named_parameters_test/10: StaticWarning
-named_parameters_type_test/01: StaticWarning
-new_expression1_negative_test: CompileTimeError
-new_expression2_negative_test: CompileTimeError
-new_expression3_negative_test: CompileTimeError
-non_const_super_negative_test: CompileTimeError
-non_parameterized_factory2_test: StaticWarning
-non_parameterized_factory_test: StaticWarning
-no_such_constructor2_test: StaticWarning
-no_such_method2_test: StaticWarning
-no_such_method_dispatcher_test: StaticWarning
-not_enough_positional_arguments_test/00: StaticWarning
-not_enough_positional_arguments_test/01: CompileTimeError
-not_enough_positional_arguments_test/02: StaticWarning
-not_enough_positional_arguments_test/03: StaticWarning
-not_enough_positional_arguments_test/05: StaticWarning
-not_enough_positional_arguments_test/06: StaticWarning
-not_enough_positional_arguments_test/07: StaticWarning
-number_identifier_test/08: StaticWarning
-number_identifier_test/09: StaticWarning
-on_catch_malformed_type_test: StaticWarning
-operator1_negative_test: CompileTimeError
-operator2_negative_test: CompileTimeError
-operator_equals_test: StaticWarning
-optional_named_parameters_test/01: StaticWarning
-optional_named_parameters_test/02: StaticWarning
-optional_named_parameters_test/03: StaticWarning
-optional_named_parameters_test/04: StaticWarning
-optional_named_parameters_test/05: StaticWarning
-optional_named_parameters_test/06: StaticWarning
-optional_named_parameters_test/07: StaticWarning
-optional_named_parameters_test/08: StaticWarning
-optional_named_parameters_test/09: StaticWarning
-override_field_method1_negative_test: CompileTimeError
-override_field_method2_negative_test: CompileTimeError
-override_field_method4_negative_test: CompileTimeError
-override_field_method5_negative_test: CompileTimeError
-parameter_initializer1_negative_test: CompileTimeError
-parameter_initializer2_negative_test: CompileTimeError
-parameter_initializer3_negative_test: CompileTimeError
-parameter_initializer4_negative_test: CompileTimeError
-parameter_initializer5_negative_test: CompileTimeError
-parameter_initializer6_negative_test: CompileTimeError
-parser_quirks_test: StaticWarning
-part2_test: StaticWarning
-positional_parameters_type_test/01: StaticWarning
-prefix13_negative_test: CompileTimeError
-prefix14_test: StaticWarning
-prefix15_negative_test: CompileTimeError
-prefix15_test: StaticWarning
-prefix16_test: StaticWarning
-prefix17_test: StaticWarning
-prefix18_negative_test: CompileTimeError
-prefix22_test: StaticWarning
-prefix23_test: StaticWarning
-prefix7_negative_test: CompileTimeError
-property_field_override_test: StaticWarning
-redirecting_factory_incompatible_signature_test: StaticWarning
-regress_13494_test: StaticWarning
-return_type_test: StaticWarning
-script1_negative_test: CompileTimeError
-script2_negative_test: CompileTimeError
-setter_declaration2_negative_test: CompileTimeError
-setter_declaration_negative_test: CompileTimeError
-setter_no_getter_call_test/01: StaticWarning
-source_self_negative_test: CompileTimeError
-static_initializer_type_error_test: StaticWarning
-string_escape4_negative_test: CompileTimeError
-string_interpolate1_negative_test: CompileTimeError
-string_interpolate2_negative_test: CompileTimeError
-string_interpolate_test: StaticWarning
-string_interpolation1_negative_test: CompileTimeError
-string_interpolation2_negative_test: CompileTimeError
-string_interpolation3_negative_test: CompileTimeError
-string_interpolation4_negative_test: CompileTimeError
-string_interpolation5_negative_test: CompileTimeError
-string_interpolation6_negative_test: CompileTimeError
-string_test: StaticWarning
-string_unicode1_negative_test: CompileTimeError
-string_unicode2_negative_test: CompileTimeError
-string_unicode3_negative_test: CompileTimeError
-string_unicode4_negative_test: CompileTimeError
-super_assign_test: StaticWarning
-super_call4_test: StaticWarning
-super_getter_setter_test: StaticWarning
-super_operator_index5_test: StaticWarning
-super_operator_index6_test: StaticWarning
-super_operator_index7_test: StaticWarning
-super_operator_index8_test: StaticWarning
-super_operator_test: StaticWarning
-super_setter_test: StaticWarning
-switch1_negative_test: CompileTimeError
-switch3_negative_test: CompileTimeError
-switch4_negative_test: CompileTimeError
-switch5_negative_test: CompileTimeError
-switch6_test: StaticWarning
-switch7_negative_test: CompileTimeError
-switch_fallthru_test: StaticWarning
-test_negative_test: CompileTimeError
-top_level_non_prefixed_library_test: StaticWarning
-try_catch4_test: StaticWarning
-try_catch5_test: StaticWarning
-type_argument_in_super_type_test: StaticWarning
-typed_selector2_test: StaticWarning
-type_variable_identifier_expression_test: StaticWarning
-type_variable_scope2_test: StaticWarning
-type_variable_conflict2_test/02: MissingCompileTimeError
-type_variable_conflict2_test/06: MissingCompileTimeError
-type_variable_conflict2_test/08: MissingCompileTimeError
-type_variable_conflict2_test/10: MissingCompileTimeError
-unary_plus_negative_test: CompileTimeError
-unbound_getter_test: StaticWarning
-unhandled_exception_negative_test: CompileTimeError
-unresolved_top_level_method_negative_test: StaticWarning
-vm/debug_break_enabled_vm_test: CompileTimeError, OK
-vm/type_cast_vm_test: StaticWarning
-vm/type_vm_test: StaticWarning
-void_type_test: StaticWarning
-
-issue13474_test: StaticWarning, OK # Test Issue
-
-
-# The following lines have been left in to quickly switch back to having deferred loading
-# off by default again.
-# Deferred loading support, tests marked as failing until support is enabled by default.
-#deferred_closurize_load_library_test: Pass, Fail
-#deferred_not_loaded_check_test/*: Pass, Fail
-#deferred_shadow_load_library_test: Pass, Fail
-#deferred_constraints_constants_test/*: Pass, Fail
-#deferred_load_library_wrong_args_test/*: Pass, Fail
-#deferred_constraints_type_annotation_test/*: Pass, Fail
-#deferred_load_inval_code_test: Pass, Fail
-#deferred_not_loaded_check_test: Pass, Fail
-
-# Issues to be fixed now that type parameters have been fixed
-# (issues 14221, 15553)
-factory1_test/00: StaticWarning # Test Issue 18726
-factory1_test/01: StaticWarning # Test Issue 18726
-factory1_test/none: StaticWarning # Test Issue 18726
-generic_closure_test: StaticWarning
-local_function2_test: StaticWarning
-redirecting_factory_long_test: StaticWarning
-
-# This test uses "const Symbol('_setAt')"
-vm/reflect_core_vm_test: CompileTimeError
-
-# This test is expected to have warnings because of noSuchMethod overriding.
-regress_12561_test: StaticWarning
-
-main_not_a_function_test/01: Fail # Issue 20030
-main_test/03: Fail # Issue 20030
-no_main_test/01: Fail # Issue 20030
-
-compile_time_constant10_test/none: CompileTimeError # Issue 21177
-
-const_dynamic_type_literal_test: CompileTimeError # Issue 22989
-
-regress_21912_test/02: StaticWarning # Issue 21912
-regress_22976_test/02: StaticWarning # Issue 22976
-
-variable_declaration_metadata_test/02: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/03: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/04: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/06: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/08: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/09: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/10: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/12: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/13: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/14: MissingCompileTimeError # Issue 23204
-variable_declaration_metadata_test/16: MissingCompileTimeError # Issue 23204
-
-# Null-aware operators aren't implemented in the Java-based analyzer.
-if_null_evaluation_order_test: CompileTimeError
-if_null_precedence_test: CompileTimeError
-if_null_behavior_test: CompileTimeError
-if_null_assignment_behavior_test: CompileTimeError
-if_null_assignment_static_test: CompileTimeError
-conditional_property_assignment_test: CompileTimeError
-conditional_property_access_test: CompileTimeError
-conditional_method_invocation_test: CompileTimeError
-
-# This test is expected to generate a warning, since it's
-# intentionally referring to a variable that's not in scope.
-transitive_private_library_access_test: StaticWarning
-
-# Issue 16391. These tests are supposed to produce a compile time
-# error in checked mode, but they don't:
-[ $compiler == dartanalyzer && $checked ]
-assign_static_type_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/04: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked2_test/06: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/04: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked3_test/06: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/01: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/02: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked4_test/03: MissingCompileTimeError # Issue 16391
-compile_time_constant_checked_test/02: MissingCompileTimeError # Issue 16391
-const_constructor2_test/13: MissingCompileTimeError # Issue 16391
-const_constructor2_test/14: MissingCompileTimeError # Issue 16391
-const_constructor2_test/15: MissingCompileTimeError # Issue 16391
-const_constructor2_test/16: MissingCompileTimeError # Issue 16391
-const_constructor2_test/17: MissingCompileTimeError # Issue 16391
-const_constructor2_test/20: MissingCompileTimeError # Issue 16391
-const_constructor2_test/22: MissingCompileTimeError # Issue 16391
-const_constructor2_test/24: MissingCompileTimeError # Issue 16391
-const_constructor3_test/02: MissingCompileTimeError # Issue 16391
-const_constructor3_test/04: MissingCompileTimeError # Issue 16391
-const_init2_test/02: MissingCompileTimeError # Issue 16391
-malformed2_test/01: MissingCompileTimeError # Issue 16391
-type_check_const_function_typedef2_test/00: MissingCompileTimeError # Issue 16391
-type_parameter_test/05: MissingCompileTimeError # Issue 16391
-
-compile_time_constant_checked5_test/03: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/04: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/08: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/09: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/13: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/14: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/18: MissingCompileTimeError # Issue 23292
-compile_time_constant_checked5_test/19: MissingCompileTimeError # Issue 23292
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index ac93e88..547ffb6 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -15,6 +15,7 @@
 
 regress_17382_test: Skip # don't care about the static warning.
 regress_23408_test: Skip # don't care about the static warning.
+regress_25246_test: Skip
 getter_setter_in_lib_test: Fail # issue 23286
 
 # Test issue 12694 (was analyzer issue), (1) when "abstract" is import prefix using it as type is warning; (2) currently analyzer resolves prefix as field (don't ask)
diff --git a/tests/language/regress_25246_1_test.dart b/tests/language/regress_25246_1_test.dart
new file mode 100644
index 0000000..e392e89
--- /dev/null
+++ b/tests/language/regress_25246_1_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+import 'regress_25246_2.dart';
+
+class ConcreteClass extends Object with MixIn { }
+
+void main() {
+  new ConcreteClass().test();
+}
diff --git a/tests/language/regress_25246_2.dart b/tests/language/regress_25246_2.dart
new file mode 100644
index 0000000..84c9cfb
--- /dev/null
+++ b/tests/language/regress_25246_2.dart
@@ -0,0 +1,12 @@
+// 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.
+
+import 'regress_25246_3.dart';
+
+class MixIn {
+  var test3 = new Test3(() { });
+  void test() {
+    test3.test();
+  }
+}
diff --git a/tests/language/regress_25246_3.dart b/tests/language/regress_25246_3.dart
new file mode 100644
index 0000000..ce61a2e
--- /dev/null
+++ b/tests/language/regress_25246_3.dart
@@ -0,0 +1,11 @@
+// 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.
+
+class Test3 {
+  final fn;
+  Test3(this.fn);
+  void test() {
+    fn();
+  }
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 12ceb29..8c17e5b 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -292,6 +292,9 @@
 profiler/metrics_test: Fail # Issue 20309
 profiler/metrics_num_test: Fail # Issue 20309
 
+[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
+mirrors/metadata_allowed_values_test/29: Crash # Issue 25287
+
 [ ($compiler == dartanalyzer || $compiler == dart2analyzer) && $checked ]
 mirrors/regress_16321_test/01: MissingCompileTimeError # Issue 16391
 
diff --git a/tests/lib/mirrors/metadata_allowed_values_test.dart b/tests/lib/mirrors/metadata_allowed_values_test.dart
index ce1011b..76a5c58 100644
--- a/tests/lib/mirrors/metadata_allowed_values_test.dart
+++ b/tests/lib/mirrors/metadata_allowed_values_test.dart
@@ -149,6 +149,30 @@
 }
 get kk => const KK();
 
+@LL(() => 42)  /// 28: compile-time error
+class LL {
+  final field;
+  const LL(this.field);
+}
+
+@MM((x) => 42)  /// 29: compile-time error
+class MM {
+  final field;
+  const MM(this.field);
+}
+
+@NN(() {})  /// 30: compile-time error
+class NN {
+  final field;
+  const NN(this.field);
+}
+
+@OO(() { () {} })  /// 31: compile-time error
+class OO {
+  final field;
+  const OO(this.field);
+}
+
 checkMetadata(DeclarationMirror mirror, List expectedMetadata) {
   Expect.listEquals(expectedMetadata.map(reflect).toList(), mirror.metadata);
 }
@@ -191,4 +215,8 @@
   reflectClass(II).metadata;
   reflectClass(JJ).metadata;
   reflectClass(KK).metadata;
+  reflectClass(LL).metadata;
+  reflectClass(MM).metadata;
+  reflectClass(NN).metadata;
+  reflectClass(OO).metadata;
 }
diff --git a/tests/standalone/io/platform_test.dart b/tests/standalone/io/platform_test.dart
index f074750..308d5d0 100644
--- a/tests/standalone/io/platform_test.dart
+++ b/tests/standalone/io/platform_test.dart
@@ -48,11 +48,20 @@
   Expect.isTrue(Platform.script.toFilePath().startsWith(oldDir.path));
   // Restore dir.
   Directory.current = oldDir;
-  Directory packageRoot = new Directory(Platform.packageRoot);
+  var pkgRootString = Platform.packageRoot;
+  Directory packageRoot = new Directory.fromUri(Uri.parse(pkgRootString));
   Expect.isTrue(packageRoot.existsSync());
   Expect.isTrue(new Directory("${packageRoot.path}/expect").existsSync());
   Expect.isTrue(Platform.executableArguments.any(
-      (arg) => arg.contains(Platform.packageRoot)));
+      (arg) {
+        if (!arg.startsWith("--package-root=")) {
+          return false;
+        }
+        // Cut out the '--package-root=' prefix.
+        arg = arg.substring(15);
+        return pkgRootString.contains(arg);
+      }
+  ));
 }
 
 void f(reply) {
diff --git a/tests/standalone/precompilation_dart2js_test.dart b/tests/standalone/precompilation_dart2js_test.dart
index 52957d7..303c955 100644
--- a/tests/standalone/precompilation_dart2js_test.dart
+++ b/tests/standalone/precompilation_dart2js_test.dart
@@ -43,7 +43,8 @@
     return;
   }
 
-  var abs_package_root = new File(Platform.packageRoot).absolute.path;
+  var pkgRoot = Uri.parse(Platform.packageRoot);
+  var abs_package_root = new File.fromUri(pkgRoot).absolute.path;
   var dart_executable =
       Directory.current.path + Platform.pathSeparator + Platform.executable;
   Directory tmp;
diff --git a/tools/VERSION b/tools/VERSION
index 433c092..083073e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 14
 PATCH 0
-PRERELEASE 4
+PRERELEASE 5
 PRERELEASE_PATCH 0
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index decf876..7952885 100644
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -39,11 +39,9 @@
                               'tools', 'bots', 'dartdoc_footer.html')
   url = 'https://api.dartlang.org/stable'
   with bot.BuildStep('Build API docs by dartdoc'):
-    subprocess.call([dart_exe, '--package-root=' + packages_dir, dartdoc_dart, 
-                    '--sdk-docs','--output', dirname, '--dart-sdk', dart_sdk, 
-                    '--footer' , footer_file,
-                    '--rel-canonical-prefix=' + url], 
-                     stdout=open(os.devnull, 'wb'))
+    bot_utils.run([dart_exe, '--package-root=' + packages_dir, dartdoc_dart, 
+                  '--sdk-docs','--output', dirname, '--dart-sdk', dart_sdk, 
+                  '--footer' , footer_file, '--rel-canonical-prefix=' + url])
 
 def CreateUploadVersionFile():
   file_path = os.path.join(bot_utils.DART_DIR,
diff --git a/tools/bots/pub.py b/tools/bots/pub.py
index cdd8a8b..7f177e0 100755
--- a/tools/bots/pub.py
+++ b/tools/bots/pub.py
@@ -33,7 +33,7 @@
   mode = 'release'
   if system == 'win': system = 'windows'
 
-  return bot.BuildInfo('none', 'vm', mode, system, checked=True)
+  return bot.BuildInfo('none', 'vm', mode, system, checked=True, arch='x64')
 
 def PubSteps(build_info):
   pub_location = os.path.join('third_party', 'pkg', 'pub')
diff --git a/tools/canary.dart b/tools/canary.dart
index cca1f90..0df9f70 100644
--- a/tools/canary.dart
+++ b/tools/canary.dart
@@ -2,10 +2,6 @@
 // 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.
 
-// Script which exits with code 42.
-
-import 'dart:io';
-
 void main() {
-  exitCode = 42;
+  print("Success running the canary.");
 }
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index e9312f4..08529ef 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -49,7 +49,7 @@
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
   "metatest_rev": "@e5aa8e4e19fc4188ac2f6d38368a47d8f07c3df1",
   "oauth2_rev": "@1bff41f4d54505c36f2d1a001b83b8b745c452f5",
-  "observatory_pub_packages_rev": "@5c199c5954146747f75ed127871207718dc87786",
+  "observatory_pub_packages_rev": "@cf90eb9077177d3d6b3fd5e8289477c2385c026a",
   "package_config_rev": "@0.1.3",
   "path_rev": "@b657c0854d1cf41c014986fa9d2321f1173df805",
   "plugin_tag": "@0.1.0",
@@ -71,7 +71,6 @@
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
 
   "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
-  "fake_async_rev": "@38614",
 })
 
 def massage_deps(deps):
@@ -189,10 +188,6 @@
   "src/dart/third_party/WebCore":
     "http://dart.googlecode.com/svn/third_party/WebCore",
 
-  "src/dart/third_party/pkg/fake_async":
-    "http://dart.googlecode.com/svn/third_party/fake_async" +
-    Var("fake_async_rev"),
-
   "src/dart/tests/co19/src":
       (Var("github_mirror") % "co19") + Var("co19_rev"),
 
diff --git a/tools/dom/scripts/chromegenerator.py b/tools/dom/scripts/chromegenerator.py
deleted file mode 100755
index e537c85..0000000
--- a/tools/dom/scripts/chromegenerator.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-"""This module generates Dart Chrome APIs from the Chrome IDL files."""
-
-import sys
-import os
-
-# The path to the JSON Schema Compiler, which can be run to generate the files.
-# Lives in the Chromium repository, so needs to be pulled in somehow.
-COMPILER = "../../../third_party/chrome/tools/json_schema_compiler/compiler.py"
-
-# The path to the Chrome IDL files. They live in the Chromium repository, so
-# need to be pulled in somehow.
-API_DIR = "../../../third_party/chrome/idl/"
-
-# The path to the custom overrides directory, containing override files.
-OVERRIDES_DIR = "../src/_chrome/custom_dart/"
-
-# The path to where the generated .dart files should be saved.
-OUTPUT_DIR = "../src/_chrome/"
-
-# The path to where the output template file is. This file will be populated
-# with TEMPLATE_CONTENT, followed by the list of generated .dart files.
-OUTPUT_TEMPLATE = "../templates/html/dart2js/chrome_dart2js.darttemplate"
-
-# The content to fill OUTPUT_TEMPLATE with. Will be followed by a list of the
-# names of the generated .dart files.
-TEMPLATE_CONTENT = """
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// DO NOT EDIT
-// Auto-generated dart:_chrome library.
-
-/// Native wrappers for the Chrome packaged app APIs.
-///
-/// These functions allow direct access to the chrome.* APIs, allowing
-/// Chrome packaged apps to be written using Dart.
-///
-/// For more information on these APIs, see the
-/// [chrome.* API documentation](http://developer.chrome.com/apps/api_index.html).
-library _chrome;
-
-import 'dart:_foreign_helper' show JS;
-/* TODO(sashab): Add "show convertDartClosureToJS" once 'show' works. */
-import 'dart:_js_helper';
-import 'dart:html_common';
-import 'dart:html';
-
-part "$AUXILIARY_DIR/_chrome/utils.dart";
-part "$AUXILIARY_DIR/_chrome/_chrome.dart";
-
-// Generated files below this line.
-"""
-
-# The format for adding files to TEMPLATE_CONTENT. Will be substituted with the
-# filename (not including the extension) of the IDL/JSON file.
-TEMPLATE_FILE_FORMAT = 'part "$AUXILIARY_DIR/_chrome/%s.dart";'
-
-# A list of schema files to generate.
-# TODO(sashab): Later, use the ones from API_DIR/api.gyp and
-# API_DIR/_permission_features.json (for 'platform_apps').
-API_FILES = [
-    "app_window.idl",
-    "app_runtime.idl",
-    "file_system.idl",
-]
-
-if __name__ == "__main__":
-  # Generate each file.
-  for filename in API_FILES:
-    result = os.system('python "%s" -g dart -D "%s" -d "%s" -r "%s" "%s"' % (
-        COMPILER, OVERRIDES_DIR, OUTPUT_DIR, API_DIR,
-        os.path.join(API_DIR, filename)))
-    if result != 0:
-        print "Error occurred during generation of %s" % (
-            os.path.join(API_DIR, filename))
-        sys.exit(1)
-    else:
-      print "Generated %s successfully to %s.dart" % (
-          os.path.join(API_DIR, filename),
-          os.path.join(OUTPUT_DIR, os.path.splitext(filename)[0]))
-
-  # Generate the template.
-  files_to_add = (TEMPLATE_FILE_FORMAT % os.path.splitext(f)[0]
-                  for f in API_FILES)
-  with open(OUTPUT_TEMPLATE, 'w') as template_file:
-    template_file.write(TEMPLATE_CONTENT)
-    template_file.write('\n'.join(files_to_add))
-  print "Generated template succesfully."
-
-
diff --git a/tools/full-coverage.dart b/tools/full-coverage.dart
index 2963574..d7ff76f 100644
--- a/tools/full-coverage.dart
+++ b/tools/full-coverage.dart
@@ -462,9 +462,11 @@
 
   env.pkgRoot = args["package-root"];
   if (env.pkgRoot != null) {
-    env.pkgRoot = absolute(normalize(args["package-root"]));
-    if (!FileSystemEntity.isDirectorySync(env.pkgRoot)) {
-      fail("Provided package root '${args["package-root"]}' is not directory.");
+    var pkgRootUri = Uri.parse(env.pkgRoot);
+    if (pkgRootUri.scheme == "file") {
+      if (!FileSystemEntity.isDirectorySync(pkgRootUri.toFilePath())) {
+        fail("Provided package root '${args["package-root"]}' is not directory.");
+      }
     }
   } else {
     env.pkgRoot = Platform.packageRoot;
diff --git a/tools/observatory_tool.py b/tools/observatory_tool.py
index 5b1c7c5..a8595dc 100755
--- a/tools/observatory_tool.py
+++ b/tools/observatory_tool.py
@@ -36,11 +36,28 @@
   result.add_argument("--pub-executable", help="pub executable", default=None)
   result.add_argument("--directory", help="observatory root", default=None)
   result.add_argument("--command", help="[get, build, deploy]", default=None)
-  result.add_argument("--silent", help="silence all output", default=False)
-  result.add_argument("--sdk", help="Use prebuilt sdk", default=False)
+  result.add_argument("--silent", help="silence all output", default=None)
+  result.add_argument("--sdk", help="Use prebuilt sdk", default=None)
   return result
 
 def ProcessOptions(options, args):
+  # Fix broken boolean parsing in argparse, where False ends up being True.
+  if (options.silent is not None) and (options.silent == "True"):
+    options.silent = True
+  elif (options.silent is None) or (options.silent == "False"):
+    options.silent = False
+  else:
+    print "--silent expects 'True' or 'False' argument."
+    return False
+
+  if (options.sdk is not None) and (options.sdk == "True"):
+    options.sdk = True
+  elif (options.sdk is None) or (options.sdk == "False"):
+    options.sdk = False
+  else:
+    print "--sdk expects 'True' or 'False' argument."
+    return False
+
   with open(os.devnull, 'wb') as silent_sink:
     # Required options.
     if options.command is None or options.directory is None:
@@ -61,7 +78,7 @@
         pass
     options.pub_executable = None
 
-    if options.sdk is not None and utils.CheckedInSdkCheckExecutable():
+    if options.sdk and utils.CheckedInSdkCheckExecutable():
       # Use the checked in pub executable.
       options.pub_snapshot = os.path.join(utils.CheckedInSdkPath(),
                                           'bin',
@@ -93,7 +110,10 @@
 bootstrap Dart executable will make debug builds slow.
 Please see the Wiki for instructions on replacing the checked-in Dart SDK.
 
-https://github.com/dart-lang/sdk/wiki/The-checked-in-SDK-in--tools
+https://github.com/dart-lang/sdk/wiki/The-checked-in-SDK-in-tools
+
+To use the dart_bootstrap binary please update the PubCommand function
+in the tools/observatory_tool.py script.
 
 """
 
@@ -111,6 +131,10 @@
     else:
       DisplayBootstrapWarning()
       executable = [dart_executable, '--package-root=' + pkg_root, PUB_PATH]
+      # Prevent the bootstrap Dart executable from running in regular
+      # development flow.
+      # REMOVE THE FOLLOWING LINE TO USE the dart_bootstrap binary.
+      # return False
     return subprocess.call(executable + command,
                            stdout=silent_sink if silent else None,
                            stderr=silent_sink if silent else None)
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index b9db509..90b6e73 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-e525a9271e840f53382edfab773ad330384d8caa
\ No newline at end of file
+2709941a74b808414feb005dfa50986680f9bd20
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index d88e4ae..9f3c196 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-b80cd51c9fe293de25273102de5b2721aacc8aba
\ No newline at end of file
+8d928e400289862483a11e798743e49815c06c43
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index 97a2743..a5b7f6a 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-e098625fb19d40c9554f88e3306987c2c5988963
\ No newline at end of file
+90d43da115a1eafe707f6f5c5c0d718ff716c227
\ No newline at end of file
diff --git a/tools/testing/dart/co19_test.dart b/tools/testing/dart/co19_test.dart
index 7c7b27e..f138688e 100644
--- a/tools/testing/dart/co19_test.dart
+++ b/tools/testing/dart/co19_test.dart
@@ -28,7 +28,6 @@
 const List<List<String>> COMMAND_LINES = const <List<String>>[
     const <String>['-mrelease,debug', '-rvm', '-cnone'],
     const <String>['-mrelease,debug', '-rvm', '-cnone', '--checked'],
-    const <String>['-mrelease', '-rnone', '-cdartanalyzer'],
     const <String>['-mrelease', '-rnone', '-cdart2analyzer'],
     const <String>['-mrelease', '-rd8', '-cdart2js', '--use-sdk'],
     const <String>['-mrelease', '-rd8,jsshell', '-cdart2js', '--use-sdk',
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 83fcfbe..e901344 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -64,12 +64,8 @@
     bool useNoopt = configuration['noopt'];
 
     switch (compiler) {
-      case 'dartanalyzer':
-        return new AnalyzerCompilerConfiguration(
-            'dartanalyzer', isDebug: isDebug, isChecked: isChecked,
-            isHostChecked: isHostChecked, useSdk: useSdk);
       case 'dart2analyzer':
-        return new DartBasedAnalyzerCompilerConfiguration(
+        return new AnalyzerCompilerConfiguration(
             isDebug: isDebug, isChecked: isChecked,
             isHostChecked: isHostChecked, useSdk: useSdk);
       case 'dart2js':
@@ -298,12 +294,8 @@
   }
 }
 
-/// Common configuration for analyzer-based tools, such as, dartanalyzer.
 class AnalyzerCompilerConfiguration extends CompilerConfiguration {
-  final String moniker;
-
   AnalyzerCompilerConfiguration(
-      this.moniker,
       {bool isDebug,
       bool isChecked,
       bool isHostChecked,
@@ -317,54 +309,6 @@
   }
 
   String computeCompilerPath(String buildDir) {
-    String suffix = executableScriptSuffix;
-    return 'sdk/bin/dartanalyzer_java$suffix';
-  }
-
-  CommandArtifact computeCompilationArtifact(
-      String buildDir,
-      String tempDir,
-      CommandBuilder commandBuilder,
-      List arguments,
-      Map<String, String> environmentOverrides) {
-    arguments = new List.from(arguments);
-    if (isChecked) {
-      arguments.add('--enable_type_checks');
-    }
-    return new CommandArtifact(
-        <Command>[
-            commandBuilder.getAnalysisCommand(
-                moniker, computeCompilerPath(buildDir), arguments,
-                environmentOverrides,
-                flavor: moniker)],
-        null, null); // Since this is not a real compilation, no artifacts are
-                     // produced.
-  }
-
-  List<String> computeRuntimeArguments(
-      RuntimeConfiguration runtimeConfiguration,
-      String buildDir,
-      TestInformation info,
-      List<String> vmOptions,
-      List<String> sharedOptions,
-      List<String> originalArguments,
-      CommandArtifact artifact) {
-    return <String>[];
-  }
-}
-
-class DartBasedAnalyzerCompilerConfiguration
-    extends AnalyzerCompilerConfiguration {
-  DartBasedAnalyzerCompilerConfiguration({
-      bool isDebug,
-      bool isChecked,
-      bool isHostChecked,
-      bool useSdk})
-      : super(
-          'dart2analyzer', isDebug: isDebug, isChecked: isChecked,
-          isHostChecked: isHostChecked, useSdk: useSdk);
-
-  String computeCompilerPath(String buildDir) {
     var prefix = 'sdk/bin';
     String suffix = executableScriptSuffix;
     if (isHostChecked) {
@@ -381,4 +325,35 @@
     }
     return '$prefix/dartanalyzer$suffix';
   }
+
+  CommandArtifact computeCompilationArtifact(
+      String buildDir,
+      String tempDir,
+      CommandBuilder commandBuilder,
+      List arguments,
+      Map<String, String> environmentOverrides) {
+    arguments = new List.from(arguments);
+    if (isChecked) {
+      arguments.add('--enable_type_checks');
+    }
+    return new CommandArtifact(
+        <Command>[
+            commandBuilder.getAnalysisCommand(
+                'dart2analyzer', computeCompilerPath(buildDir), arguments,
+                environmentOverrides,
+                flavor: 'dart2analyzer')],
+        null, null); // Since this is not a real compilation, no artifacts are
+                     // produced.
+  }
+
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      String buildDir,
+      TestInformation info,
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    return <String>[];
+  }
 }
diff --git a/tools/testing/dart/status_reporter.dart b/tools/testing/dart/status_reporter.dart
index 0e744d0..5841052 100644
--- a/tools/testing/dart/status_reporter.dart
+++ b/tools/testing/dart/status_reporter.dart
@@ -9,8 +9,8 @@
     {
       'runtimes' : ['none'],
       'modes' : ['release'],
-      'archs' : ['ia32'],
-      'compiler' : 'dartanalyzer'
+      'archs' : ['x64'],
+      'compiler' : 'dart2analyzer'
     },
     {
       'runtimes' : ['vm'],
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 1113174..a376f28 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -64,11 +64,10 @@
          safari, ie9, ie10, ie11, firefox, opera, chromeOnAndroid,
          none (compile only)),
 
-   dartanalyzer: Perform static analysis on Dart code by running the analyzer on Java.
-   dart2analyzer: Perform static analysis on Dart code by running the analyzer on Dart.
+   dart2analyzer: Perform static analysis on Dart code by running the analyzer
           (only valid with the following runtimes: none)''',
               ['-c', '--compiler'],
-              ['none', 'dart2js', 'dartanalyzer', 'dart2analyzer'],
+              ['none', 'dart2js', 'dart2analyzer'],
               'none'),
           // TODO(antonm): fix the option drt.
           new _TestOptionSpecification(
@@ -93,7 +92,7 @@
     [ff | chrome | safari | ie9 | ie10 | ie11 | opera | chromeOnAndroid]:
         Run JavaScript in the specified browser.
 
-    none: No runtime, compile only (for example, used for dartanalyzer static
+    none: No runtime, compile only (for example, used for dart2analyzer static
           analysis tests).''',
               ['-r', '--runtime'],
               ['vm', 'd8', 'jsshell', 'drt', 'dartium', 'ff', 'firefox',
@@ -642,7 +641,6 @@
                                'ff', 'chrome', 'safari', 'ie9', 'ie10', 'ie11',
                                'opera', 'chromeOnAndroid', 'safarimobilesim'];
         break;
-      case 'dartanalyzer':
       case 'dart2analyzer':
         validRuntimes = const ['none'];
         break;
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 97ad17a..eeb1d69 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -610,7 +610,7 @@
 
   AnalysisCommand getAnalysisCommand(
       String displayName, executable, arguments, environmentOverrides,
-      {String flavor: 'dartanalyzer'}) {
+      {String flavor: 'dart2analyzer'}) {
     var command = new AnalysisCommand._(
         flavor, displayName, executable, arguments, environmentOverrides);
     return _getUniqueCommand(command);
@@ -2450,7 +2450,8 @@
   final int maxProcesses;
   final int maxBrowserProcesses;
 
-  // For dartanalyzer batch processing we keep a list of batch processes.
+  // For dart2js and analyzer batch processing,
+  // we keep a list of batch processes.
   final _batchProcesses = new Map<String, List<BatchRunnerProcess>>();
   // We keep a BrowserTestRunner for every configuration.
   final _browserTestRunners = new Map<Map, BrowserTestRunner>();
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index b36668c..bec08a8 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -674,7 +674,6 @@
     var status_paths = ['$directory/$name.status',
                         '$directory/.status',
                         '$directory/${name}_dart2js.status',
-                        '$directory/${name}_analyzer.status',
                         '$directory/${name}_analyzer2.status'];
 
     return new StandardTestSuite(configuration,
@@ -1502,7 +1501,6 @@
       case 'none':
         return 'application/dart';
       case 'dart2js':
-      case 'dartanalyzer':
       case 'dart2analyzer':
         return 'text/javascript';
       default:
@@ -1551,8 +1549,7 @@
       args.add('--no-hints');
     }
 
-    if ((configuration["compiler"] == "dartanalyzer" ||
-        configuration["compiler"] == "dart2analyzer") &&
+    if (configuration["compiler"] == "dart2analyzer" &&
         (filePath.filename.contains("dart2js") ||
         filePath.directoryPath.segments().last.contains('html_common'))) {
       args.add("--use-dart2js-libraries");
@@ -2247,7 +2244,7 @@
     if (compiler == "dart2js" && configuration["cps_ir"]) {
       args.add("--use-cps-ir");
     }
-    if (compiler == "dartanalyzer" || compiler == "dart2analyzer") {
+    if (compiler == "dart2analyzer") {
       args.add("--show-package-warnings");
       args.add("--enable-async");
     }
@@ -2277,7 +2274,7 @@
       const ['d8', 'jsshell'].contains(runtime);
 
   static bool isCommandLineAnalyzer(String compiler) =>
-      compiler == 'dartanalyzer' || compiler == 'dart2analyzer';
+      compiler == 'dart2analyzer';
 
   static String buildDir(Map configuration) {
     // FIXME(kustermann,ricow): Our code assumes that the returned 'buildDir'
diff --git a/tools/utils.py b/tools/utils.py
index a6e7f51..efcb886 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -634,8 +634,9 @@
   canary_script = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                'canary.dart')
   try:
-    if 42 == subprocess.call([executable, canary_script]):
-      return True
+    with open(os.devnull, 'wb') as silent_sink:
+      if 0 == subprocess.call([executable, canary_script], stdout=silent_sink):
+        return True
   except OSError as e:
     pass
   return False