diff --git a/CHANGELOG.md b/CHANGELOG.md
index a3fffad..7702384 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 1.15.0
+
+### Core library changes
+  * Added `Uri.queryParametersAll` to handle multiple query parameters with
+    the same name.
+
 ## 1.14.0
 
 ### Core library changes
@@ -10,8 +16,10 @@
 
 * `dart:core`
   * Added `current` getter to `StackTrace` class.
-  * Added `Uri.data` getter for `data:` URIs, and `UriData` class for the
-    return type.
+  * `Uri` class added support for data URIs
+      * Added two new constructors: `dataFromBytes` and `dataFromString`.
+      * Added a `data` getter for `data:` URIs with a new `UriData` class for
+      the return type.
   * Added `growable` parameter to `List.filled` constructor.
   * Added microsecond support to `DateTime`: `DateTime.microsecond`,
     `DateTime.microsecondsSinceEpoch`, and
@@ -23,14 +31,25 @@
     embedder for every generated random value.
 
 * `dart:io`
-  * `Platform` added an `isIOS` getter and `Platform.operatingSystem` may now
-    return `ios`.
-  * Added support for WebSocket compression as standardized in RFC 7692. By
-    default compression is turned on for all WebSocket connections. The
-    optionally named parameter `compression` on the methods `WebSocket.connect`,
-    `WebSocket.fromUpgradedSocket`, and `WebSocketTransformer.upgrade` and on
-    the `WebSocketTransformer` constructor is used to select the compression
-    options.
+  * `Platform` added a static `isIOS` getter and `Platform.operatingSystem` may
+    now return `ios`.
+  * `Platform` added a static `packageConfig` getter.
+  * Added support for WebSocket compression as standardized in RFC 7692.
+  * Compression is enabled by default for all WebSocket connections.
+      * The optionally named parameter `compression` on the methods
+      `WebSocket.connect`, `WebSocket.fromUpgradedSocket`, and
+      `WebSocketTransformer.upgrade` and  the `WebSocketTransformer`
+      constructor can be used to modify or disable compression using the new
+      `CompressionOptions` class.
+
+* `dart:isolate`
+  * Added **_experimental_** support for [Package Resolution Configuration].
+    * Added `packageConfig` and `packageRoot` instance getters to `Isolate`.
+    * Added a `resolvePackageUri` method to `Isolate`.
+    * Added named arguments `packageConfig` and `automaticPackageResolution` to
+    the `Isolate.spawnUri` constructor.
+
+[Package Resolution Configuration File]: https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Accepted/0005%20-%20Package%20Specification/DEP-pkgspec.md
 
 ### Tool changes
 
diff --git a/DEPS b/DEPS
index fbe59dc..fdb11dc 100644
--- a/DEPS
+++ b/DEPS
@@ -40,7 +40,7 @@
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "dartdoc_tag" : "@v0.8.5",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
-  "dart_style_tag": "@0.2.2",
+  "dart_style_tag": "@0.2.4",
   "dev_compiler_rev": "@0.1.9",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
   "html_tag" : "@0.12.1+1",
@@ -86,7 +86,6 @@
   "test_tag": "@0.12.6+1",
   "test_reflective_loader_tag": "@0.0.3",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
-  "unittest_tag": "@0.11.6",
   "usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
   "watcher_tag": "@0.9.7",
   "when_tag": "@0.2.0+2",
@@ -256,8 +255,6 @@
   Var("dart_root") + "/third_party/pkg/test_reflective_loader":
       (Var("github_mirror") % "test_reflective_loader") +
       Var("test_reflective_loader_tag"),
-  Var("dart_root") + "/third_party/pkg/unittest":
-      (Var("github_mirror") % "test") + Var("unittest_tag"),
   Var("dart_root") + "/third_party/pkg/usage":
       (Var("github_mirror") % "usage") + Var("usage_rev"),
   Var("dart_root") + "/third_party/pkg/utf":
@@ -384,6 +381,22 @@
     ],
   },
   {
+    "name": "unittest",
+    # Unittest is an early version, 0.11.6, of the package "test"
+    # Do not use it in any new tests.
+    "pattern": ".",
+    "action": [
+      "download_from_google_storage",
+      "--no_auth",
+      "--no_resume",
+      "--bucket",
+      "dart-dependencies",
+      "--extract",
+      "-s",
+      Var('dart_root') + "/third_party/pkg/unittest.tar.gz.sha1",
+    ],
+  },
+  {
     "name": "7zip",
     "pattern": ".",
     "action": [
diff --git a/dart.gyp b/dart.gyp
index 3e73877..a0c5a85 100644
--- a/dart.gyp
+++ b/dart.gyp
@@ -25,7 +25,7 @@
       'type': 'none',
       'dependencies': [
         'runtime/dart-runtime.gyp:dart',
-        'runtime/dart-runtime.gyp:dart_precompiled',
+        'runtime/dart-runtime.gyp:dart_precompiled_runtime',
         'runtime/dart-runtime.gyp:dart_no_snapshot',
         'runtime/dart-runtime.gyp:run_vm_tests',
         'runtime/dart-runtime.gyp:process_test',
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index fb3a9e4..25a0c0d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -1547,7 +1547,7 @@
 Any expression that appears within the initializer list of a constant constructor must be a potentially constant expression, or a compile-time error occurs. 
 
 \LMHash{}
-A {\em potentially constant expression} is an expression $e$ that would be a valid constant expression if all formal parameters of $e$'s immediately enclosing constant constructor were treated as compile-time constants that were guaranteed to evaluate to an integer, boolean or string value as required by their immediately enclosing superexpression.
+A {\em potentially constant expression} is an expression $e$ that would be a valid constant expression if all formal parameters of $e$'s immediately enclosing constant constructor were treated as compile-time constants that were guaranteed to evaluate to an integer, boolean or string value as required by their immediately enclosing superexpression, <em>and</em> where $e$ is also a valid expression if all the formal parameters are treated as non-constant variables.
 
 \commentary{
 Note that a parameter that is not used in a superexpression that is restricted to certain types can be a constant of any type. For example}
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index 2da3812..863ced0 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -61,7 +61,7 @@
       return Assist.EMPTY_LIST;
     }
     CompilationUnit unit =
-        analysisContext.resolveCompilationUnit2(source, libraries[0]);
+        analysisContext.getResolvedCompilationUnit2(source, libraries[0]);
     if (unit == null) {
       return Assist.EMPTY_LIST;
     }
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
index e8f7104..6ef1bed 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_dart.dart
@@ -44,7 +44,7 @@
       return Fix.EMPTY_LIST;
     }
     CompilationUnit unit =
-        analysisContext.resolveCompilationUnit2(source, libraries[0]);
+        analysisContext.getResolvedCompilationUnit2(source, libraries[0]);
     if (unit == null) {
       return Fix.EMPTY_LIST;
     }
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 45467ca..02c4f70 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     show HoverInformation;
+import 'package:analysis_server/src/computer/computer_overrides.dart';
 import 'package:analysis_server/src/utilities/documentation.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -69,7 +70,6 @@
             hover.containingLibraryPath = library.source.fullName;
           }
         }
-
         // documentation
         hover.dartdoc = _computeDocumentation(element);
       }
@@ -91,7 +91,23 @@
     if (element is ParameterElement) {
       element = element.enclosingElement;
     }
-    return removeDartDocDelimiters(element.documentationComment);
+    // The documentation of the element itself.
+    if (element.documentationComment != null) {
+      return removeDartDocDelimiters(element.documentationComment);
+    }
+    // Look for documentation comments of overridden members.
+    OverriddenElements overridden = findOverriddenElements(element);
+    for (Element superElement in []
+      ..addAll(overridden.superElements)
+      ..addAll(overridden.interfaceElements)) {
+      String rawDoc = superElement.documentationComment;
+      if (rawDoc != null) {
+        Element interfaceClass = superElement.enclosingElement;
+        return removeDartDocDelimiters(rawDoc) +
+            '\n\nCopied from `${interfaceClass.displayName}`.';
+      }
+    }
+    return null;
   }
 
   static _safeToString(obj) => obj != null ? obj.toString() : null;
diff --git a/pkg/analysis_server/lib/src/computer/computer_overrides.dart b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
index 4e2e00b..4eb93d1 100644
--- a/pkg/analysis_server/lib/src/computer/computer_overrides.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_overrides.dart
@@ -5,15 +5,106 @@
 library computer.overrides;
 
 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:analysis_server/src/protocol_server.dart' as proto;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/ast.dart';
 
 /**
+ * Return the elements that the given [element] overrides.
+ */
+OverriddenElements findOverriddenElements(Element element) {
+  if (element?.enclosingElement is ClassElement) {
+    return new _OverriddenElementsFinder(element).find();
+  }
+  return new OverriddenElements(element, <Element>[], <Element>[]);
+}
+
+/**
  * A computer for class member overrides in a Dart [CompilationUnit].
  */
 class DartUnitOverridesComputer {
+  final CompilationUnit _unit;
+  final List<proto.Override> _overrides = <proto.Override>[];
+
+  DartUnitOverridesComputer(this._unit);
+
+  /**
+   * Returns the computed occurrences, not `null`.
+   */
+  List<proto.Override> compute() {
+    for (CompilationUnitMember unitMember in _unit.declarations) {
+      if (unitMember is ClassDeclaration) {
+        for (ClassMember classMember in unitMember.members) {
+          if (classMember is MethodDeclaration) {
+            if (classMember.isStatic) {
+              continue;
+            }
+            _addOverride(classMember.name);
+          }
+          if (classMember is FieldDeclaration) {
+            if (classMember.isStatic) {
+              continue;
+            }
+            List<VariableDeclaration> fields = classMember.fields.variables;
+            for (VariableDeclaration field in fields) {
+              _addOverride(field.name);
+            }
+          }
+        }
+      }
+    }
+    return _overrides;
+  }
+
+  /**
+   * Add a new [Override] for the declaration with the given name [node].
+   */
+  void _addOverride(SimpleIdentifier node) {
+    Element element = node.staticElement;
+    OverriddenElements overridesResult =
+        new _OverriddenElementsFinder(element).find();
+    List<Element> superElements = overridesResult.superElements;
+    List<Element> interfaceElements = overridesResult.interfaceElements;
+    if (superElements.isNotEmpty || interfaceElements.isNotEmpty) {
+      proto.OverriddenMember superMember = superElements.isNotEmpty
+          ? proto.newOverriddenMember_fromEngine(superElements.first)
+          : null;
+      List<proto.OverriddenMember> interfaceMembers = interfaceElements
+          .map((member) => proto.newOverriddenMember_fromEngine(member))
+          .toList();
+      _overrides.add(new proto.Override(node.offset, node.length,
+          superclassMember: superMember,
+          interfaceMembers: nullIfEmpty(interfaceMembers)));
+    }
+  }
+}
+
+/**
+ * The container with elements that a class member overrides.
+ */
+class OverriddenElements {
+  /**
+   * The element that overrides other class members.
+   */
+  final Element element;
+
+  /**
+   * The elements that [element] overrides and which is defined in a class that
+   * is a superclass of the class that defines [element].
+   */
+  final List<Element> superElements;
+
+  /**
+   * The elements that [element] overrides and which is defined in a class that
+   * which is implemented by the class that defines [element].
+   */
+  final List<Element> interfaceElements;
+
+  OverriddenElements(this.element, this.superElements, this.interfaceElements);
+}
+
+class _OverriddenElementsFinder {
   static const List<ElementKind> FIELD_KINDS = const <ElementKind>[
     ElementKind.FIELD,
     ElementKind.GETTER,
@@ -34,138 +125,102 @@
     ElementKind.SETTER
   ];
 
-  final CompilationUnit _unit;
+  Element _seed;
+  LibraryElement _library;
+  ClassElement _class;
+  String _name;
+  List<ElementKind> _kinds;
 
-  final List<Override> _overrides = <Override>[];
-  engine.ClassElement _currentClass;
+  List<Element> _superElements = <Element>[];
+  List<Element> _interfaceElements = <Element>[];
+  Set<InterfaceType> _visited = new Set<InterfaceType>();
 
-  DartUnitOverridesComputer(this._unit);
-
-  /**
-   * Returns the computed occurrences, not `null`.
-   */
-  List<Override> compute() {
-    for (CompilationUnitMember unitMember in _unit.declarations) {
-      if (unitMember is ClassDeclaration) {
-        _currentClass = unitMember.element;
-        for (ClassMember classMember in unitMember.members) {
-          if (classMember is MethodDeclaration) {
-            if (classMember.isStatic) {
-              continue;
-            }
-            SimpleIdentifier nameNode = classMember.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) {
-              continue;
-            }
-            List<VariableDeclaration> fields = classMember.fields.variables;
-            for (VariableDeclaration field in fields) {
-              SimpleIdentifier nameNode = field.name;
-              _addOverride(
-                  nameNode.offset, nameNode.length, nameNode.name, FIELD_KINDS);
-            }
-          }
-        }
-      }
+  _OverriddenElementsFinder(Element seed) {
+    _seed = seed;
+    _class = seed.enclosingElement;
+    _library = _class.library;
+    _name = seed.displayName;
+    if (seed is MethodElement) {
+      _kinds = METHOD_KINDS;
+    } else if (seed is PropertyAccessorElement) {
+      _kinds = seed.isGetter ? GETTER_KINDS : SETTER_KINDS;
+    } else {
+      _kinds = FIELD_KINDS;
     }
-    return _overrides;
   }
 
-  void _addInterfaceOverrides(
-      Set<engine.Element> elements,
-      String name,
-      List<ElementKind> kinds,
-      engine.InterfaceType type,
-      bool checkType,
-      Set<engine.InterfaceType> visited) {
+  /**
+   * Add the [OverriddenElements] for this element.
+   */
+  OverriddenElements find() {
+    _visited.clear();
+    _addSuperOverrides(_class.supertype);
+    _visited.clear();
+    _addInterfaceOverrides(_class.type, false);
+    _superElements.forEach(_interfaceElements.remove);
+    return new OverriddenElements(_seed, _superElements, _interfaceElements);
+  }
+
+  void _addInterfaceOverrides(InterfaceType type, bool checkType) {
     if (type == null) {
       return;
     }
-    if (!visited.add(type)) {
+    if (!_visited.add(type)) {
       return;
     }
-    // check type
+    // this type
     if (checkType) {
-      engine.Element element = _lookupMember(type.element, name, kinds);
-      if (element != null) {
-        elements.add(element);
-        return;
-      }
-    }
-    // check interfaces
-    for (engine.InterfaceType interfaceType in type.interfaces) {
-      _addInterfaceOverrides(
-          elements, name, kinds, interfaceType, true, visited);
-    }
-    // check super
-    _addInterfaceOverrides(
-        elements, name, kinds, type.superclass, checkType, visited);
-  }
-
-  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, kinds);
+      Element element = _lookupMember(type.element);
+      if (element != null && !_interfaceElements.contains(element)) {
+        _interfaceElements.add(element);
       }
     }
     // interfaces
-    Set<engine.Element> interfaceEngineElements = new Set<engine.Element>();
-    _addInterfaceOverrides(interfaceEngineElements, name, kinds,
-        _currentClass.type, false, new Set<engine.InterfaceType>());
-    interfaceEngineElements.remove(superEngineElement);
-    // is there any override?
-    if (superEngineElement != null || interfaceEngineElements.isNotEmpty) {
-      OverriddenMember superMember = superEngineElement != null
-          ? newOverriddenMember_fromEngine(superEngineElement)
-          : null;
-      List<OverriddenMember> interfaceMembers = interfaceEngineElements
-          .map((member) => newOverriddenMember_fromEngine(member))
-          .toList();
-      _overrides.add(new Override(offset, length,
-          superclassMember: superMember,
-          interfaceMembers: nullIfEmpty(interfaceMembers)));
+    for (InterfaceType interfaceType in type.interfaces) {
+      _addInterfaceOverrides(interfaceType, true);
     }
+    // super
+    _addInterfaceOverrides(type.superclass, checkType);
   }
 
-  static engine.Element _lookupMember(
-      engine.ClassElement classElement, String name, List<ElementKind> kinds) {
+  void _addSuperOverrides(InterfaceType type) {
+    if (type == null) {
+      return;
+    }
+    if (!_visited.add(type)) {
+      return;
+    }
+    // this type
+    Element element = _lookupMember(type.element);
+    if (element != null && !_superElements.contains(element)) {
+      _superElements.add(element);
+    }
+    // super
+    _addSuperOverrides(type.superclass);
+  }
+
+  Element _lookupMember(ClassElement classElement) {
     if (classElement == null) {
       return null;
     }
-    engine.LibraryElement library = classElement.library;
-    engine.Element member;
+    Element member;
     // method
-    if (kinds.contains(ElementKind.METHOD)) {
-      member = classElement.lookUpMethod(name, library);
+    if (_kinds.contains(ElementKind.METHOD)) {
+      member = classElement.lookUpMethod(_name, _library);
       if (member != null) {
         return member;
       }
     }
     // getter
-    if (kinds.contains(ElementKind.GETTER)) {
-      member = classElement.lookUpGetter(name, library);
+    if (_kinds.contains(ElementKind.GETTER)) {
+      member = classElement.lookUpGetter(_name, _library);
       if (member != null) {
         return member;
       }
     }
     // setter
-    if (kinds.contains(ElementKind.SETTER)) {
-      member = classElement.lookUpSetter(name + '=', library);
+    if (_kinds.contains(ElementKind.SETTER)) {
+      member = classElement.lookUpSetter(_name + '=', _library);
       if (member != null) {
         return member;
       }
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 5391d5e..42e7213 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/implemented_dart.dart
@@ -57,21 +57,23 @@
     if (element.isSynthetic || _isStatic(element)) {
       return;
     }
-    String name = element.displayName;
-    if (name != null && _hasOverride(name)) {
+    if (_hasOverride(element)) {
       _addImplementedMember(element);
     }
   }
 
-  bool _hasOverride(String name) {
+  bool _hasOverride(Element element) {
+    String name = element.displayName;
+    LibraryElement library = element.library;
     for (ClassElement subtype in subtypes) {
-      MethodElement method = subtype.getMethod(name);
-      if (method != null) {
-        return !method.isStatic;
+      ClassMemberElement subElement = subtype.getMethod(name);
+      if (subElement == null) {
+        subElement = subtype.getField(name);
       }
-      FieldElement field = subtype.getField(name);
-      if (field != null) {
-        return !field.isStatic;
+      if (subElement != null &&
+          !subElement.isStatic &&
+          subElement.isAccessibleIn(library)) {
+        return true;
       }
     }
     return false;
diff --git a/pkg/analysis_server/lib/src/search/type_hierarchy.dart b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
index 793e471..e723722 100644
--- a/pkg/analysis_server/lib/src/search/type_hierarchy.dart
+++ b/pkg/analysis_server/lib/src/search/type_hierarchy.dart
@@ -175,7 +175,7 @@
         result = clazz.getSetter(_pivotName);
       }
     }
-    if (result != null) {
+    if (result != null && result.isAccessibleIn(_pivotLibrary)) {
       return result;
     }
     // try to find in the class mixin
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 5833af4..664ab74 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -46,8 +46,9 @@
   // create logger
   if (spec == 'console') {
     logger = new StringSinkLogger(stdout);
-  }
-  if (spec.startsWith('file:')) {
+  } else if (spec == 'stderr') {
+    logger = new StringSinkLogger(stderr);
+  } else if (spec.startsWith('file:')) {
     String fileName = spec.substring('file:'.length);
     File file = new File(fileName);
     IOSink sink = file.openWrite();
@@ -485,7 +486,7 @@
         defaultsTo: false,
         negatable: false);
     parser.addOption(INCREMENTAL_RESOLUTION_LOG,
-        help: "the description of the incremental resolution log");
+        help: "set a destination for the incremental resolver's log");
     parser.addFlag(INCREMENTAL_RESOLUTION_VALIDATION,
         help: "enable validation of incremental resolution results (slow)",
         defaultsTo: false,
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 a683638..13714ae 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -1092,17 +1092,15 @@
     Block targetBlock;
     {
       Statement statement = node.getAncestor((n) => n is Statement);
-      prefix = utils.getNodePrefix(statement);
       if (statement is IfStatement && statement.thenStatement is Block) {
         targetBlock = statement.thenStatement;
-      }
-      if (statement is WhileStatement && statement.body is Block) {
+      } else if (statement is WhileStatement && statement.body is Block) {
         targetBlock = statement.body;
+      } else {
+        _coverageMarker();
+        return;
       }
-    }
-    if (targetBlock == null) {
-      _coverageMarker();
-      return;
+      prefix = utils.getNodePrefix(statement);
     }
     // prepare location
     int offset;
diff --git a/pkg/analysis_server/lib/src/services/correction/strings.dart b/pkg/analysis_server/lib/src/services/correction/strings.dart
index 1689c7c..4a0ff76 100644
--- a/pkg/analysis_server/lib/src/services/correction/strings.dart
+++ b/pkg/analysis_server/lib/src/services/correction/strings.dart
@@ -201,6 +201,10 @@
   return str == null || str.isEmpty;
 }
 
+bool isEOL(int c) {
+  return c == 0x0D || c == 0x0A;
+}
+
 bool isLetter(int c) {
   return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A);
 }
@@ -220,7 +224,7 @@
 }
 
 bool isWhitespace(int c) {
-  return isSpace(c) || c == 0x0D || c == 0x0A;
+  return isSpace(c) || isEOL(c);
 }
 
 String remove(String str, String remove) {
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 33a3105..63aefd9 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -396,17 +396,14 @@
  */
 Expression getNodeQualifier(SimpleIdentifier node) {
   AstNode parent = node.parent;
-  if (parent is PropertyAccess) {
-    PropertyAccess propertyAccess = parent;
-    if (identical(propertyAccess.propertyName, node)) {
-      return propertyAccess.target;
-    }
+  if (parent is MethodInvocation && identical(parent.methodName, node)) {
+    return parent.target;
   }
-  if (parent is PrefixedIdentifier) {
-    PrefixedIdentifier prefixed = parent;
-    if (identical(prefixed.identifier, node)) {
-      return prefixed.prefix;
-    }
+  if (parent is PropertyAccess && identical(parent.propertyName, node)) {
+    return parent.target;
+  }
+  if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
+    return parent.prefix;
   }
   return null;
 }
@@ -667,7 +664,8 @@
     AstNode enclosingNode = findNode(offset);
     Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
     if (enclosingBlock != null) {
-      _CollectReferencedUnprefixedNames visitor = new _CollectReferencedUnprefixedNames();
+      _CollectReferencedUnprefixedNames visitor =
+          new _CollectReferencedUnprefixedNames();
       enclosingBlock.accept(visitor);
       return visitor.names;
     }
@@ -906,10 +904,14 @@
    * Returns a [SourceRange] that covers [range] and extends (if possible) to
    * cover whole lines.
    */
-  SourceRange getLinesRange(SourceRange range) {
+  SourceRange getLinesRange(SourceRange range,
+      {bool skipLeadingEmptyLines: false}) {
     // start
     int startOffset = range.offset;
     int startLineOffset = getLineContentStart(startOffset);
+    if (skipLeadingEmptyLines) {
+      startLineOffset = skipEmptyLinesLeft(startLineOffset);
+    }
     // end
     int endOffset = range.end;
     int afterEndLineOffset = getLineContentEnd(endOffset);
@@ -1224,6 +1226,27 @@
   }
 
   /**
+   * Skip spaces, tabs and EOLs on the left from [index].
+   *
+   * If [index] is the start of a method, then in the most cases return the end
+   * of the previous not-whitespace line.
+   */
+  int skipEmptyLinesLeft(int index) {
+    int lastLine = index;
+    while (index > 0) {
+      int c = _buffer.codeUnitAt(index - 1);
+      if (!isWhitespace(c)) {
+        return lastLine;
+      }
+      if (isEOL(c)) {
+        lastLine = index;
+      }
+      index--;
+    }
+    return 0;
+  }
+
+  /**
    * @return the [ImportElement] used to import given [Element] into [library].
    *         May be `null` if was not imported, i.e. declared in the same library.
    */
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 3b3c786..125c7ba 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/inline_method.dart
@@ -102,7 +102,7 @@
     }
   });
   // replace static field "qualifier" with invocation target
-  part._staticFieldOffsets.forEach((String className, List<int> offsets) {
+  part._implicitClassNameOffsets.forEach((String className, List<int> offsets) {
     for (int offset in offsets) {
 //      edits.add(newSourceEdit_range(range, className + '.'));
       edits.add(new SourceEdit(offset, 0, className + '.'));
@@ -263,7 +263,8 @@
     // delete method
     if (deleteSource && inlineAll) {
       SourceRange methodRange = rangeNode(_methodNode);
-      SourceRange linesRange = _methodUtils.getLinesRange(methodRange);
+      SourceRange linesRange =
+          _methodUtils.getLinesRange(methodRange, skipLeadingEmptyLines: true);
       doSourceChange_addElementEdit(
           change, _methodElement, newSourceEdit_range(linesRange, ''));
     }
@@ -682,9 +683,9 @@
   final List<int> _implicitThisOffsets = [];
 
   /**
-   * The offsets of the implicit class references in static field references.
+   * The offsets of the implicit class references in static member references.
    */
-  final Map<String, List<int>> _staticFieldOffsets = {};
+  final Map<String, List<int>> _implicitClassNameOffsets = {};
 
   _SourcePart(this._base, this._source, this._prefix);
 
@@ -692,6 +693,15 @@
     _explicitThisOffsets.add(offset - _base);
   }
 
+  void addImplicitClassNameOffset(String className, int offset) {
+    List<int> offsets = _implicitClassNameOffsets[className];
+    if (offsets == null) {
+      offsets = [];
+      _implicitClassNameOffsets[className] = offsets;
+    }
+    offsets.add(offset - _base);
+  }
+
   void addImplicitThisOffset(int offset) {
     _implicitThisOffsets.add(offset - _base);
   }
@@ -709,15 +719,6 @@
     }
   }
 
-  void addStaticFieldOffset(String className, int offset) {
-    List<int> offsets = _staticFieldOffsets[className];
-    if (offsets == null) {
-      offsets = [];
-      _staticFieldOffsets[className] = offsets;
-    }
-    offsets.add(offset - _base);
-  }
-
   void addVariable(VariableElement element, SourceRange range) {
     List<SourceRange> ranges = _variables[element];
     if (ranges == null) {
@@ -765,7 +766,7 @@
   visitSimpleIdentifier(SimpleIdentifier node) {
     SourceRange nodeRange = rangeNode(node);
     if (bodyRange.covers(nodeRange)) {
-      _addInstanceFieldQualifier(node);
+      _addMemberQualifier(node);
       _addParameter(node);
       _addVariable(node);
     }
@@ -779,19 +780,28 @@
     }
   }
 
-  void _addInstanceFieldQualifier(SimpleIdentifier node) {
-    PropertyAccessorElement accessor = getPropertyAccessorElement(node);
-    if (isFieldAccessorElement(accessor)) {
-      AstNode qualifier = getNodeQualifier(node);
-      if (qualifier == null) {
-        int offset = node.offset;
-        if (accessor.isStatic) {
-          String className = accessor.enclosingElement.displayName;
-          result.addStaticFieldOffset(className, offset);
-        } else {
-          result.addImplicitThisOffset(offset);
-        }
-      }
+  void _addMemberQualifier(SimpleIdentifier node) {
+    // should be unqualified
+    AstNode qualifier = getNodeQualifier(node);
+    if (qualifier != null) {
+      return;
+    }
+    // should be a method or field reference
+    Element element = node.staticElement;
+    if (!(element is MethodElement || element is PropertyAccessorElement)) {
+      return;
+    }
+    if (element.enclosingElement is! ClassElement) {
+      return;
+    }
+    // record the implicit static or instance reference
+    ExecutableElement member = element;
+    int offset = node.offset;
+    if (member.isStatic) {
+      String className = member.enclosingElement.displayName;
+      result.addImplicitClassNameOffset(className, offset);
+    } else {
+      result.addImplicitThisOffset(offset);
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 7260013..b20d642 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -65,10 +65,10 @@
   int totalDocSpan = 0;
 
   void visit(Element element) {
-    SourceRange docRange = element.docRange;
-    if (docRange != null) {
+    String comment = element.documentationComment;
+    if (comment != null) {
       ++elementsWithDocs;
-      totalDocSpan += docRange.length;
+      totalDocSpan += comment.length;
     }
 
     Type type = element.runtimeType;
@@ -639,8 +639,16 @@
           Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
           Map<String, int> sourceTypeCounts = new HashMap<String, int>();
           Map<String, int> typeCounts = new HashMap<String, int>();
+          int explicitSourceCount = 0;
+          int explicitLineInfoCount = 0;
+          int explicitLineCount = 0;
+          int implicitSourceCount = 0;
+          int implicitLineInfoCount = 0;
+          int implicitLineCount = 0;
           analysisServer.folderMap
               .forEach((Folder folder, InternalAnalysisContext context) {
+            Set<Source> explicitSources = new HashSet<Source>();
+            Set<Source> implicitSources = new HashSet<Source>();
             AnalysisCache cache = context.analysisCache;
             MapIterator<AnalysisTarget, CacheEntry> iterator = cache.iterator();
             while (iterator.moveNext()) {
@@ -651,8 +659,10 @@
                   String sourceName;
                   if (AnalysisEngine.isDartFileName(name)) {
                     if (iterator.value.explicitlyAdded) {
+                      explicitSources.add(target);
                       sourceName = 'Dart file (explicit)';
                     } else {
+                      implicitSources.add(target);
                       sourceName = 'Dart file (implicit)';
                     }
                   } else if (AnalysisEngine.isHtmlFileName(name)) {
@@ -677,6 +687,26 @@
                 }
               }
             }
+
+            int lineCount(Set<Source> sources, bool explicit) {
+              return sources.fold(0, (int previousTotal, Source source) {
+                LineInfo lineInfo = context.getLineInfo(source);
+                if (lineInfo is LineInfoWithCount) {
+                  if (explicit) {
+                    explicitLineInfoCount++;
+                  } else {
+                    implicitLineInfoCount++;
+                  }
+                  return previousTotal + lineInfo.lineCount;
+                } else {
+                  return previousTotal;
+                }
+              });
+            }
+            explicitSourceCount += explicitSources.length;
+            explicitLineCount += lineCount(explicitSources, true);
+            implicitSourceCount += implicitSources.length;
+            implicitLineCount += lineCount(implicitSources, false);
           });
           List<String> sourceTypeNames = sourceTypeCounts.keys.toList();
           sourceTypeNames.sort();
@@ -697,6 +727,37 @@
                 classes: [null, "right"]);
           }
           buffer.write('</table>');
+
+          buffer.write('<p><b>Line counts</b></p>');
+          buffer.write(
+              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+          _writeRow(buffer, ['Kind', 'Lines of Code', 'Source Counts'],
+              header: true);
+          _writeRow(buffer, [
+            'Explicit',
+            explicitLineCount.toString(),
+            '$explicitLineInfoCount / $explicitSourceCount'
+          ], classes: [
+            null,
+            "right"
+          ]);
+          _writeRow(buffer, [
+            'Implicit',
+            implicitLineCount.toString(),
+            '$implicitLineInfoCount / $implicitSourceCount'
+          ], classes: [
+            null,
+            "right"
+          ]);
+          _writeRow(buffer, [
+            'Total',
+            (explicitLineCount + implicitLineCount).toString(),
+            '${explicitLineInfoCount + implicitLineInfoCount} / ${explicitSourceCount + implicitSourceCount}'
+          ], classes: [
+            null,
+            "right"
+          ]);
+          buffer.write('</table>');
         }, (StringBuffer buffer) {
           //
           // Write task model timing information.
@@ -1293,9 +1354,16 @@
           buffer.write('<p><b>Error Processor count</b>: $processorCount</p>');
         });
 
-        _writeFiles(buffer, 'Priority Files', priorityNames);
-        _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
-        _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
+        _writeFiles(
+            buffer, 'Priority Files (${priorityNames.length})', priorityNames);
+        _writeFiles(
+            buffer,
+            'Explicitly Analyzed Files (${explicitNames.length})',
+            explicitNames);
+        _writeFiles(
+            buffer,
+            'Implicitly Analyzed Files (${implicitNames.length})',
+            implicitNames);
 
         buffer.write('<h3>Exceptions</h3>');
         if (exceptions.isEmpty) {
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index cc1a4e4..672e9f2 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -96,6 +96,71 @@
     expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
   }
 
+  test_dartdoc_inherited_methodByMethod_fromInterface() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {} // in A
+}
+
+class B implements A {
+  m() {} // in B
+}
+''');
+    HoverInformation hover = await prepareHover('m() {} // in B');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_inherited_methodByMethod_fromSuper_direct() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {} // in A
+}
+
+class B extends A {
+  m() {} // in B
+}
+''');
+    HoverInformation hover = await prepareHover('m() {} // in B');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_inherited_methodByMethod_fromSuper_indirect() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {}
+}
+class B extends A {
+  m() {}
+}
+class C extends B {
+  m() {} // in C
+}''');
+    HoverInformation hover = await prepareHover('m() {} // in C');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
+  test_dartdoc_inherited_methodByMethod_preferSuper() async {
+    addTestFile('''
+class A {
+  /// my doc
+  m() {}
+}
+class B extends A {
+}
+class I {
+  // wrong doc
+  m() {}
+}
+class C extends B implements I {
+  m() {} // in C
+}''');
+    HoverInformation hover = await prepareHover('m() {} // in C');
+    expect(hover.dartdoc, '''my doc\n\nCopied from `A`.''');
+  }
+
   test_enum() async {
     addTestFile('''
 enum MyEnum {AAA, BBB, CCC}
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index d5cde86..ab0e0c1 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -276,6 +276,38 @@
     assertHasImplementedMember('m() {} // A');
   }
 
+  test_method_withMethod_private_differentLib() async {
+    addFile(
+        '$testFolder/lib.dart',
+        r'''
+import 'test.dart';
+class B extends A {
+  void _m() {}
+}
+''');
+    addTestFile('''
+class A {
+  _m() {} // A
+}
+''');
+    await prepareImplementedElements();
+    assertNoImplementedMember('_m() {} // A');
+  }
+
+  test_method_withMethod_private_sameLibrary() async {
+    addTestFile('''
+class A {
+  _m() {} // A
+}
+class B extends A {
+  _m() {} // B
+}
+''');
+    await prepareImplementedElements();
+    assertHasImplementedMember('_m() {} // A');
+    assertNoImplementedMember('_m() {} // B');
+  }
+
   test_method_withMethod_wasAbstract() async {
     addTestFile('''
 abstract class A {
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index ae7551e..61db513 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -229,6 +229,24 @@
     assertNoOverride('fff(x) {} // B');
   }
 
+  test_BAD_privateByPrivate_inDifferentLib() async {
+    addFile(
+        '$testFolder/lib.dart',
+        r'''
+class A {
+  void _m() {}
+}
+''');
+    addTestFile('''
+import 'lib.dart';
+class B extends A {
+  void _m() {} // in B
+}
+''');
+    await prepareOverrides();
+    assertNoOverride('_m() {} // in B');
+  }
+
   test_BAD_setterByGetter() async {
     addTestFile('''
 class A {
@@ -352,7 +370,7 @@
 ''');
     await prepareOverrides();
     assertHasOverride('m() {} // in C');
-    expect(override.interfaceMembers, hasLength(1));
+    expect(override.interfaceMembers, hasLength(2));
     assertHasInterfaceMember('m() {} // in B');
   }
 
@@ -514,6 +532,21 @@
     assertNoInterfaceMembers();
   }
 
+  test_super_method_privateByPrivate() async {
+    addTestFile('''
+class A {
+  _m() {} // in A
+}
+class B extends A {
+  _m() {} // in B
+}
+''');
+    await prepareOverrides();
+    assertHasOverride('_m() {} // in B');
+    assertHasSuperElement('_m() {} // in A');
+    assertNoInterfaceMembers();
+  }
+
   test_super_method_superTypeCycle() async {
     addTestFile('''
 class A extends B {
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 5c0616e..4faf108 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -32,7 +32,8 @@
     int c = search.codeUnitAt(length);
     if (!(c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0) ||
         c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0) ||
-        c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0))) {
+        c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0) ||
+        c == '_'.codeUnitAt(0))) {
       break;
     }
     length++;
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index f6eff47..c332aa9 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -14,6 +14,7 @@
 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_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/services/lint.dart';
@@ -366,7 +367,8 @@
     // Sanity check embedder libs.
     var source = context.sourceFactory.forUri('dart:foobar');
     expect(source, isNotNull);
-    expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
+    expect(source.fullName,
+        '/my/proj/sdk_ext/entry.dart'.replaceAll('/', JavaFile.separator));
   }
 
   test_embedder_packagespec() async {
@@ -403,7 +405,8 @@
     var context = contexts[0];
     var source = context.sourceFactory.forUri('dart:foobar');
     expect(source, isNotNull);
-    expect(source.fullName, equals('/my/proj/sdk_ext/entry.dart'));
+    expect(source.fullName,
+        '/my/proj/sdk_ext/entry.dart'.replaceAll('/', JavaFile.separator));
     // We can't find dart:core because we didn't list it in our
     // embedder_libs map.
     expect(context.sourceFactory.forUri('dart:core'), isNull);
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index f234463..e0a6867 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -71,14 +71,15 @@
       var request = new DiagnosticGetDiagnosticsParams().toRequest('0');
       var response = handler.handleRequest(request);
 
-      int fileCount = MockSdk.LIBRARIES.length + 1 /* test.dart */;
+      int fileCount = 1 /* test.dart */;
 
       var json = response.toJson()[Response.RESULT];
       expect(json['contexts'], hasLength(1));
       var context = json['contexts'][0];
       expect(context['name'], '/project');
       expect(context['explicitFileCount'], fileCount);
-      expect(context['implicitFileCount'], 0);
+      // dart:core dart:async dart:math dart:_internal
+      expect(context['implicitFileCount'], 4);
       expect(context['workItemQueueLength'], isNotNull);
     });
 
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 1fbb426..c43ef63 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -222,12 +222,6 @@
       _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
-      ChangeSet changeSet = new ChangeSet();
-      for (String uri in uris) {
-        Source source = factory.forUri(uri);
-        changeSet.addedSource(source);
-      }
-      _analysisContext.applyChanges(changeSet);
     }
     return _analysisContext;
   }
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 1d6ddf9a..c8b62dd 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -186,8 +186,9 @@
 class C extends A {}
 ''');
     // configure roots
-    Request request = new AnalysisSetAnalysisRootsParams(
-        [projectPath, '/packages/pkgA'], []).toRequest('0');
+    Request request =
+        new AnalysisSetAnalysisRootsParams([projectPath, '/packages/pkgA'], [])
+            .toRequest('0');
     handleSuccessfulRequest(request);
     // test A type hierarchy
     List<TypeHierarchyItem> items = await _getTypeHierarchy('A {}');
@@ -699,6 +700,66 @@
         itemD.memberElement.location.offset, findOffset('test() {} // in D'));
   }
 
+  test_member_method_private_differentLib() async {
+    addFile(
+        '$testFolder/lib.dart',
+        r'''
+import 'test.dart';
+class A {
+  void _m() {}
+}
+class C extends B {
+  void _m() {}
+}
+''');
+    addTestFile('''
+import 'lib.dart';
+class B extends A {
+  _m() {} // in B
+}
+class D extends C {
+  _m() {} // in D
+}
+''');
+    List<TypeHierarchyItem> items = await _getTypeHierarchy('_m() {} // in B');
+    var itemB = items[0];
+    var itemA = items[itemB.superclass];
+    var itemC = items[itemB.subclasses[0]];
+    var itemD = items[itemC.subclasses[0]];
+    expect(itemB.classElement.name, 'B');
+    expect(itemA.classElement.name, 'A');
+    expect(itemC.classElement.name, 'C');
+    expect(itemD.classElement.name, 'D');
+    expect(itemA.memberElement, isNull);
+    expect(itemC.memberElement, isNull);
+    expect(itemB.memberElement, isNotNull);
+    expect(itemD.memberElement, isNotNull);
+  }
+
+  test_member_method_private_sameLib() async {
+    addTestFile('''
+class A {
+  _m() {} // in A
+}
+class B extends A {
+  _m() {} // in B
+}
+class C extends B {
+  _m() {} // in C
+}
+''');
+    List<TypeHierarchyItem> items = await _getTypeHierarchy('_m() {} // in B');
+    var itemB = items[0];
+    var itemA = items[itemB.superclass];
+    var itemC = items[itemB.subclasses[0]];
+    expect(itemA.classElement.name, 'A');
+    expect(itemB.classElement.name, 'B');
+    expect(itemC.classElement.name, 'C');
+    expect(itemA.memberElement.location.offset, findOffset('_m() {} // in A'));
+    expect(itemB.memberElement.location.offset, findOffset('_m() {} // in B'));
+    expect(itemC.memberElement.location.offset, findOffset('_m() {} // in C'));
+  }
+
   test_member_ofMixin2_method() async {
     addTestFile('''
 class M1 {
@@ -963,8 +1024,9 @@
 
   test_superOnly_fileDoesNotExist() async {
     Request request = new SearchGetTypeHierarchyParams(
-        '/does/not/exist.dart', 0,
-        superOnly: true).toRequest(requestId);
+            '/does/not/exist.dart', 0,
+            superOnly: true)
+        .toRequest(requestId);
     Response response = await serverChannel.sendRequest(request);
     List<TypeHierarchyItem> items =
         new SearchGetTypeHierarchyResult.fromResponse(response).hierarchyItems;
@@ -973,7 +1035,8 @@
 
   Request _createGetTypeHierarchyRequest(String search, {bool superOnly}) {
     return new SearchGetTypeHierarchyParams(testFile, findOffset(search),
-        superOnly: superOnly).toRequest(requestId);
+            superOnly: superOnly)
+        .toRequest(requestId);
   }
 
   Future<List<TypeHierarchyItem>> _getTypeHierarchy(String search,
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index ed3d7d3..859f248 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -2379,6 +2379,15 @@
     await assertNoAssistAt('if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
   }
 
+  test_introduceLocalTestedType_BAD_notStatement() async {
+    resolveTestUnit('''
+class C {
+  bool b;
+  C(v) : b = v is int;
+}''');
+    await assertNoAssistAt('is int', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE);
+  }
+
   test_introduceLocalTestedType_OK_if_is() async {
     resolveTestUnit('''
 class MyTypeName {}
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index 8ff6c84..3433f1e 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -917,6 +917,81 @@
 ''');
   }
 
+  test_method_methodInstance() {
+    indexTestUnit(r'''
+class A {
+  ma() {}
+}
+class B extends A {
+  test() {
+    ma();
+    mb();
+  }
+  mb() {}
+}
+main(B b) {
+  b.test();
+}
+''');
+    _createRefactoring('test();');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+class A {
+  ma() {}
+}
+class B extends A {
+  test() {
+    ma();
+    mb();
+  }
+  mb() {}
+}
+main(B b) {
+  b.ma();
+  b.mb();
+}
+''');
+  }
+
+  test_method_methodStatic() {
+    indexTestUnit(r'''
+class A {
+  static ma() {}
+}
+class B extends A {
+  static mb() {}
+  test() {
+    mb();
+    A.ma();
+    B.mb();
+  }
+}
+main(B b) {
+  b.test();
+}
+''');
+    _createRefactoring('test();');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+class A {
+  static ma() {}
+}
+class B extends A {
+  static mb() {}
+  test() {
+    mb();
+    A.ma();
+    B.mb();
+  }
+}
+main(B b) {
+  B.mb();
+  A.ma();
+  B.mb();
+}
+''');
+  }
+
   test_method_singleStatement() {
     indexTestUnit(r'''
 class A {
@@ -973,7 +1048,7 @@
 ''');
   }
 
-  test_method_unqualifiedUnvocation() {
+  test_method_unqualifiedInvocation() {
     indexTestUnit(r'''
 class A {
   test(a, b) {
@@ -1198,6 +1273,36 @@
 ''');
   }
 
+  test_removeEmptyLinesBefore_method() {
+    indexTestUnit(r'''
+class A {
+  before() {
+  }
+
+
+  test() {
+    print(0);
+  }
+
+  foo() {
+    test();
+  }
+}
+''');
+    _createRefactoring('test() {');
+    // validate change
+    return _assertSuccessfulRefactoring(r'''
+class A {
+  before() {
+  }
+
+  foo() {
+    print(0);
+  }
+}
+''');
+  }
+
   test_setter_classMember_instance() {
     indexTestUnit(r'''
 class A {
@@ -1361,7 +1466,7 @@
 ''');
   }
 
-  test_singleExpression_wrapIntoParenthesized_bools() {
+  test_singleExpression_wrapIntoParenthesized_bool() {
     indexTestUnit(r'''
 test(bool a, bool b) {
   return a || b;
diff --git a/pkg/analyzer/example/parser_driver.dart b/pkg/analyzer/example/parser_driver.dart
index 8fdf1a9..2e082b7 100644
--- a/pkg/analyzer/example/parser_driver.dart
+++ b/pkg/analyzer/example/parser_driver.dart
@@ -5,7 +5,8 @@
 
 import 'dart:io';
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index 74ed79c..fa2af7f 100755
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -5,8 +5,9 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.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/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index d0fdc65..78de42e 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -6,8 +6,8 @@
 
 import 'dart:io';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/error.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -15,8 +15,10 @@
 import 'package:analyzer/src/string_source.dart';
 import 'package:path/path.dart' as pathos;
 
+export 'package:analyzer/dart/ast/ast.dart';
+export 'package:analyzer/dart/ast/visitor.dart';
+export 'package:analyzer/src/dart/ast/utilities.dart';
 export 'package:analyzer/src/error.dart';
-export 'package:analyzer/src/generated/ast.dart';
 export 'package:analyzer/src/generated/error.dart';
 export 'package:analyzer/src/generated/utilities_dart.dart';
 
@@ -63,22 +65,6 @@
       suppressErrors: suppressErrors, parseFunctionBodies: parseFunctionBodies);
 }
 
-CompilationUnit _parseSource(String contents, Source source,
-    {bool suppressErrors: false, bool parseFunctionBodies: true}) {
-  var reader = new CharSequenceReader(contents);
-  var errorCollector = new _ErrorCollector();
-  var scanner = new Scanner(source, reader, errorCollector);
-  var token = scanner.tokenize();
-  var parser = new Parser(source, errorCollector)
-    ..parseFunctionBodies = parseFunctionBodies;
-  var unit = parser.parseCompilationUnit(token)
-    ..lineInfo = new LineInfo(scanner.lineStarts);
-
-  if (errorCollector.hasErrors && !suppressErrors) throw errorCollector.group;
-
-  return unit;
-}
-
 /// Parses the script tag and directives in a string of Dart code into an AST.
 ///
 /// Stops parsing when the first non-directive is encountered. The rest of the
@@ -111,6 +97,22 @@
   return literal.stringValue;
 }
 
+CompilationUnit _parseSource(String contents, Source source,
+    {bool suppressErrors: false, bool parseFunctionBodies: true}) {
+  var reader = new CharSequenceReader(contents);
+  var errorCollector = new _ErrorCollector();
+  var scanner = new Scanner(source, reader, errorCollector);
+  var token = scanner.tokenize();
+  var parser = new Parser(source, errorCollector)
+    ..parseFunctionBodies = parseFunctionBodies;
+  var unit = parser.parseCompilationUnit(token)
+    ..lineInfo = new LineInfo(scanner.lineStarts);
+
+  if (errorCollector.hasErrors && !suppressErrors) throw errorCollector.group;
+
+  return unit;
+}
+
 /// A simple error listener that collects errors into an [AnalysisErrorGroup].
 class _ErrorCollector extends AnalysisErrorListener {
   final _errors = <AnalysisError>[];
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
new file mode 100644
index 0000000..1237fd1
--- /dev/null
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -0,0 +1,7988 @@
+// 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.ast.ast;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart' show AuxiliaryElements;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * Two or more string literals that are implicitly concatenated because of being
+ * adjacent (separated only by whitespace).
+ *
+ * While the grammar only allows adjacent strings when all of the strings are of
+ * the same kind (single line or multi-line), this class doesn't enforce that
+ * restriction.
+ *
+ * > adjacentStrings ::=
+ * >     [StringLiteral] [StringLiteral]+
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AdjacentStrings extends StringLiteral {
+  /**
+   * Initialize a newly created list of adjacent strings. To be syntactically
+   * valid, the list of [strings] must contain at least two elements.
+   */
+  factory AdjacentStrings(List<StringLiteral> strings) = AdjacentStringsImpl;
+
+  /**
+   * Return the strings that are implicitly concatenated.
+   */
+  NodeList<StringLiteral> get strings;
+}
+
+/**
+ * An AST node that can be annotated with both a documentation comment and a
+ * list of annotations.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AnnotatedNode extends AstNode {
+  /**
+   * Return the documentation comment associated with this node, or `null` if
+   * this node does not have a documentation comment associated with it.
+   */
+  Comment get documentationComment;
+
+  /**
+   * Set the documentation comment associated with this node to the given
+   * [comment].
+   */
+  void set documentationComment(Comment comment);
+
+  /**
+   * Return the first token following the comment and metadata.
+   */
+  Token get firstTokenAfterCommentAndMetadata;
+
+  /**
+   * Return the annotations associated with this node.
+   */
+  NodeList<Annotation> get metadata;
+
+  /**
+   * Return a list containing the comment and annotations associated with this
+   * node, sorted in lexical order.
+   */
+  List<AstNode> get sortedCommentAndAnnotations;
+}
+
+/**
+ * An annotation that can be associated with an AST node.
+ *
+ * > metadata ::=
+ * >     annotation*
+ * >
+ * > annotation ::=
+ * >     '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Annotation extends AstNode {
+  /**
+   * Initialize a newly created annotation. Both the [period] and the
+   * [constructorName] can be `null` if the annotation is not referencing a
+   * named constructor. The [arguments] can be `null` if the annotation is not
+   * referencing a constructor.
+   */
+  factory Annotation(
+      Token atSign,
+      Identifier name,
+      Token period,
+      SimpleIdentifier constructorName,
+      ArgumentList arguments) = AnnotationImpl;
+
+  /**
+   * Return the arguments to the constructor being invoked, or `null` if this
+   * annotation is not the invocation of a constructor.
+   */
+  ArgumentList get arguments;
+
+  /**
+   * Set the arguments to the constructor being invoked to the given [arguments].
+   */
+  void set arguments(ArgumentList arguments);
+
+  /**
+   * Return the at sign that introduced the annotation.
+   */
+  Token get atSign;
+
+  /**
+   * Set the at sign that introduced the annotation to the given [token].
+   */
+  void set atSign(Token token);
+
+  /**
+   * Return the name of the constructor being invoked, or `null` if this
+   * annotation is not the invocation of a named constructor.
+   */
+  SimpleIdentifier get constructorName;
+
+  /**
+   * Set the name of the constructor being invoked to the given [name].
+   */
+  void set constructorName(SimpleIdentifier name);
+
+  /**
+   * Return the element associated with this annotation, or `null` if the AST
+   * structure has not been resolved or if this annotation could not be
+   * resolved.
+   */
+  Element get element;
+
+  /**
+   * Set the element associated with this annotation to the given [element].
+   */
+  void set element(Element element);
+
+  /**
+   * Return the element annotation representing this annotation in the element model.
+   */
+  ElementAnnotation get elementAnnotation;
+
+  /**
+   * Set the element annotation representing this annotation in the element
+   * model to the given [annotation].
+   */
+  void set elementAnnotation(ElementAnnotation annotation);
+
+  /**
+   * Return the name of the class defining the constructor that is being invoked
+   * or the name of the field that is being referenced.
+   */
+  Identifier get name;
+
+  /**
+   * Set the name of the class defining the constructor that is being invoked or
+   * the name of the field that is being referenced to the given [name].
+   */
+  void set name(Identifier name);
+
+  /**
+   * Return the period before the constructor name, or `null` if this annotation
+   * is not the invocation of a named constructor.
+   */
+  Token get period;
+
+  /**
+   * Set the period before the constructor name to the given [token].
+   */
+  void set period(Token token);
+}
+
+/**
+ * A list of arguments in the invocation of an executable element (that is, a
+ * function, method, or constructor).
+ *
+ * > argumentList ::=
+ * >     '(' arguments? ')'
+ * >
+ * > arguments ::=
+ * >     [NamedExpression] (',' [NamedExpression])*
+ * >   | [Expression] (',' [Expression])* (',' [NamedExpression])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ArgumentList extends AstNode {
+  /**
+   * Initialize a newly created list of arguments. The list of [arguments] can
+   * be `null` if there are no arguments.
+   */
+  factory ArgumentList(Token leftParenthesis, List<Expression> arguments,
+      Token rightParenthesis) = ArgumentListImpl;
+
+  /**
+   * Return the expressions producing the values of the arguments. Although the
+   * language requires that positional arguments appear before named arguments,
+   * this class allows them to be intermixed.
+   */
+  NodeList<Expression> get arguments;
+
+  /**
+   * Set the parameter elements corresponding to each of the arguments in this
+   * list to the given list of [parameters]. The list of parameters must be the
+   * same length as the number of arguments, but can contain `null` entries if a
+   * given argument does not correspond to a formal parameter.
+   */
+  void set correspondingPropagatedParameters(List<ParameterElement> parameters);
+
+  /**
+   * Set the parameter elements corresponding to each of the arguments in this
+   * list to the given list of [parameters]. The list of parameters must be the
+   * same length as the number of arguments, but can contain `null` entries if a
+   * given argument does not correspond to a formal parameter.
+   */
+  void set correspondingStaticParameters(List<ParameterElement> parameters);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+}
+
+/**
+ * An as expression.
+ *
+ * > asExpression ::=
+ * >     [Expression] 'as' [TypeName]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AsExpression extends Expression {
+  /**
+   * Initialize a newly created as expression.
+   */
+  factory AsExpression(Expression expression, Token asOperator, TypeName type) =
+      AsExpressionImpl;
+
+  /**
+   * Return the 'as' operator.
+   */
+  Token get asOperator;
+
+  /**
+   * Set the 'as' operator to the given [token].
+   */
+  void set asOperator(Token token);
+
+  /**
+   * Return the expression used to compute the value being cast.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression used to compute the value being cast to the given
+   * [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the name of the type being cast to.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the type being cast to to the given [name].
+   */
+  void set type(TypeName name);
+}
+
+/**
+ * An assert statement.
+ *
+ * > assertStatement ::=
+ * >     'assert' '(' [Expression] ')' ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AssertStatement extends Statement {
+  /**
+   * Initialize a newly created assert statement. The [comma] and [message] can
+   * be `null` if there is no message.
+   */
+  factory AssertStatement(
+      Token assertKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token comma,
+      Expression message,
+      Token rightParenthesis,
+      Token semicolon) = AssertStatementImpl;
+
+  /**
+   * Return the token representing the 'assert' keyword.
+   */
+  Token get assertKeyword;
+
+  /**
+   * Set the token representing the 'assert' keyword to the given [token].
+   */
+  void set assertKeyword(Token token);
+
+  /**
+   * Return the comma between the [condition] and the [message], or `null` if no
+   * message was supplied.
+   */
+  Token get comma;
+
+  /**
+   * Set the comma between the [condition] and the [message] to the given [token].
+   */
+  void set comma(Token token);
+
+  /**
+   * Return the condition that is being asserted to be `true`.
+   */
+  Expression get condition;
+
+  /**
+   * Set the condition that is being asserted to be `true` to the given
+   * [expression].
+   */
+  void set condition(Expression condition);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the message to report if the assertion fails, or `null` if no
+   * message was supplied.
+   */
+  Expression get message;
+
+  /**
+   * Set the message to report if the assertion fails to the given
+   * [expression].
+   */
+  void set message(Expression expression);
+
+  /**
+   *  Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   *  Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * An assignment expression.
+ *
+ * > assignmentExpression ::=
+ * >     [Expression] operator [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AssignmentExpression extends Expression {
+  /**
+   * Initialize a newly created assignment expression.
+   */
+  factory AssignmentExpression(
+          Expression leftHandSide, Token operator, Expression rightHandSide) =
+      AssignmentExpressionImpl;
+
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  MethodElement get bestElement;
+
+  /**
+   * Return the expression used to compute the left hand side.
+   */
+  Expression get leftHandSide;
+
+  /**
+   * Return the expression used to compute the left hand side.
+   */
+  void set leftHandSide(Expression expression);
+
+  /**
+   * Return the assignment operator being applied.
+   */
+  Token get operator;
+
+  /**
+   * Set the assignment operator being applied to the given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the element associated with the operator based on the propagated
+   * type of the left-hand-side, or `null` if the AST structure has not been
+   * resolved, if the operator is not a compound operator, or if the operator
+   * could not be resolved.
+   */
+  MethodElement get propagatedElement;
+
+  /**
+   * Set the element associated with the operator based on the propagated
+   * type of the left-hand-side to the given [element].
+   */
+  void set propagatedElement(MethodElement element);
+
+  /**
+   * Return the expression used to compute the right hand side.
+   */
+  Expression get rightHandSide;
+
+  /**
+   * Set the expression used to compute the left hand side to the given
+   * [expression].
+   */
+  void set rightHandSide(Expression expression);
+
+  /**
+   * Return the element associated with the operator based on the static type of
+   * the left-hand-side, or `null` if the AST structure has not been resolved,
+   * if the operator is not a compound operator, or if the operator could not be
+   * resolved.
+   */
+  MethodElement get staticElement;
+
+  /**
+   * Set the element associated with the operator based on the static type of
+   * the left-hand-side to the given [element].
+   */
+  void set staticElement(MethodElement element);
+}
+
+/**
+ * A node in the AST structure for a Dart program.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AstNode {
+  /**
+   * An empty list of AST nodes.
+   */
+  static const List<AstNode> EMPTY_LIST = const <AstNode>[];
+
+  /**
+   * A comparator that can be used to sort AST nodes in lexical order. In other
+   * words, `compare` will return a negative value if the offset of the first
+   * node is less than the offset of the second node, zero (0) if the nodes have
+   * the same offset, and a positive value if the offset of the first node is
+   * greater than the offset of the second node.
+   */
+  static Comparator<AstNode> LEXICAL_ORDER =
+      (AstNode first, AstNode second) => first.offset - second.offset;
+
+  /**
+   * Return the first token included in this node's source range.
+   */
+  Token get beginToken;
+
+  /**
+   * Return an iterator that can be used to iterate through all the entities
+   * (either AST nodes or tokens) that make up the contents of this node,
+   * including doc comments but excluding other comments.
+   */
+  Iterable/*<AstNode | Token>*/ get childEntities;
+
+  /**
+   * Return the offset of the character immediately following the last character
+   * of this node's source range. This is equivalent to
+   * `node.getOffset() + node.getLength()`. For a compilation unit this will be
+   * equal to the length of the unit's source. For synthetic nodes this will be
+   * equivalent to the node's offset (because the length is zero (0) by
+   * definition).
+   */
+  int get end;
+
+  /**
+   * Return the last token included in this node's source range.
+   */
+  Token get endToken;
+
+  /**
+   * Return `true` if this node is a synthetic node. A synthetic node is a node
+   * that was introduced by the parser in order to recover from an error in the
+   * code. Synthetic nodes always have a length of zero (`0`).
+   */
+  bool get isSynthetic;
+
+  /**
+   * Return the number of characters in the node's source range.
+   */
+  int get length;
+
+  /**
+   * Return the offset from the beginning of the file to the first character in
+   * the node's source range.
+   */
+  int get offset;
+
+  /**
+   * Return this node's parent node, or `null` if this node is the root of an
+   * AST structure.
+   *
+   * Note that the relationship between an AST node and its parent node may
+   * change over the lifetime of a node.
+   */
+  AstNode get parent;
+
+  /**
+   * Return the node at the root of this node's AST structure. Note that this
+   * method's performance is linear with respect to the depth of the node in the
+   * AST structure (O(depth)).
+   */
+  AstNode get root;
+
+  /**
+   * Use the given [visitor] to visit this node. Return the value returned by
+   * the visitor as a result of visiting this node.
+   */
+  dynamic /* =E */ accept/*<E>*/(AstVisitor/*<E>*/ visitor);
+
+  /**
+   * Return the most immediate ancestor of this node for which the [predicate]
+   * returns `true`, or `null` if there is no such ancestor. Note that this node
+   * will never be returned.
+   */
+  AstNode getAncestor(Predicate<AstNode> predicate);
+
+  /**
+   * Return the value of the property with the given [name], or `null` if this
+   * node does not have a property with the given name.
+   */
+  Object getProperty(String name);
+
+  /**
+   * Set the value of the property with the given [name] to the given [value].
+   * If the value is `null`, the property will effectively be removed.
+   */
+  void setProperty(String name, Object value);
+
+  /**
+   * Return a textual description of this node in a form approximating valid
+   * source. The returned string will not be valid source primarily in the case
+   * where the node itself is not well-formed.
+   */
+  String toSource();
+
+  /**
+   * Use the given [visitor] to visit all of the children of this node. The
+   * children will be visited in lexical order.
+   */
+  void visitChildren(AstVisitor visitor);
+}
+
+/**
+ * An object that can be used to visit an AST structure.
+ *
+ * Clients may extend or implement this class.
+ */
+abstract class AstVisitor<R> {
+  R visitAdjacentStrings(AdjacentStrings node);
+
+  R visitAnnotation(Annotation node);
+
+  R visitArgumentList(ArgumentList node);
+
+  R visitAsExpression(AsExpression node);
+
+  R visitAssertStatement(AssertStatement assertStatement);
+
+  R visitAssignmentExpression(AssignmentExpression node);
+
+  R visitAwaitExpression(AwaitExpression node);
+
+  R visitBinaryExpression(BinaryExpression node);
+
+  R visitBlock(Block node);
+
+  R visitBlockFunctionBody(BlockFunctionBody node);
+
+  R visitBooleanLiteral(BooleanLiteral node);
+
+  R visitBreakStatement(BreakStatement node);
+
+  R visitCascadeExpression(CascadeExpression node);
+
+  R visitCatchClause(CatchClause node);
+
+  R visitClassDeclaration(ClassDeclaration node);
+
+  R visitClassTypeAlias(ClassTypeAlias node);
+
+  R visitComment(Comment node);
+
+  R visitCommentReference(CommentReference node);
+
+  R visitCompilationUnit(CompilationUnit node);
+
+  R visitConditionalExpression(ConditionalExpression node);
+
+  R visitConfiguration(Configuration node);
+
+  R visitConstructorDeclaration(ConstructorDeclaration node);
+
+  R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
+
+  R visitConstructorName(ConstructorName node);
+
+  R visitContinueStatement(ContinueStatement node);
+
+  R visitDeclaredIdentifier(DeclaredIdentifier node);
+
+  R visitDefaultFormalParameter(DefaultFormalParameter node);
+
+  R visitDoStatement(DoStatement node);
+
+  R visitDottedName(DottedName node);
+
+  R visitDoubleLiteral(DoubleLiteral node);
+
+  R visitEmptyFunctionBody(EmptyFunctionBody node);
+
+  R visitEmptyStatement(EmptyStatement node);
+
+  R visitEnumConstantDeclaration(EnumConstantDeclaration node);
+
+  R visitEnumDeclaration(EnumDeclaration node);
+
+  R visitExportDirective(ExportDirective node);
+
+  R visitExpressionFunctionBody(ExpressionFunctionBody node);
+
+  R visitExpressionStatement(ExpressionStatement node);
+
+  R visitExtendsClause(ExtendsClause node);
+
+  R visitFieldDeclaration(FieldDeclaration node);
+
+  R visitFieldFormalParameter(FieldFormalParameter node);
+
+  R visitForEachStatement(ForEachStatement node);
+
+  R visitFormalParameterList(FormalParameterList node);
+
+  R visitForStatement(ForStatement node);
+
+  R visitFunctionDeclaration(FunctionDeclaration node);
+
+  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
+
+  R visitFunctionExpression(FunctionExpression node);
+
+  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node);
+
+  R visitFunctionTypeAlias(FunctionTypeAlias functionTypeAlias);
+
+  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node);
+
+  R visitHideCombinator(HideCombinator node);
+
+  R visitIfStatement(IfStatement node);
+
+  R visitImplementsClause(ImplementsClause node);
+
+  R visitImportDirective(ImportDirective node);
+
+  R visitIndexExpression(IndexExpression node);
+
+  R visitInstanceCreationExpression(InstanceCreationExpression node);
+
+  R visitIntegerLiteral(IntegerLiteral node);
+
+  R visitInterpolationExpression(InterpolationExpression node);
+
+  R visitInterpolationString(InterpolationString node);
+
+  R visitIsExpression(IsExpression node);
+
+  R visitLabel(Label node);
+
+  R visitLabeledStatement(LabeledStatement node);
+
+  R visitLibraryDirective(LibraryDirective node);
+
+  R visitLibraryIdentifier(LibraryIdentifier node);
+
+  R visitListLiteral(ListLiteral node);
+
+  R visitMapLiteral(MapLiteral node);
+
+  R visitMapLiteralEntry(MapLiteralEntry node);
+
+  R visitMethodDeclaration(MethodDeclaration node);
+
+  R visitMethodInvocation(MethodInvocation node);
+
+  R visitNamedExpression(NamedExpression node);
+
+  R visitNativeClause(NativeClause node);
+
+  R visitNativeFunctionBody(NativeFunctionBody node);
+
+  R visitNullLiteral(NullLiteral node);
+
+  R visitParenthesizedExpression(ParenthesizedExpression node);
+
+  R visitPartDirective(PartDirective node);
+
+  R visitPartOfDirective(PartOfDirective node);
+
+  R visitPostfixExpression(PostfixExpression node);
+
+  R visitPrefixedIdentifier(PrefixedIdentifier node);
+
+  R visitPrefixExpression(PrefixExpression node);
+
+  R visitPropertyAccess(PropertyAccess node);
+
+  R visitRedirectingConstructorInvocation(
+      RedirectingConstructorInvocation node);
+
+  R visitRethrowExpression(RethrowExpression node);
+
+  R visitReturnStatement(ReturnStatement node);
+
+  R visitScriptTag(ScriptTag node);
+
+  R visitShowCombinator(ShowCombinator node);
+
+  R visitSimpleFormalParameter(SimpleFormalParameter node);
+
+  R visitSimpleIdentifier(SimpleIdentifier node);
+
+  R visitSimpleStringLiteral(SimpleStringLiteral node);
+
+  R visitStringInterpolation(StringInterpolation node);
+
+  R visitSuperConstructorInvocation(SuperConstructorInvocation node);
+
+  R visitSuperExpression(SuperExpression node);
+
+  R visitSwitchCase(SwitchCase node);
+
+  R visitSwitchDefault(SwitchDefault node);
+
+  R visitSwitchStatement(SwitchStatement node);
+
+  R visitSymbolLiteral(SymbolLiteral node);
+
+  R visitThisExpression(ThisExpression node);
+
+  R visitThrowExpression(ThrowExpression node);
+
+  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node);
+
+  R visitTryStatement(TryStatement node);
+
+  R visitTypeArgumentList(TypeArgumentList node);
+
+  R visitTypeName(TypeName node);
+
+  R visitTypeParameter(TypeParameter node);
+
+  R visitTypeParameterList(TypeParameterList node);
+
+  R visitVariableDeclaration(VariableDeclaration node);
+
+  R visitVariableDeclarationList(VariableDeclarationList node);
+
+  R visitVariableDeclarationStatement(VariableDeclarationStatement node);
+
+  R visitWhileStatement(WhileStatement node);
+
+  R visitWithClause(WithClause node);
+
+  R visitYieldStatement(YieldStatement node);
+}
+
+/**
+ * An await expression.
+ *
+ * > awaitExpression ::=
+ * >     'await' [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class AwaitExpression extends Expression {
+  /**
+   * Initialize a newly created await expression.
+   */
+  factory AwaitExpression(Token awaitKeyword, Expression expression) =
+      AwaitExpressionImpl;
+
+  /**
+   * Return the 'await' keyword.
+   */
+  Token get awaitKeyword;
+
+  /**
+   * Set the 'await' keyword to the given [token].
+   */
+  void set awaitKeyword(Token token);
+
+  /**
+   * Return the expression whose value is being waited on.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression whose value is being waited on to the given [expression].
+   */
+  void set expression(Expression expression);
+}
+
+/**
+ * A binary (infix) expression.
+ *
+ * > binaryExpression ::=
+ * >     [Expression] [Token] [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class BinaryExpression extends Expression {
+  /**
+   * Initialize a newly created binary expression.
+   */
+  factory BinaryExpression(
+          Expression leftOperand, Token operator, Expression rightOperand) =
+      BinaryExpressionImpl;
+
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  MethodElement get bestElement;
+
+  /**
+   * Return the expression used to compute the left operand.
+   */
+  Expression get leftOperand;
+
+  /**
+   * Set the expression used to compute the left operand to the given
+   * [expression].
+   */
+  void set leftOperand(Expression expression);
+
+  /**
+   * Return the binary operator being applied.
+   */
+  Token get operator;
+
+  /**
+   * Set the binary operator being applied to the given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the element associated with the operator based on the propagated
+   * type of the left operand, or `null` if the AST structure has not been
+   * resolved, if the operator is not user definable, or if the operator could
+   * not be resolved.
+   */
+  MethodElement get propagatedElement;
+
+  /**
+   * Set the element associated with the operator based on the propagated
+   * type of the left operand to the given [element].
+   */
+  void set propagatedElement(MethodElement element);
+
+  /**
+   * Return the expression used to compute the right operand.
+   */
+  Expression get rightOperand;
+
+  /**
+   * Set the expression used to compute the right operand to the given
+   * [expression].
+   */
+  void set rightOperand(Expression expression);
+
+  /**
+   * Return the element associated with the operator based on the static type of
+   * the left operand, or `null` if the AST structure has not been resolved, if
+   * the operator is not user definable, or if the operator could not be
+   * resolved.
+   */
+  MethodElement get staticElement;
+
+  /**
+   * Set the element associated with the operator based on the static type of
+   * the left operand to the given [element].
+   */
+  void set staticElement(MethodElement element);
+}
+
+/**
+ * A sequence of statements.
+ *
+ * > block ::=
+ * >     '{' statement* '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Block extends Statement {
+  /**
+   * Initialize a newly created block of code.
+   */
+  factory Block(
+          Token leftBracket, List<Statement> statements, Token rightBracket) =
+      BlockImpl;
+
+  /**
+   * Return the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left curly bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+
+  /**
+   * Return the statements contained in the block.
+   */
+  NodeList<Statement> get statements;
+}
+
+/**
+ * A function body that consists of a block of statements.
+ *
+ * > blockFunctionBody ::=
+ * >     ('async' | 'async' '*' | 'sync' '*')? [Block]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class BlockFunctionBody extends FunctionBody {
+  /**
+   * Initialize a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if there is no keyword specified
+   * for the block. The [star] can be `null` if there is no star following the
+   * keyword (and must be `null` if there is no keyword).
+   */
+  factory BlockFunctionBody(Token keyword, Token star, Block block) =
+      BlockFunctionBodyImpl;
+
+  /**
+   * Return the block representing the body of the function.
+   */
+  Block get block;
+
+  /**
+   * Set the block representing the body of the function to the given [block].
+   */
+  void set block(Block block);
+
+  /**
+   * Set token representing the 'async' or 'sync' keyword to the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Set the star following the 'async' or 'sync' keyword to the given [token].
+   */
+  void set star(Token token);
+}
+
+/**
+ * A boolean literal expression.
+ *
+ * > booleanLiteral ::=
+ * >     'false' | 'true'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class BooleanLiteral extends Literal {
+  /**
+   * Initialize a newly created boolean literal.
+   */
+  factory BooleanLiteral(Token literal, bool value) = BooleanLiteralImpl;
+
+  /**
+   * Return the token representing the literal.
+   */
+  Token get literal;
+
+  /**
+   * Set the token representing the literal to the given [token].
+   */
+  void set literal(Token token);
+
+  /**
+   * Return the value of the literal.
+   */
+  bool get value;
+}
+
+/**
+ * A break statement.
+ *
+ * > breakStatement ::=
+ * >     'break' [SimpleIdentifier]? ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class BreakStatement extends Statement {
+  /**
+   * Initialize a newly created break statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  factory BreakStatement(
+          Token breakKeyword, SimpleIdentifier label, Token semicolon) =
+      BreakStatementImpl;
+
+  /**
+   * Return the token representing the 'break' keyword.
+   */
+  Token get breakKeyword;
+
+  /**
+   * Set the token representing the 'break' keyword to the given [token].
+   */
+  void set breakKeyword(Token token);
+
+  /**
+   * Return the label associated with the statement, or `null` if there is no
+   * label.
+   */
+  SimpleIdentifier get label;
+
+  /**
+   * Set the label associated with the statement to the given [identifier].
+   */
+  void set label(SimpleIdentifier identifier);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the node from which this break statement is breaking. This will be
+   * either a [Statement] (in the case of breaking out of a loop), a
+   * [SwitchMember] (in the case of a labeled break statement whose label
+   * matches a label on a switch case in an enclosing switch statement), or
+   * `null` if the AST has not yet been resolved or if the target could not be
+   * resolved. Note that if the source code has errors, the target might be
+   * invalid (e.g. trying to break to a switch case).
+   */
+  AstNode get target;
+
+  /**
+   * Set the node from which this break statement is breaking to the given
+   * [node].
+   */
+  void set target(AstNode node);
+}
+
+/**
+ * A sequence of cascaded expressions: expressions that share a common target.
+ * There are three kinds of expressions that can be used in a cascade
+ * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
+ *
+ * > cascadeExpression ::=
+ * >     [Expression] cascadeSection*
+ * >
+ * > cascadeSection ::=
+ * >     '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
+ * >     (assignmentOperator expressionWithoutCascade)?
+ * >
+ * > cascadeSelector ::=
+ * >     '[ ' expression '] '
+ * >   | identifier
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CascadeExpression extends Expression {
+  /**
+   * Initialize a newly created cascade expression. The list of
+   * [cascadeSections] must contain at least one element.
+   */
+  factory CascadeExpression(
+          Expression target, List<Expression> cascadeSections) =
+      CascadeExpressionImpl;
+
+  /**
+   * Return the cascade sections sharing the common target.
+   */
+  NodeList<Expression> get cascadeSections;
+
+  /**
+   * Return the target of the cascade sections.
+   */
+  Expression get target;
+
+  /**
+   * Set the target of the cascade sections to the given [expression].
+   */
+  void set target(Expression target);
+}
+
+/**
+ * A catch clause within a try statement.
+ *
+ * > onPart ::=
+ * >     catchPart [Block]
+ * >   | 'on' type catchPart? [Block]
+ * >
+ * > catchPart ::=
+ * >     'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CatchClause extends AstNode {
+  /**
+   * Initialize a newly created catch clause. The [onKeyword] and
+   * [exceptionType] can be `null` if the clause will catch all exceptions. The
+   * [comma] and [stackTraceParameter] can be `null` if the stack trace
+   * parameter is not defined.
+   */
+  factory CatchClause(
+      Token onKeyword,
+      TypeName exceptionType,
+      Token catchKeyword,
+      Token leftParenthesis,
+      SimpleIdentifier exceptionParameter,
+      Token comma,
+      SimpleIdentifier stackTraceParameter,
+      Token rightParenthesis,
+      Block body) = CatchClauseImpl;
+
+  /**
+   * Return the body of the catch block.
+   */
+  Block get body;
+
+  /**
+   * Set the body of the catch block to the given [block].
+   */
+  void set body(Block block);
+
+  /**
+   * Return the token representing the 'catch' keyword, or `null` if there is no
+   * 'catch' keyword.
+   */
+  Token get catchKeyword;
+
+  /**
+   * Set the token representing the 'catch' keyword to the given [token].
+   */
+  void set catchKeyword(Token token);
+
+  /**
+   * Return the comma separating the exception parameter from the stack trace
+   * parameter, or `null` if there is no stack trace parameter.
+   */
+  Token get comma;
+
+  /**
+   * Set the comma separating the exception parameter from the stack trace
+   * parameter to the given [token].
+   */
+  void set comma(Token token);
+
+  /**
+   * Return the parameter whose value will be the exception that was thrown, or
+   * `null` if there is no 'catch' keyword.
+   */
+  SimpleIdentifier get exceptionParameter;
+
+  /**
+   * Set the parameter whose value will be the exception that was thrown to the
+   * given [parameter].
+   */
+  void set exceptionParameter(SimpleIdentifier parameter);
+
+  /**
+   * Return the type of exceptions caught by this catch clause, or `null` if
+   * this catch clause catches every type of exception.
+   */
+  TypeName get exceptionType;
+
+  /**
+   * Set the type of exceptions caught by this catch clause to the given
+   * [exceptionType].
+   */
+  void set exceptionType(TypeName exceptionType);
+
+  /**
+   * Return the left parenthesis, or `null` if there is no 'catch' keyword.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the token representing the 'on' keyword, or `null` if there is no 'on'
+   * keyword.
+   */
+  Token get onKeyword;
+
+  /**
+   * Set the token representing the 'on' keyword to the given [token].
+   */
+  void set onKeyword(Token token);
+
+  /**
+   * Return the right parenthesis, or `null` if there is no 'catch' keyword.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the parameter whose value will be the stack trace associated with
+   * the exception, or `null` if there is no stack trace parameter.
+   */
+  SimpleIdentifier get stackTraceParameter;
+
+  /**
+   * Set the parameter whose value will be the stack trace associated with the
+   * exception to the given [parameter].
+   */
+  void set stackTraceParameter(SimpleIdentifier parameter);
+}
+
+/**
+ * The declaration of a class.
+ *
+ * > classDeclaration ::=
+ * >     'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
+ * >     ([ExtendsClause] [WithClause]?)?
+ * >     [ImplementsClause]?
+ * >     '{' [ClassMember]* '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassDeclaration extends NamedCompilationUnitMember {
+  /**
+   * Initialize a newly created class declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the class does not have the
+   * corresponding attribute. The [abstractKeyword] can be `null` if the class
+   * is not abstract. The [typeParameters] can be `null` if the class does not
+   * have any type parameters. Any or all of the [extendsClause], [withClause],
+   * and [implementsClause] can be `null` if the class does not have the
+   * corresponding clause. The list of [members] can be `null` if the class does
+   * not have any members.
+   */
+  factory ClassDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token abstractKeyword,
+      Token classKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      ExtendsClause extendsClause,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      Token leftBracket,
+      List<ClassMember> members,
+      Token rightBracket) = ClassDeclarationImpl;
+
+  /**
+   * Return the 'abstract' keyword, or `null` if the keyword was absent.
+   */
+  Token get abstractKeyword;
+
+  /**
+   * Set the 'abstract' keyword to the given [token].
+   */
+  void set abstractKeyword(Token token);
+
+  /**
+   * Return the token representing the 'class' keyword to the given [token].
+   */
+  Token get classKeyword;
+
+  /**
+   * Set the token representing the 'class' keyword.
+   */
+  void set classKeyword(Token token);
+
+  @override
+  ClassElement get element;
+
+  /**
+   * Return the extends clause for this class, or `null` if the class does not
+   * extend any other class.
+   */
+  ExtendsClause get extendsClause;
+
+  /**
+   * Set the extends clause for this class to the given [extendsClause].
+   */
+  void set extendsClause(ExtendsClause extendsClause);
+
+  /**
+   * Return the implements clause for the class, or `null` if the class does not
+   * implement any interfaces.
+   */
+  ImplementsClause get implementsClause;
+
+  /**
+   * Set the implements clause for the class to the given [implementsClause].
+   */
+  void set implementsClause(ImplementsClause implementsClause);
+
+  /**
+   * Return `true` if this class is declared to be an abstract class.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left curly bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the members defined by the class.
+   */
+  NodeList<ClassMember> get members;
+
+  /**
+   * Return the native clause for this class, or `null` if the class does not
+   * have a native clause.
+   */
+  NativeClause get nativeClause;
+
+  /**
+   * Set the native clause for this class to the given [nativeClause].
+   */
+  void set nativeClause(NativeClause nativeClause);
+
+  /**
+   * Return the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+
+  /**
+   * Return the type parameters for the class, or `null` if the class does not
+   * have any type parameters.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters for the class to the given list of [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+
+  /**
+   * Return the with clause for the class, or `null` if the class does not have
+   * a with clause.
+   */
+  WithClause get withClause;
+
+  /**
+   * Set the with clause for the class to the given [withClause].
+   */
+  void set withClause(WithClause withClause);
+
+  /**
+   * Return the constructor declared in the class with the given [name], or
+   * `null` if there is no such constructor. If the [name] is `null` then the
+   * default constructor will be searched for.
+   */
+  ConstructorDeclaration getConstructor(String name);
+
+  /**
+   * Return the field declared in the class with the given [name], or `null` if
+   * there is no such field.
+   */
+  VariableDeclaration getField(String name);
+
+  /**
+   * Return the method declared in the class with the given [name], or `null` if
+   * there is no such method.
+   */
+  MethodDeclaration getMethod(String name);
+}
+
+/**
+ * A node that declares a name within the scope of a class.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassMember extends Declaration {}
+
+/**
+ * A class type alias.
+ *
+ * > classTypeAlias ::=
+ * >     [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication
+ * >
+ * > mixinApplication ::=
+ * >     [TypeName] [WithClause] [ImplementsClause]? ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ClassTypeAlias extends TypeAlias {
+  /**
+   * Initialize a newly created class type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the class type alias does not
+   * have the corresponding attribute. The [typeParameters] can be `null` if the
+   * class does not have any type parameters. The [abstractKeyword] can be
+   * `null` if the class is not abstract. The [implementsClause] can be `null`
+   * if the class does not implement any interfaces.
+   */
+  factory ClassTypeAlias(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      Token equals,
+      Token abstractKeyword,
+      TypeName superclass,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      Token semicolon) = ClassTypeAliasImpl;
+
+  /**
+   * Return the token for the 'abstract' keyword, or `null` if this is not
+   * defining an abstract class.
+   */
+  Token get abstractKeyword;
+
+  /**
+   * Set the token for the 'abstract' keyword to the given [token].
+   */
+  void set abstractKeyword(Token token);
+
+  /**
+   * Return the token for the '=' separating the name from the definition.
+   */
+  Token get equals;
+
+  /**
+   * Set the token for the '=' separating the name from the definition to the
+   * given [token].
+   */
+  void set equals(Token token);
+
+  /**
+   * Return the implements clause for this class, or `null` if there is no
+   * implements clause.
+   */
+  ImplementsClause get implementsClause;
+
+  /**
+   * Set the implements clause for this class to the given [implementsClause].
+   */
+  void set implementsClause(ImplementsClause implementsClause);
+
+  /**
+   * Return `true` if this class is declared to be an abstract class.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return the name of the superclass of the class being declared.
+   */
+  TypeName get superclass;
+
+  /**
+   * Set the name of the superclass of the class being declared to the given
+   * [superclass] name.
+   */
+  void set superclass(TypeName superclass);
+
+  /**
+   * Return the type parameters for the class, or `null` if the class does not
+   * have any type parameters.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters for the class to the given list of [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+
+  /**
+   * Return the with clause for this class.
+   */
+  WithClause get withClause;
+
+  /**
+   * Set the with clause for this class to the given with [withClause].
+   */
+  void set withClause(WithClause withClause);
+}
+
+/**
+ * A combinator associated with an import or export directive.
+ *
+ * > combinator ::=
+ * >     [HideCombinator]
+ * >   | [ShowCombinator]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Combinator extends AstNode {
+  /**
+   * Return the 'hide' or 'show' keyword specifying what kind of processing is
+   * to be done on the names.
+   */
+  Token get keyword;
+
+  /**
+   * Set the 'hide' or 'show' keyword specifying what kind of processing is
+   * to be done on the names to the given [token].
+   */
+  void set keyword(Token token);
+}
+
+/**
+ * A comment within the source code.
+ *
+ * > comment ::=
+ * >     endOfLineComment
+ * >   | blockComment
+ * >   | documentationComment
+ * >
+ * > endOfLineComment ::=
+ * >     '//' (CHARACTER - EOL)* EOL
+ * >
+ * > blockComment ::=
+ * >     '/ *' CHARACTER* '&#42;/'
+ * >
+ * > documentationComment ::=
+ * >     '/ **' (CHARACTER | [CommentReference])* '&#42;/'
+ * >   | ('///' (CHARACTER - EOL)* EOL)+
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Comment extends AstNode {
+  /**
+   * Initialize a newly created comment. The list of [tokens] must contain at
+   * least one token. The [type] is the type of the comment. The list of
+   * [references] can be empty if the comment does not contain any embedded
+   * references.
+   */
+  factory Comment(List<Token> tokens, CommentType type,
+      List<CommentReference> references) = CommentImpl;
+
+  /**
+   * Return `true` if this is a block comment.
+   */
+  bool get isBlock;
+
+  /**
+   * Return `true` if this is a documentation comment.
+   */
+  bool get isDocumentation;
+
+  /**
+   * Return `true` if this is an end-of-line comment.
+   */
+  bool get isEndOfLine;
+
+  /**
+   * Return the references embedded within the documentation comment.
+   */
+  NodeList<CommentReference> get references;
+
+  /**
+   * Return the tokens representing the comment.
+   */
+  List<Token> get tokens;
+
+  /**
+   * Create a block comment consisting of the given [tokens].
+   */
+  static Comment createBlockComment(List<Token> tokens) =>
+      CommentImpl.createBlockComment(tokens);
+
+  /**
+   * Create a documentation comment consisting of the given [tokens].
+   */
+  static Comment createDocumentationComment(List<Token> tokens) =>
+      CommentImpl.createDocumentationComment(tokens);
+
+  /**
+   * Create a documentation comment consisting of the given [tokens] and having
+   * the given [references] embedded within it.
+   */
+  static Comment createDocumentationCommentWithReferences(
+          List<Token> tokens, List<CommentReference> references) =>
+      CommentImpl.createDocumentationCommentWithReferences(tokens, references);
+
+  /**
+   * Create an end-of-line comment consisting of the given [tokens].
+   */
+  static Comment createEndOfLineComment(List<Token> tokens) =>
+      CommentImpl.createEndOfLineComment(tokens);
+}
+
+/**
+ * A reference to a Dart element that is found within a documentation comment.
+ *
+ * > commentReference ::=
+ * >     '[' 'new'? [Identifier] ']'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CommentReference extends AstNode {
+  /**
+   * Initialize a newly created reference to a Dart element. The [newKeyword]
+   * can be `null` if the reference is not to a constructor.
+   */
+  factory CommentReference(Token newKeyword, Identifier identifier) =
+      CommentReferenceImpl;
+
+  /**
+   * Return the identifier being referenced.
+   */
+  Identifier get identifier;
+
+  /**
+   * Set the identifier being referenced to the given [identifier].
+   */
+  void set identifier(Identifier identifier);
+
+  /**
+   * Return the token representing the 'new' keyword, or `null` if there was no
+   * 'new' keyword.
+   */
+  Token get newKeyword;
+
+  /**
+   * Set the token representing the 'new' keyword to the given [token].
+   */
+  void set newKeyword(Token token);
+}
+
+/**
+ * A compilation unit.
+ *
+ * While the grammar restricts the order of the directives and declarations
+ * within a compilation unit, this class does not enforce those restrictions.
+ * In particular, the children of a compilation unit will be visited in lexical
+ * order even if lexical order does not conform to the restrictions of the
+ * grammar.
+ *
+ * > compilationUnit ::=
+ * >     directives declarations
+ * >
+ * > directives ::=
+ * >     [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
+ * >   | [PartOfDirective]
+ * >
+ * > namespaceDirective ::=
+ * >     [ImportDirective]
+ * >   | [ExportDirective]
+ * >
+ * > declarations ::=
+ * >     [CompilationUnitMember]*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CompilationUnit extends AstNode {
+  /**
+   * Initialize a newly created compilation unit to have the given directives
+   * and declarations. The [scriptTag] can be `null` if there is no script tag
+   * in the compilation unit. The list of [directives] can be `null` if there
+   * are no directives in the compilation unit. The list of [declarations] can
+   * be `null` if there are no declarations in the compilation unit.
+   */
+  factory CompilationUnit(
+      Token beginToken,
+      ScriptTag scriptTag,
+      List<Directive> directives,
+      List<CompilationUnitMember> declarations,
+      Token endToken) = CompilationUnitImpl;
+
+  /**
+   * Set the first token included in this node's source range to the given
+   * [token].
+   */
+  void set beginToken(Token token);
+
+  /**
+   * Return the declarations contained in this compilation unit.
+   */
+  NodeList<CompilationUnitMember> get declarations;
+
+  /**
+   * Return the directives contained in this compilation unit.
+   */
+  NodeList<Directive> get directives;
+
+  /**
+   * Return the element associated with this compilation unit, or `null` if the
+   * AST structure has not been resolved.
+   */
+  CompilationUnitElement get element;
+
+  /**
+   * Set the element associated with this compilation unit to the given
+   * [element].
+   */
+  void set element(CompilationUnitElement element);
+
+  /**
+   * Set the last token included in this node's source range to the given
+   * [token].
+   */
+  void set endToken(Token token);
+
+  /**
+   * Return the line information for this compilation unit.
+   */
+  LineInfo get lineInfo;
+
+  /**
+   * Set the line information for this compilation unit to the given [info].
+   */
+  void set lineInfo(LineInfo info);
+
+  /**
+   * Return the script tag at the beginning of the compilation unit, or `null`
+   * if there is no script tag in this compilation unit.
+   */
+  ScriptTag get scriptTag;
+
+  /**
+   * Set the script tag at the beginning of the compilation unit to the given
+   * [scriptTag].
+   */
+  void set scriptTag(ScriptTag scriptTag);
+
+  /**
+   * Return a list containing all of the directives and declarations in this
+   * compilation unit, sorted in lexical order.
+   */
+  List<AstNode> get sortedDirectivesAndDeclarations;
+}
+
+/**
+ * A node that declares one or more names within the scope of a compilation
+ * unit.
+ *
+ * > compilationUnitMember ::=
+ * >     [ClassDeclaration]
+ * >   | [TypeAlias]
+ * >   | [FunctionDeclaration]
+ * >   | [MethodDeclaration]
+ * >   | [VariableDeclaration]
+ * >   | [VariableDeclaration]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CompilationUnitMember extends Declaration {}
+
+/**
+ * A conditional expression.
+ *
+ * > conditionalExpression ::=
+ * >     [Expression] '?' [Expression] ':' [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConditionalExpression extends Expression {
+  /**
+   * Initialize a newly created conditional expression.
+   */
+  factory ConditionalExpression(
+      Expression condition,
+      Token question,
+      Expression thenExpression,
+      Token colon,
+      Expression elseExpression) = ConditionalExpressionImpl;
+
+  /**
+   * Return the token used to separate the then expression from the else
+   * expression.
+   */
+  Token get colon;
+
+  /**
+   * Set the token used to separate the then expression from the else expression
+   * to the given [token].
+   */
+  void set colon(Token token);
+
+  /**
+   * Return the condition used to determine which of the expressions is executed
+   * next.
+   */
+  Expression get condition;
+
+  /**
+   * Set the condition used to determine which of the expressions is executed
+   * next to the given [expression].
+   */
+  void set condition(Expression expression);
+
+  /**
+   * Return the expression that is executed if the condition evaluates to
+   * `false`.
+   */
+  Expression get elseExpression;
+
+  /**
+   * Set the expression that is executed if the condition evaluates to `false`
+   * to the given [expression].
+   */
+  void set elseExpression(Expression expression);
+
+  /**
+   * Return the token used to separate the condition from the then expression.
+   */
+  Token get question;
+
+  /**
+   * Set the token used to separate the condition from the then expression to
+   * the given [token].
+   */
+  void set question(Token token);
+
+  /**
+   * Return the expression that is executed if the condition evaluates to
+   * `true`.
+   */
+  Expression get thenExpression;
+
+  /**
+   * Set the expression that is executed if the condition evaluates to `true` to
+   * the given [expression].
+   */
+  void set thenExpression(Expression expression);
+}
+
+/**
+ * A configuration in either an import or export directive.
+ *
+ * > configuration ::=
+ * >     'if' '(' test ')' uri
+ * >
+ * > test ::=
+ * >     dottedName ('==' stringLiteral)?
+ * >
+ * > dottedName ::=
+ * >     identifier ('.' identifier)*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Configuration extends AstNode {
+  /**
+   * Initialize a newly created configuration.
+   */
+  factory Configuration(
+      Token ifKeyword,
+      Token leftParenthesis,
+      DottedName name,
+      Token equalToken,
+      StringLiteral value,
+      Token rightParenthesis,
+      StringLiteral libraryUri) = ConfigurationImpl;
+
+  /**
+   * Return the token for the equal operator, or `null` if the condition does
+   * not include an equality test.
+   */
+  Token get equalToken;
+
+  /**
+   * Set the token for the equal operator to the given [token].
+   */
+  void set equalToken(Token token);
+
+  /**
+   * Return the token for the 'if' keyword.
+   */
+  Token get ifKeyword;
+
+  /**
+   * Set the token for the 'if' keyword to the given [token].
+   */
+  void set ifKeyword(Token token);
+
+  /**
+   * Return the token for the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the token for the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the URI of the implementation library to be used if the condition is
+   * true.
+   */
+  StringLiteral get libraryUri;
+
+  /**
+   * Set the URI of the implementation library to be used if the condition is
+   * true to the given [uri].
+   */
+  void set libraryUri(StringLiteral uri);
+
+  /**
+   * Return the name of the declared variable whose value is being used in the
+   * condition.
+   */
+  DottedName get name;
+
+  /**
+   * Set the name of the declared variable whose value is being used in the
+   * condition to the given [name].
+   */
+  void set name(DottedName name);
+
+  /**
+   * Return the token for the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the token for the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the value to which the value of the declared variable will be
+   * compared, or `null` if the condition does not include an equality test.
+   */
+  StringLiteral get value;
+
+  /**
+   * Set the value to which the value of the declared variable will be
+   * compared to the given [value].
+   */
+  void set value(StringLiteral value);
+}
+
+/**
+ * A constructor declaration.
+ *
+ * > constructorDeclaration ::=
+ * >     constructorSignature [FunctionBody]?
+ * >   | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments
+ * >
+ * > constructorSignature ::=
+ * >     'external'? constructorName formalParameterList initializerList?
+ * >   | 'external'? 'factory' factoryName formalParameterList initializerList?
+ * >   | 'external'? 'const'  constructorName formalParameterList initializerList?
+ * >
+ * > constructorName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])?
+ * >
+ * > factoryName ::=
+ * >     [Identifier] ('.' [SimpleIdentifier])?
+ * >
+ * > initializerList ::=
+ * >     ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorDeclaration extends ClassMember {
+  /**
+   * Initialize a newly created constructor declaration. The [externalKeyword]
+   * can be `null` if the constructor is not external. Either or both of the
+   * [comment] and [metadata] can be `null` if the constructor does not have the
+   * corresponding attribute. The [constKeyword] can be `null` if the
+   * constructor cannot be used to create a constant. The [factoryKeyword] can
+   * be `null` if the constructor is not a factory. The [period] and [name] can
+   * both be `null` if the constructor is not a named constructor. The
+   * [separator] can be `null` if the constructor does not have any initializers
+   * and does not redirect to a different constructor. The list of
+   * [initializers] can be `null` if the constructor does not have any
+   * initializers. The [redirectedConstructor] can be `null` if the constructor
+   * does not redirect to a different constructor. The [body] can be `null` if
+   * the constructor does not have a body.
+   */
+  factory ConstructorDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      Token constKeyword,
+      Token factoryKeyword,
+      Identifier returnType,
+      Token period,
+      SimpleIdentifier name,
+      FormalParameterList parameters,
+      Token separator,
+      List<ConstructorInitializer> initializers,
+      ConstructorName redirectedConstructor,
+      FunctionBody body) = ConstructorDeclarationImpl;
+
+  /**
+   * Return the body of the constructor, or `null` if the constructor does not
+   * have a body.
+   */
+  FunctionBody get body;
+
+  /**
+   * Set the body of the constructor to the given [functionBody].
+   */
+  void set body(FunctionBody functionBody);
+
+  /**
+   * Return the token for the 'const' keyword, or `null` if the constructor is
+   * not a const constructor.
+   */
+  Token get constKeyword;
+
+  /**
+   * Set the token for the 'const' keyword to the given [token].
+   */
+  void set constKeyword(Token token);
+
+  @override
+  ConstructorElement get element;
+
+  /**
+   * Set the element associated with this constructor to the given [element].
+   */
+  void set element(ConstructorElement element);
+
+  /**
+   * Return the token for the 'external' keyword to the given [token].
+   */
+  Token get externalKeyword;
+
+  /**
+   * Set the token for the 'external' keyword, or `null` if the constructor
+   * is not external.
+   */
+  void set externalKeyword(Token token);
+
+  /**
+   * Return the token for the 'factory' keyword, or `null` if the constructor is
+   * not a factory constructor.
+   */
+  Token get factoryKeyword;
+
+  /**
+   * Set the token for the 'factory' keyword to the given [token].
+   */
+  void set factoryKeyword(Token token);
+
+  /**
+   * Return the initializers associated with the constructor.
+   */
+  NodeList<ConstructorInitializer> get initializers;
+
+  /**
+   * Return the name of the constructor, or `null` if the constructor being
+   * declared is unnamed.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the constructor to the given [identifier].
+   */
+  void set name(SimpleIdentifier identifier);
+
+  /**
+   * Return the parameters associated with the constructor.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters associated with the constructor to the given list of
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the token for the period before the constructor name, or `null` if
+   * the constructor being declared is unnamed.
+   */
+  Token get period;
+
+  /**
+   * Set the token for the period before the constructor name to the given
+   * [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the name of the constructor to which this constructor will be
+   * redirected, or `null` if this is not a redirecting factory constructor.
+   */
+  ConstructorName get redirectedConstructor;
+
+  /**
+   * Set the name of the constructor to which this constructor will be
+   * redirected to the given [redirectedConstructor] name.
+   */
+  void set redirectedConstructor(ConstructorName redirectedConstructor);
+
+  /**
+   * Return the type of object being created. This can be different than the
+   * type in which the constructor is being declared if the constructor is the
+   * implementation of a factory constructor.
+   */
+  Identifier get returnType;
+
+  /**
+   * Set the type of object being created to the given [typeName].
+   */
+  void set returnType(Identifier typeName);
+
+  /**
+   * Return the token for the separator (colon or equals) before the initializer
+   * list or redirection, or `null` if there are no initializers.
+   */
+  Token get separator;
+
+  /**
+   * Set the token for the separator (colon or equals) before the initializer
+   * list or redirection to the given [token].
+   */
+  void set separator(Token token);
+}
+
+/**
+ * The initialization of a field within a constructor's initialization list.
+ *
+ * > fieldInitializer ::=
+ * >     ('this' '.')? [SimpleIdentifier] '=' [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorFieldInitializer extends ConstructorInitializer {
+  /**
+   * Initialize a newly created field initializer to initialize the field with
+   * the given name to the value of the given expression. The [thisKeyword] and
+   * [period] can be `null` if the 'this' keyword was not specified.
+   */
+  factory ConstructorFieldInitializer(
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier fieldName,
+      Token equals,
+      Expression expression) = ConstructorFieldInitializerImpl;
+
+  /**
+   * Return the token for the equal sign between the field name and the
+   * expression.
+   */
+  Token get equals;
+
+  /**
+   * Set the token for the equal sign between the field name and the
+   * expression to the given [token].
+   */
+  void set equals(Token token);
+
+  /**
+   * Return the expression computing the value to which the field will be
+   * initialized.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression computing the value to which the field will be
+   * initialized to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the name of the field being initialized.
+   */
+  SimpleIdentifier get fieldName;
+
+  /**
+   * Set the name of the field being initialized to the given [identifier].
+   */
+  void set fieldName(SimpleIdentifier identifier);
+
+  /**
+   * Return the token for the period after the 'this' keyword, or `null` if
+   * there is no 'this' keyword.
+   */
+  Token get period;
+
+  /**
+   * Set the token for the period after the 'this' keyword to the given [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the token for the 'this' keyword, or `null` if there is no 'this'
+   * keyword.
+   */
+  Token get thisKeyword;
+
+  /**
+   * Set the token for the 'this' keyword to the given [token].
+   */
+  void set thisKeyword(Token token);
+}
+
+/**
+ * A node that can occur in the initializer list of a constructor declaration.
+ *
+ * > constructorInitializer ::=
+ * >     [SuperConstructorInvocation]
+ * >   | [ConstructorFieldInitializer]
+ * >   | [RedirectingConstructorInvocation]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorInitializer extends AstNode {}
+
+/**
+ * The name of a constructor.
+ *
+ * > constructorName ::=
+ * >     type ('.' identifier)?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ConstructorName extends AstNode {
+  /**
+   * Initialize a newly created constructor name. The [period] and [name] can be
+   * `null` if the constructor being named is the unnamed constructor.
+   */
+  factory ConstructorName(TypeName type, Token period, SimpleIdentifier name) =
+      ConstructorNameImpl;
+
+  /**
+   * Return the name of the constructor, or `null` if the specified constructor
+   * is the unnamed constructor.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the constructor to the given [name].
+   */
+  void set name(SimpleIdentifier name);
+
+  /**
+   * Return the token for the period before the constructor name, or `null` if
+   * the specified constructor is the unnamed constructor.
+   */
+  Token get period;
+
+  /**
+   * Set the token for the period before the constructor name to the given
+   * [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the element associated with this constructor name based on static
+   * type information, or `null` if the AST structure has not been resolved or
+   * if this constructor name could not be resolved.
+   */
+  ConstructorElement get staticElement;
+
+  /**
+   * Set the element associated with this constructor name based on static type
+   * information to the given [element].
+   */
+  void set staticElement(ConstructorElement element);
+
+  /**
+   * Return the name of the type defining the constructor.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the type defining the constructor to the given [type] name.
+   */
+  void set type(TypeName type);
+}
+
+/**
+ * A continue statement.
+ *
+ * > continueStatement ::=
+ * >     'continue' [SimpleIdentifier]? ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ContinueStatement extends Statement {
+  /**
+   * Initialize a newly created continue statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  factory ContinueStatement(
+          Token continueKeyword, SimpleIdentifier label, Token semicolon) =
+      ContinueStatementImpl;
+
+  /**
+   * Return the token representing the 'continue' keyword.
+   */
+  Token get continueKeyword;
+
+  /**
+   * Set the token representing the 'continue' keyword to the given [token].
+   */
+  void set continueKeyword(Token token);
+
+  /**
+   * Return the label associated with the statement, or `null` if there is no
+   * label.
+   */
+  SimpleIdentifier get label;
+
+  /**
+   * Set the label associated with the statement to the given [identifier].
+   */
+  void set label(SimpleIdentifier identifier);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the node to which this continue statement is continuing. This will
+   * be either a [Statement] (in the case of continuing a loop), a
+   * [SwitchMember] (in the case of continuing from one switch case to another),
+   * or `null` if the AST has not yet been resolved or if the target could not
+   * be resolved. Note that if the source code has errors, the target might be
+   * invalid (e.g. the target may be in an enclosing function).
+   */
+  AstNode get target;
+
+  /**
+   * Set the node to which this continue statement is continuing to the given
+   * [node].
+   */
+  void set target(AstNode node);
+}
+
+/**
+ * A node that represents the declaration of one or more names. Each declared
+ * name is visible within a name scope.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Declaration extends AnnotatedNode {
+  /**
+   * Return the element associated with this declaration, or `null` if either
+   * this node corresponds to a list of declarations or if the AST structure has
+   * not been resolved.
+   */
+  Element get element;
+}
+
+/**
+ * The declaration of a single identifier.
+ *
+ * > declaredIdentifier ::=
+ * >     [Annotation] finalConstVarOrType [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DeclaredIdentifier extends Declaration {
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type name is
+   * given. The [type] must be `null` if the keyword is 'var'.
+   */
+  factory DeclaredIdentifier(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      SimpleIdentifier identifier) = DeclaredIdentifierImpl;
+
+  @override
+  LocalVariableElement get element;
+
+  /**
+   * Return the name of the variable being declared.
+   */
+  SimpleIdentifier get identifier;
+
+  /**
+   * Set the name of the variable being declared to the given [identifier].
+   */
+  void set identifier(SimpleIdentifier identifier);
+
+  /**
+   * 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 the token representing either the 'final', 'const' or 'var' keyword,
+   * or `null` if no keyword was used.
+   */
+  Token get keyword;
+
+  /**
+   * Set the token representing either the 'final', 'const' or 'var' keyword to
+   * the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the name of the declared type of the parameter, or `null` if the
+   * parameter does not have a declared type.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the declared type of the parameter to the given [typeName].
+   */
+  void set type(TypeName typeName);
+}
+
+/**
+ * A formal parameter with a default value. There are two kinds of parameters
+ * that are both represented by this class: named formal parameters and
+ * positional formal parameters.
+ *
+ * > defaultFormalParameter ::=
+ * >     [NormalFormalParameter] ('=' [Expression])?
+ * >
+ * > defaultNamedParameter ::=
+ * >     [NormalFormalParameter] (':' [Expression])?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DefaultFormalParameter extends FormalParameter {
+  /**
+   * Initialize a newly created default formal parameter. The [separator] and
+   * [defaultValue] can be `null` if there is no default value.
+   */
+  factory DefaultFormalParameter(
+      NormalFormalParameter parameter,
+      ParameterKind kind,
+      Token separator,
+      Expression defaultValue) = DefaultFormalParameterImpl;
+
+  /**
+   * Return the expression computing the default value for the parameter, or
+   * `null` if there is no default value.
+   */
+  Expression get defaultValue;
+
+  /**
+   * Set the expression computing the default value for the parameter to the
+   * given [expression].
+   */
+  void set defaultValue(Expression expression);
+
+  /**
+   * Set the kind of this parameter to the given [kind].
+   */
+  void set kind(ParameterKind kind);
+
+  /**
+   * Return the formal parameter with which the default value is associated.
+   */
+  NormalFormalParameter get parameter;
+
+  /**
+   * Set the formal parameter with which the default value is associated to the
+   * given [formalParameter].
+   */
+  void set parameter(NormalFormalParameter formalParameter);
+
+  /**
+   * Return the token separating the parameter from the default value, or `null`
+   * if there is no default value.
+   */
+  Token get separator;
+
+  /**
+   * Set the token separating the parameter from the default value to the given
+   * [token].
+   */
+  void set separator(Token token);
+}
+
+/**
+ * A node that represents a directive.
+ *
+ * > directive ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ * >   | [LibraryDirective]
+ * >   | [PartDirective]
+ * >   | [PartOfDirective]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Directive extends AnnotatedNode {
+  /**
+   * Return the element associated with this directive, or `null` if the AST
+   * structure has not been resolved or if this directive could not be resolved.
+   */
+  Element get element;
+
+  /**
+   * Set the element associated with this directive to the given [element].
+   */
+  void set element(Element element);
+
+  /**
+   * Return the token representing the keyword that introduces this directive
+   * ('import', 'export', 'library' or 'part').
+   */
+  Token get keyword;
+}
+
+/**
+ * A do statement.
+ *
+ * > doStatement ::=
+ * >     'do' [Statement] 'while' '(' [Expression] ')' ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DoStatement extends Statement {
+  /**
+   * Initialize a newly created do loop.
+   */
+  factory DoStatement(
+      Token doKeyword,
+      Statement body,
+      Token whileKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      Token semicolon) = DoStatementImpl;
+
+  /**
+   * Return the body of the loop.
+   */
+  Statement get body;
+
+  /**
+   * Set the body of the loop to the given [statement].
+   */
+  void set body(Statement statement);
+
+  /**
+   * Return the condition that determines when the loop will terminate.
+   */
+  Expression get condition;
+
+  /**
+   * Set the condition that determines when the loop will terminate to the given
+   * [expression].
+   */
+  void set condition(Expression expression);
+
+  /**
+   * Return the token representing the 'do' keyword.
+   */
+  Token get doKeyword;
+
+  /**
+   * Set the token representing the 'do' keyword to the given [token].
+   */
+  void set doKeyword(Token token);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the token representing the 'while' keyword.
+   */
+  Token get whileKeyword;
+
+  /**
+   * Set the token representing the 'while' keyword to the given [token].
+   */
+  void set whileKeyword(Token token);
+}
+
+/**
+ * A dotted name, used in a configuration within an import or export directive.
+ *
+ * > dottedName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DottedName extends AstNode {
+  /**
+   * Initialize a newly created dotted name.
+   */
+  factory DottedName(List<SimpleIdentifier> components) = DottedNameImpl;
+
+  /**
+   * Return the components of the identifier.
+   */
+  NodeList<SimpleIdentifier> get components;
+}
+
+/**
+ * A floating point literal expression.
+ *
+ * > doubleLiteral ::=
+ * >     decimalDigit+ ('.' decimalDigit*)? exponent?
+ * >   | '.' decimalDigit+ exponent?
+ * >
+ * > exponent ::=
+ * >     ('e' | 'E') ('+' | '-')? decimalDigit+
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class DoubleLiteral extends Literal {
+  /**
+   * Initialize a newly created floating point literal.
+   */
+  factory DoubleLiteral(Token literal, double value) = DoubleLiteralImpl;
+
+  /**
+   * Return the token representing the literal.
+   */
+  Token get literal;
+
+  /**
+   * Set the token representing the literal to the given [token].
+   */
+  void set literal(Token token);
+
+  /**
+   * Return the value of the literal.
+   */
+  double get value;
+
+  /**
+   * Set the value of the literal to the given [value].
+   */
+  void set value(double value);
+}
+
+/**
+ * An empty function body, which can only appear in constructors or abstract
+ * methods.
+ *
+ * > emptyFunctionBody ::=
+ * >     ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class EmptyFunctionBody extends FunctionBody {
+  /**
+   * Initialize a newly created function body.
+   */
+  factory EmptyFunctionBody(Token semicolon) = EmptyFunctionBodyImpl;
+
+  /**
+   * Return the token representing the semicolon that marks the end of the
+   * function body.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the token representing the semicolon that marks the end of the
+   * function body to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * An empty statement.
+ *
+ * > emptyStatement ::=
+ * >     ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class EmptyStatement extends Statement {
+  /**
+   * Initialize a newly created empty statement.
+   */
+  factory EmptyStatement(Token semicolon) = EmptyStatementImpl;
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * The declaration of an enum constant.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class EnumConstantDeclaration extends Declaration {
+  /**
+   * Initialize a newly created enum constant declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the constant does not have the
+   * corresponding attribute. (Technically, enum constants cannot have metadata,
+   * but we allow it for consistency.)
+   */
+  factory EnumConstantDeclaration(
+          Comment comment, List<Annotation> metadata, SimpleIdentifier name) =
+      EnumConstantDeclarationImpl;
+
+  /**
+   * Return the name of the constant.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the constant to the given [name].
+   */
+  void set name(SimpleIdentifier name);
+}
+
+/**
+ * The declaration of an enumeration.
+ *
+ * > enumType ::=
+ * >     metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class EnumDeclaration extends NamedCompilationUnitMember {
+  /**
+   * Initialize a newly created enumeration declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The list of [constants] must contain at least one
+   * value.
+   */
+  factory EnumDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token enumKeyword,
+      SimpleIdentifier name,
+      Token leftBracket,
+      List<EnumConstantDeclaration> constants,
+      Token rightBracket) = EnumDeclarationImpl;
+
+  /**
+   * Return the enumeration constants being declared.
+   */
+  NodeList<EnumConstantDeclaration> get constants;
+
+  @override
+  ClassElement get element;
+
+  /**
+   * Return the 'enum' keyword.
+   */
+  Token get enumKeyword;
+
+  /**
+   * Set the 'enum' keyword to the given [token].
+   */
+  void set enumKeyword(Token token);
+
+  /**
+   * Return the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left curly bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+}
+
+/**
+ * An export directive.
+ *
+ * > exportDirective ::=
+ * >     [Annotation] 'export' [StringLiteral] [Combinator]* ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExportDirective extends NamespaceDirective {
+  /**
+   * Initialize a newly created export directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  factory ExportDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      Token semicolon) = ExportDirectiveImpl;
+}
+
+/**
+ * A node that represents an expression.
+ *
+ * > expression ::=
+ * >     [AssignmentExpression]
+ * >   | [ConditionalExpression] cascadeSection*
+ * >   | [ThrowExpression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Expression extends AstNode {
+  /**
+   * An empty list of expressions.
+   */
+  static const List<Expression> EMPTY_LIST = const <Expression>[];
+
+  /**
+   * Return the best parameter element information available for this
+   * expression. If type propagation was able to find a better parameter element
+   * than static analysis, that type will be returned. Otherwise, the result of
+   * static analysis will be returned.
+   */
+  ParameterElement get bestParameterElement;
+
+  /**
+   * Return the best type information available for this expression. If type
+   * propagation was able to find a better type than static analysis, that type
+   * will be returned. Otherwise, the result of static analysis will be
+   * returned. If no type analysis has been performed, then the type 'dynamic'
+   * will be returned.
+   */
+  DartType get bestType;
+
+  /**
+   * Return `true` if this expression is syntactically valid for the LHS of an
+   * [AssignmentExpression].
+   */
+  bool get isAssignable;
+
+  /**
+   * Return the precedence of this expression. The precedence is a positive
+   * integer value that defines how the source code is parsed into an AST. For
+   * example `a * b + c` is parsed as `(a * b) + c` because the precedence of
+   * `*` is greater than the precedence of `+`.
+   *
+   * Clients should not assume that returned values will stay the same, they
+   * might change as result of specification change. Only relative order should
+   * be used.
+   */
+  int get precedence;
+
+  /**
+   * If this expression is an argument to an invocation, and the AST structure
+   * has been resolved, and the function being invoked is known based on
+   * propagated type information, and this expression corresponds to one of the
+   * parameters of the function being invoked, then return the parameter element
+   * representing the parameter to which the value of this expression will be
+   * bound. Otherwise, return `null`.
+   */
+  ParameterElement get propagatedParameterElement;
+
+  /**
+   * Return the propagated type of this expression, or `null` if type
+   * propagation has not been performed on the AST structure.
+   */
+  DartType get propagatedType;
+
+  /**
+   * Set the propagated type of this expression to the given [type].
+   */
+  void set propagatedType(DartType type);
+
+  /**
+   * If this expression is an argument to an invocation, and the AST structure
+   * has been resolved, and the function being invoked is known based on static
+   * type information, and this expression corresponds to one of the parameters
+   * of the function being invoked, then return the parameter element
+   * representing the parameter to which the value of this expression will be
+   * bound. Otherwise, return `null`.
+   */
+  ParameterElement get staticParameterElement;
+
+  /**
+   * Return the static type of this expression, or `null` if the AST structure
+   * has not been resolved.
+   */
+  DartType get staticType;
+
+  /**
+   * Set the static type of this expression to the given [type].
+   */
+  void set staticType(DartType type);
+}
+
+/**
+ * A function body consisting of a single expression.
+ *
+ * > expressionFunctionBody ::=
+ * >     'async'? '=>' [Expression] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExpressionFunctionBody extends FunctionBody {
+  /**
+   * Initialize a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if the function body is not an
+   * async function body.
+   */
+  factory ExpressionFunctionBody(Token keyword, Token functionDefinition,
+      Expression expression, Token semicolon) = ExpressionFunctionBodyImpl;
+
+  /**
+   * Return the expression representing the body of the function.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression representing the body of the function to the given
+   * [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the token introducing the expression that represents the body of the
+   * function.
+   */
+  Token get functionDefinition;
+
+  /**
+   * Set the token introducing the expression that represents the body of the
+   * function to the given [token].
+   */
+  void set functionDefinition(Token token);
+
+  /**
+   * Set token representing the 'async' or 'sync' keyword to the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * An expression used as a statement.
+ *
+ * > expressionStatement ::=
+ * >     [Expression]? ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExpressionStatement extends Statement {
+  /**
+   * Initialize a newly created expression statement.
+   */
+  factory ExpressionStatement(Expression expression, Token semicolon) =
+      ExpressionStatementImpl;
+
+  /**
+   * Return the expression that comprises the statement.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression that comprises the statement to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the semicolon terminating the statement, or `null` if the expression is a
+   * function expression and therefore isn't followed by a semicolon.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * The "extends" clause in a class declaration.
+ *
+ * > extendsClause ::=
+ * >     'extends' [TypeName]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ExtendsClause extends AstNode {
+  /**
+   * Initialize a newly created extends clause.
+   */
+  factory ExtendsClause(Token extendsKeyword, TypeName superclass) =
+      ExtendsClauseImpl;
+
+  /**
+   * Return the token representing the 'extends' keyword.
+   */
+  Token get extendsKeyword;
+
+  /**
+   * Set the token representing the 'extends' keyword to the given [token].
+   */
+  void set extendsKeyword(Token token);
+
+  /**
+   * Return the name of the class that is being extended.
+   */
+  TypeName get superclass;
+
+  /**
+   * Set the name of the class that is being extended to the given [name].
+   */
+  void set superclass(TypeName name);
+}
+
+/**
+ * The declaration of one or more fields of the same type.
+ *
+ * > fieldDeclaration ::=
+ * >     'static'? [VariableDeclarationList] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldDeclaration extends ClassMember {
+  /**
+   * Initialize a newly created field declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [staticKeyword] can be `null` if the field is
+   * not a static field.
+   */
+  factory FieldDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token staticKeyword,
+      VariableDeclarationList fieldList,
+      Token semicolon) = FieldDeclarationImpl;
+
+  /**
+   * Return the fields being declared.
+   */
+  VariableDeclarationList get fields;
+
+  /**
+   * Set the fields being declared to the given list of [fields].
+   */
+  void set fields(VariableDeclarationList fields);
+
+  /**
+   * Return `true` if the fields are declared to be static.
+   */
+  bool get isStatic;
+
+  /**
+   * Return the semicolon terminating the declaration.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the declaration to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the token representing the 'static' keyword, or `null` if the fields
+   * are not static.
+   */
+  Token get staticKeyword;
+
+  /**
+   * Set the token representing the 'static' keyword to the given [token].
+   */
+  void set staticKeyword(Token token);
+}
+
+/**
+ * A field formal parameter.
+ *
+ * > fieldFormalParameter ::=
+ * >     ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
+ * >     'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FieldFormalParameter extends NormalFormalParameter {
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if there is a type.
+   * The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
+   * [period] can be `null` if the keyword 'this' was not provided.  The
+   * [parameters] can be `null` if this is not a function-typed field formal
+   * parameter.
+   */
+  factory FieldFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters) = FieldFormalParameterImpl;
+
+  /**
+   * Return the token representing either the 'final', 'const' or 'var' keyword,
+   * or `null` if no keyword was used.
+   */
+  Token get keyword;
+
+  /**
+   * Set the token representing either the 'final', 'const' or 'var' keyword to
+   * the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the parameters of the function-typed parameter, or `null` if this is
+   * not a function-typed field formal parameter.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters of the function-typed parameter to the given
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the token representing the period.
+   */
+  Token get period;
+
+  /**
+   * Set the token representing the period to the given [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the token representing the 'this' keyword.
+   */
+  Token get thisKeyword;
+
+  /**
+   * Set the token representing the 'this' keyword to the given [token].
+   */
+  void set thisKeyword(Token token);
+
+  /**
+   * Return the name of the declared type of the parameter, or `null` if the
+   * parameter does not have a declared type. Note that if this is a
+   * function-typed field formal parameter this is the return type of the
+   * function.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the declared type of the parameter to the given [typeName].
+   */
+  void set type(TypeName typeName);
+
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+}
+
+/**
+ * A for-each statement.
+ *
+ * > forEachStatement ::=
+ * >     'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
+ * >   | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ForEachStatement extends Statement {
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared internally (in the for-loop part). The [awaitKeyword] can be
+   * `null` if this is not an asynchronous for loop.
+   */
+  factory ForEachStatement.withDeclaration(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      DeclaredIdentifier loopVariable,
+      Token inKeyword,
+      Expression iterator,
+      Token rightParenthesis,
+      Statement body) = ForEachStatementImpl.withDeclaration;
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared outside the for loop. The [awaitKeyword] can be `null` if this
+   * is not an asynchronous for loop.
+   */
+  factory ForEachStatement.withReference(
+      Token awaitKeyword,
+      Token forKeyword,
+      Token leftParenthesis,
+      SimpleIdentifier identifier,
+      Token inKeyword,
+      Expression iterator,
+      Token rightParenthesis,
+      Statement body) = ForEachStatementImpl.withReference;
+
+  /**
+   * Return the token representing the 'await' keyword, or `null` if there is no
+   * 'await' keyword.
+   */
+  Token get awaitKeyword;
+
+  /**
+   * Set the token representing the 'await' keyword to the given [token].
+   */
+  void set awaitKeyword(Token token);
+
+  /**
+   * Return the body of the loop.
+   */
+  Statement get body;
+
+  /**
+   * Set the body of the loop to the given [statement].
+   */
+  void set body(Statement statement);
+
+  /**
+   * Return the token representing the 'for' keyword.
+   */
+  Token get forKeyword;
+
+  /**
+   * Set the token representing the 'for' keyword to the given [token].
+   */
+  void set forKeyword(Token token);
+
+  /**
+   * Return the loop variable, or `null` if the loop variable is declared in the
+   * 'for'.
+   */
+  SimpleIdentifier get identifier;
+
+  /**
+   * Set the loop variable to the given [identifier].
+   */
+  void set identifier(SimpleIdentifier identifier);
+
+  /**
+   * Return the token representing the 'in' keyword.
+   */
+  Token get inKeyword;
+
+  /**
+   * Set the token representing the 'in' keyword to the given [token].
+   */
+  void set inKeyword(Token token);
+
+  /**
+   * Return the expression evaluated to produce the iterator.
+   */
+  Expression get iterable;
+
+  /**
+   * Set the expression evaluated to produce the iterator to the given
+   * [expression].
+   */
+  void set iterable(Expression expression);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the declaration of the loop variable, or `null` if the loop variable
+   * is a simple identifier.
+   */
+  DeclaredIdentifier get loopVariable;
+
+  /**
+   * Set the declaration of the loop variable to the given [variable].
+   */
+  void set loopVariable(DeclaredIdentifier variable);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+}
+
+/**
+ * A node representing a parameter to a function.
+ *
+ * > formalParameter ::=
+ * >     [NormalFormalParameter]
+ * >   | [DefaultFormalParameter]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FormalParameter extends AstNode {
+  /**
+   * Return the element representing this parameter, or `null` if this parameter
+   * has not been resolved.
+   */
+  ParameterElement get element;
+
+  /**
+   * Return the name of the parameter being declared.
+   */
+  SimpleIdentifier get identifier;
+
+  /**
+   * Return `true` if this parameter was declared with the 'const' modifier.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if this parameter was declared with the 'final' modifier.
+   * Parameters that are declared with the 'const' modifier will return `false`
+   * even though they are implicitly final.
+   */
+  bool get isFinal;
+
+  /**
+   * Return the kind of this parameter.
+   */
+  ParameterKind get kind;
+
+  /**
+   * Return the annotations associated with this parameter.
+   */
+  NodeList<Annotation> get metadata;
+}
+
+/**
+ * The formal parameter list of a method declaration, function declaration, or
+ * function type alias.
+ *
+ * While the grammar requires all optional formal parameters to follow all of
+ * the normal formal parameters and at most one grouping of optional formal
+ * parameters, this class does not enforce those constraints. All parameters are
+ * flattened into a single list, which can have any or all kinds of parameters
+ * (normal, named, and positional) in any order.
+ *
+ * > formalParameterList ::=
+ * >     '(' ')'
+ * >   | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ * >   | '(' optionalFormalParameters ')'
+ * >
+ * > normalFormalParameters ::=
+ * >     [NormalFormalParameter] (',' [NormalFormalParameter])*
+ * >
+ * > optionalFormalParameters ::=
+ * >     optionalPositionalFormalParameters
+ * >   | namedFormalParameters
+ * >
+ * > optionalPositionalFormalParameters ::=
+ * >     '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
+ * >
+ * > namedFormalParameters ::=
+ * >     '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FormalParameterList extends AstNode {
+  /**
+   * Initialize a newly created parameter list. The list of [parameters] can be
+   * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
+   * can be `null` if there are no optional parameters.
+   */
+  factory FormalParameterList(
+      Token leftParenthesis,
+      List<FormalParameter> parameters,
+      Token leftDelimiter,
+      Token rightDelimiter,
+      Token rightParenthesis) = FormalParameterListImpl;
+
+  /**
+   * Return the left square bracket ('[') or left curly brace ('{') introducing
+   * the optional parameters, or `null` if there are no optional parameters.
+   */
+  Token get leftDelimiter;
+
+  /**
+   * Set the left square bracket ('[') or left curly brace ('{') introducing
+   * the optional parameters to the given [token].
+   */
+  void set leftDelimiter(Token token);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return a list containing the elements representing the parameters in this
+   * list. The list will contain `null`s if the parameters in this list have not
+   * been resolved.
+   */
+  List<ParameterElement> get parameterElements;
+
+  /**
+   * Return the parameters associated with the method.
+   */
+  NodeList<FormalParameter> get parameters;
+
+  /**
+   * Return the right square bracket (']') or right curly brace ('}') terminating the
+   * optional parameters, or `null` if there are no optional parameters.
+   */
+  Token get rightDelimiter;
+
+  /**
+   * Set the right square bracket (']') or right curly brace ('}') terminating the
+   * optional parameters to the given [token].
+   */
+  void set rightDelimiter(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+}
+
+/**
+ * A for statement.
+ *
+ * > forStatement ::=
+ * >     'for' '(' forLoopParts ')' [Statement]
+ * >
+ * > forLoopParts ::=
+ * >     forInitializerStatement ';' [Expression]? ';' [Expression]?
+ * >
+ * > forInitializerStatement ::=
+ * >     [DefaultFormalParameter]
+ * >   | [Expression]?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ForStatement extends Statement {
+  /**
+   * Initialize a newly created for statement. Either the [variableList] or the
+   * [initialization] must be `null`. Either the [condition] and the list of
+   * [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  factory ForStatement(
+      Token forKeyword,
+      Token leftParenthesis,
+      VariableDeclarationList variableList,
+      Expression initialization,
+      Token leftSeparator,
+      Expression condition,
+      Token rightSeparator,
+      List<Expression> updaters,
+      Token rightParenthesis,
+      Statement body) = ForStatementImpl;
+
+  /**
+   * Return the body of the loop.
+   */
+  Statement get body;
+
+  /**
+   * Set the body of the loop to the given [statement].
+   */
+  void set body(Statement statement);
+
+  /**
+   * Return the condition used to determine when to terminate the loop, or
+   * `null` if there is no condition.
+   */
+  Expression get condition;
+
+  /**
+   * Set the condition used to determine when to terminate the loop to the given
+   * [expression].
+   */
+  void set condition(Expression expression);
+
+  /**
+   * Return the token representing the 'for' keyword.
+   */
+  Token get forKeyword;
+
+  /**
+   * Set the token representing the 'for' keyword to the given [token].
+   */
+  void set forKeyword(Token token);
+
+  /**
+   * Return the initialization expression, or `null` if there is no
+   * initialization expression.
+   */
+  Expression get initialization;
+
+  /**
+   * Set the initialization expression to the given [expression].
+   */
+  void set initialization(Expression initialization);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the semicolon separating the initializer and the condition.
+   */
+  Token get leftSeparator;
+
+  /**
+   * Set the semicolon separating the initializer and the condition to the given
+   * [token].
+   */
+  void set leftSeparator(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the semicolon separating the condition and the updater.
+   */
+  Token get rightSeparator;
+
+  /**
+   * Set the semicolon separating the condition and the updater to the given
+   * [token].
+   */
+  void set rightSeparator(Token token);
+
+  /**
+   * Return the list of expressions run after each execution of the loop body.
+   */
+  NodeList<Expression> get updaters;
+
+  /**
+   * Return the declaration of the loop variables, or `null` if there are no
+   * variables.
+   */
+  VariableDeclarationList get variables;
+
+  /**
+   * Set the declaration of the loop variables to the given [variableList].
+   */
+  void set variables(VariableDeclarationList variableList);
+}
+
+/**
+ * A node representing the body of a function or method.
+ *
+ * > functionBody ::=
+ * >     [BlockFunctionBody]
+ * >   | [EmptyFunctionBody]
+ * >   | [ExpressionFunctionBody]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionBody extends AstNode {
+  /**
+   * Return `true` if this function body is asynchronous.
+   */
+  bool get isAsynchronous;
+
+  /**
+   * Return `true` if this function body is a generator.
+   */
+  bool get isGenerator;
+
+  /**
+   * Return `true` if this function body is synchronous.
+   */
+  bool get isSynchronous;
+
+  /**
+   * Return the token representing the 'async' or 'sync' keyword, or `null` if
+   * there is no such keyword.
+   */
+  Token get keyword;
+
+  /**
+   * Return the star following the 'async' or 'sync' keyword, or `null` if there
+   * is no star.
+   */
+  Token get star;
+}
+
+/**
+ * A top-level declaration.
+ *
+ * > functionDeclaration ::=
+ * >     'external' functionSignature
+ * >   | functionSignature [FunctionBody]
+ * >
+ * > functionSignature ::=
+ * >     [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionDeclaration extends NamedCompilationUnitMember {
+  /**
+   * Initialize a newly created function declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the
+   * function is not an external function. The [returnType] can be `null` if no
+   * return type was specified. The [propertyKeyword] can be `null` if the
+   * function is neither a getter or a setter.
+   */
+  factory FunctionDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      TypeName returnType,
+      Token propertyKeyword,
+      SimpleIdentifier name,
+      FunctionExpression functionExpression) = FunctionDeclarationImpl;
+
+  @override
+  ExecutableElement get element;
+
+  /**
+   * Return the token representing the 'external' keyword, or `null` if this is
+   * not an external function.
+   */
+  Token get externalKeyword;
+
+  /**
+   * Set the token representing the 'external' keyword to the given [token].
+   */
+  void set externalKeyword(Token token);
+
+  /**
+   * Return the function expression being wrapped.
+   */
+  FunctionExpression get functionExpression;
+
+  /**
+   * Set the function expression being wrapped to the given
+   * [functionExpression].
+   */
+  void set functionExpression(FunctionExpression functionExpression);
+
+  /**
+   * Return `true` if this function declares a getter.
+   */
+  bool get isGetter;
+
+  /**
+   * Return `true` if this function declares a setter.
+   */
+  bool get isSetter;
+
+  /**
+   * Return the token representing the 'get' or 'set' keyword, or `null` if this
+   * is a function declaration rather than a property declaration.
+   */
+  Token get propertyKeyword;
+
+  /**
+   * Set the token representing the 'get' or 'set' keyword to the given [token].
+   */
+  void set propertyKeyword(Token token);
+
+  /**
+   * Return the return type of the function, or `null` if no return type was
+   * declared.
+   */
+  TypeName get returnType;
+
+  /**
+   * Set the return type of the function to the given [returnType].
+   */
+  void set returnType(TypeName returnType);
+}
+
+/**
+ * A [FunctionDeclaration] used as a statement.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionDeclarationStatement extends Statement {
+  /**
+   * Initialize a newly created function declaration statement.
+   */
+  factory FunctionDeclarationStatement(
+          FunctionDeclaration functionDeclaration) =
+      FunctionDeclarationStatementImpl;
+
+  /**
+   * Return the function declaration being wrapped.
+   */
+  FunctionDeclaration get functionDeclaration;
+
+  /**
+   * Set the function declaration being wrapped to the given
+   * [functionDeclaration].
+   */
+  void set functionDeclaration(FunctionDeclaration functionDeclaration);
+}
+
+/**
+ * A function expression.
+ *
+ * > functionExpression ::=
+ * >     [TypeParameterList]? [FormalParameterList] [FunctionBody]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionExpression extends Expression {
+  /**
+   * Initialize a newly created function declaration.
+   */
+  factory FunctionExpression(
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      FunctionBody body) = FunctionExpressionImpl;
+
+  /**
+   * Return the body of the function, or `null` if this is an external function.
+   */
+  FunctionBody get body;
+
+  /**
+   * Set the body of the function to the given [functionBody].
+   */
+  void set body(FunctionBody functionBody);
+
+  /**
+   * Return the element associated with the function, or `null` if the AST
+   * structure has not been resolved.
+   */
+  ExecutableElement get element;
+
+  /**
+   * Set the element associated with the function to the given [element].
+   */
+  void set element(ExecutableElement element);
+
+  /**
+   * Return the parameters associated with the function.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters associated with the function to the given list of
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+}
+
+/**
+ * The invocation of a function resulting from evaluating an expression.
+ * Invocations of methods and other forms of functions are represented by
+ * [MethodInvocation] nodes. Invocations of getters and setters are represented
+ * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+ *
+ * > functionExpressionInvocation ::=
+ * >     [Expression] [TypeArgumentList]? [ArgumentList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionExpressionInvocation extends Expression {
+  /**
+   * Initialize a newly created function expression invocation.
+   */
+  factory FunctionExpressionInvocation(
+      Expression function,
+      TypeArgumentList typeArguments,
+      ArgumentList argumentList) = FunctionExpressionInvocationImpl;
+
+  /**
+   * Return the list of arguments to the method.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * Set the list of arguments to the method to the given [argumentList].
+   */
+  void set argumentList(ArgumentList argumentList);
+
+  /**
+   * Return the best element available for the function being invoked. If
+   * resolution was able to find a better element based on type propagation,
+   * that element will be returned. Otherwise, the element found using the
+   * result of static analysis will be returned. If resolution has not been
+   * performed, then `null` will be returned.
+   */
+  ExecutableElement get bestElement;
+
+  /**
+   * Return the expression producing the function being invoked.
+   */
+  Expression get function;
+
+  /**
+   * Set the expression producing the function being invoked to the given
+   * [expression].
+   */
+  void set function(Expression expression);
+
+  /**
+   * Return the element associated with the function being invoked based on
+   * propagated type information, or `null` if the AST structure has not been
+   * resolved or the function could not be resolved.
+   */
+  ExecutableElement get propagatedElement;
+
+  /**
+   * Set the element associated with the function being invoked based on
+   * propagated type information to the given [element].
+   */
+  void set propagatedElement(ExecutableElement element);
+
+  /**
+   * Return the function type of the method invocation based on the propagated
+   * type information, or `null` if the AST structure has not been resolved, or
+   * if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get propagatedInvokeType;
+
+  /**
+   * Set the function type of the method invocation based on the propagated type
+   * information to the given [type].
+   */
+  void set propagatedInvokeType(DartType type);
+
+  /**
+   * Return the element associated with the function being invoked based on
+   * static type information, or `null` if the AST structure has not been
+   * resolved or the function could not be resolved.
+   */
+  ExecutableElement get staticElement;
+
+  /**
+   * Set the element associated with the function being invoked based on static
+   * type information to the given [element].
+   */
+  void set staticElement(ExecutableElement element);
+
+  /**
+   * Return the function type of the method invocation based on the static type
+   * information, or `null` if the AST structure has not been resolved, or if
+   * the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get staticInvokeType;
+
+  /**
+   * Set the function type of the method invocation based on the static type
+   * information to the given [type].
+   */
+  void set staticInvokeType(DartType type);
+
+  /**
+   * Return the type arguments to be applied to the method being invoked, or
+   * `null` if no type arguments were provided.
+   */
+  TypeArgumentList get typeArguments;
+
+  /**
+   * Set the type arguments to be applied to the method being invoked to the
+   * given [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments);
+}
+
+/**
+ * A function type alias.
+ *
+ * > functionTypeAlias ::=
+ * >     functionPrefix [TypeParameterList]? [FormalParameterList] ';'
+ * >
+ * > functionPrefix ::=
+ * >     [TypeName]? [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypeAlias extends TypeAlias {
+  /**
+   * Initialize a newly created function type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified. The [typeParameters] can be `null` if the function has no
+   * type parameters.
+   */
+  factory FunctionTypeAlias(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName returnType,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      Token semicolon) = FunctionTypeAliasImpl;
+
+  /**
+   * Return the parameters associated with the function type.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters associated with the function type to the given list of
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the name of the return type of the function type being defined, or
+   * `null` if no return type was given.
+   */
+  TypeName get returnType;
+
+  /**
+   * Set the name of the return type of the function type being defined to the
+   * given [typeName].
+   */
+  void set returnType(TypeName typeName);
+
+  /**
+   * Return the type parameters for the function type, or `null` if the function
+   * type does not have any type parameters.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters for the function type to the given list of
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+}
+
+/**
+ * A function-typed formal parameter.
+ *
+ * > functionSignature ::=
+ * >     [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class FunctionTypedFormalParameter extends NormalFormalParameter {
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified.
+   */
+  factory FunctionTypedFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      TypeName returnType,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters) = FunctionTypedFormalParameterImpl;
+
+  /**
+   * Return the parameters of the function-typed parameter.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters of the function-typed parameter to the given
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the return type of the function, or `null` if the function does not
+   * have a return type.
+   */
+  TypeName get returnType;
+
+  /**
+   * Set the return type of the function to the given [type].
+   */
+  void set returnType(TypeName type);
+
+  /**
+   * Return the type parameters associated with this function, or `null` if
+   * this function is not a generic function.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+}
+
+/**
+ * A combinator that restricts the names being imported to those that are not in
+ * a given list.
+ *
+ * > hideCombinator ::=
+ * >     'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class HideCombinator extends Combinator {
+  /**
+   * Initialize a newly created import show combinator.
+   */
+  factory HideCombinator(Token keyword, List<SimpleIdentifier> hiddenNames) =
+      HideCombinatorImpl;
+
+  /**
+   * Return the list of names from the library that are hidden by this
+   * combinator.
+   */
+  NodeList<SimpleIdentifier> get hiddenNames;
+}
+
+/**
+ * A node that represents an identifier.
+ *
+ * > identifier ::=
+ * >     [SimpleIdentifier]
+ * >   | [PrefixedIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Identifier extends Expression {
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  Element get bestElement;
+
+  /**
+   * Return the lexical representation of the identifier.
+   */
+  String get name;
+
+  /**
+   * Return the element associated with this identifier based on propagated type
+   * information, or `null` if the AST structure has not been resolved or if
+   * this identifier could not be resolved. One example of the latter case is an
+   * identifier that is not defined within the scope in which it appears.
+   */
+  Element get propagatedElement;
+
+  /**
+   * Return the element associated with this identifier based on static type
+   * information, or `null` if the AST structure has not been resolved or if
+   * this identifier could not be resolved. One example of the latter case is an
+   * identifier that is not defined within the scope in which it appears
+   */
+  Element get staticElement;
+
+  /**
+   * Return `true` if the given [name] is visible only within the library in
+   * which it is declared.
+   */
+  static bool isPrivateName(String name) =>
+      StringUtilities.startsWithChar(name, 0x5F); // '_'
+}
+
+/**
+ * An if statement.
+ *
+ * > ifStatement ::=
+ * >     'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class IfStatement extends Statement {
+  /**
+   * Initialize a newly created if statement. The [elseKeyword] and
+   * [elseStatement] can be `null` if there is no else clause.
+   */
+  factory IfStatement(
+      Token ifKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      Statement thenStatement,
+      Token elseKeyword,
+      Statement elseStatement) = IfStatementImpl;
+
+  /**
+   * Return the condition used to determine which of the statements is executed
+   * next.
+   */
+  Expression get condition;
+
+  /**
+   * Set the condition used to determine which of the statements is executed
+   * next to the given [expression].
+   */
+  void set condition(Expression expression);
+
+  /**
+   * Return the token representing the 'else' keyword, or `null` if there is no
+   * else statement.
+   */
+  Token get elseKeyword;
+
+  /**
+   * Set the token representing the 'else' keyword to the given [token].
+   */
+  void set elseKeyword(Token token);
+
+  /**
+   * Return the statement that is executed if the condition evaluates to
+   * `false`, or `null` if there is no else statement.
+   */
+  Statement get elseStatement;
+
+  /**
+   * Set the statement that is executed if the condition evaluates to `false`
+   * to the given [statement].
+   */
+  void set elseStatement(Statement statement);
+
+  /**
+   * Return the token representing the 'if' keyword.
+   */
+  Token get ifKeyword;
+
+  /**
+   * Set the token representing the 'if' keyword to the given [token].
+   */
+  void set ifKeyword(Token token);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the statement that is executed if the condition evaluates to `true`.
+   */
+  Statement get thenStatement;
+
+  /**
+   * Set the statement that is executed if the condition evaluates to `true` to
+   * the given [statement].
+   */
+  void set thenStatement(Statement statement);
+}
+
+/**
+ * The "implements" clause in an class declaration.
+ *
+ * > implementsClause ::=
+ * >     'implements' [TypeName] (',' [TypeName])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ImplementsClause extends AstNode {
+  /**
+   * Initialize a newly created implements clause.
+   */
+  factory ImplementsClause(Token implementsKeyword, List<TypeName> interfaces) =
+      ImplementsClauseImpl;
+
+  /**
+   * Return the token representing the 'implements' keyword.
+   */
+  Token get implementsKeyword;
+
+  /**
+   * Set the token representing the 'implements' keyword to the given [token].
+   */
+  void set implementsKeyword(Token token);
+
+  /**
+   * Return the list of the interfaces that are being implemented.
+   */
+  NodeList<TypeName> get interfaces;
+}
+
+/**
+ * An import directive.
+ *
+ * > importDirective ::=
+ * >     [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
+ * >   | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ImportDirective extends NamespaceDirective {
+  static Comparator<ImportDirective> COMPARATOR =
+      (ImportDirective import1, ImportDirective import2) {
+    //
+    // uri
+    //
+    StringLiteral uri1 = import1.uri;
+    StringLiteral uri2 = import2.uri;
+    String uriStr1 = uri1.stringValue;
+    String uriStr2 = uri2.stringValue;
+    if (uriStr1 != null || uriStr2 != null) {
+      if (uriStr1 == null) {
+        return -1;
+      } else if (uriStr2 == null) {
+        return 1;
+      } else {
+        int compare = uriStr1.compareTo(uriStr2);
+        if (compare != 0) {
+          return compare;
+        }
+      }
+    }
+    //
+    // as
+    //
+    SimpleIdentifier prefix1 = import1.prefix;
+    SimpleIdentifier prefix2 = import2.prefix;
+    String prefixStr1 = prefix1 != null ? prefix1.name : null;
+    String prefixStr2 = prefix2 != null ? prefix2.name : null;
+    if (prefixStr1 != null || prefixStr2 != null) {
+      if (prefixStr1 == null) {
+        return -1;
+      } else if (prefixStr2 == null) {
+        return 1;
+      } else {
+        int compare = prefixStr1.compareTo(prefixStr2);
+        if (compare != 0) {
+          return compare;
+        }
+      }
+    }
+    //
+    // hides and shows
+    //
+    NodeList<Combinator> combinators1 = import1.combinators;
+    List<String> allHides1 = new List<String>();
+    List<String> allShows1 = new List<String>();
+    for (Combinator combinator in combinators1) {
+      if (combinator is HideCombinator) {
+        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
+        for (SimpleIdentifier simpleIdentifier in hides) {
+          allHides1.add(simpleIdentifier.name);
+        }
+      } else {
+        NodeList<SimpleIdentifier> shows =
+            (combinator as ShowCombinator).shownNames;
+        for (SimpleIdentifier simpleIdentifier in shows) {
+          allShows1.add(simpleIdentifier.name);
+        }
+      }
+    }
+    NodeList<Combinator> combinators2 = import2.combinators;
+    List<String> allHides2 = new List<String>();
+    List<String> allShows2 = new List<String>();
+    for (Combinator combinator in combinators2) {
+      if (combinator is HideCombinator) {
+        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
+        for (SimpleIdentifier simpleIdentifier in hides) {
+          allHides2.add(simpleIdentifier.name);
+        }
+      } else {
+        NodeList<SimpleIdentifier> shows =
+            (combinator as ShowCombinator).shownNames;
+        for (SimpleIdentifier simpleIdentifier in shows) {
+          allShows2.add(simpleIdentifier.name);
+        }
+      }
+    }
+    // test lengths of combinator lists first
+    if (allHides1.length != allHides2.length) {
+      return allHides1.length - allHides2.length;
+    }
+    if (allShows1.length != allShows2.length) {
+      return allShows1.length - allShows2.length;
+    }
+    // next ensure that the lists are equivalent
+    if (!javaCollectionContainsAll(allHides1, allHides2)) {
+      return -1;
+    }
+    if (!javaCollectionContainsAll(allShows1, allShows2)) {
+      return -1;
+    }
+    return 0;
+  };
+
+  /**
+   * Initialize a newly created import directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [deferredKeyword] can be `null` if the import
+   * is not deferred. The [asKeyword] and [prefix] can be `null` if the import
+   * does not specify a prefix. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  factory ImportDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      Token deferredKeyword,
+      Token asKeyword,
+      SimpleIdentifier prefix,
+      List<Combinator> combinators,
+      Token semicolon) = ImportDirectiveImpl;
+
+  /**
+   * Return the token representing the 'as' keyword, or `null` if the imported
+   * names are not prefixed.
+   */
+  Token get asKeyword;
+
+  /**
+   * Set the token representing the 'as' keyword to the given [token].
+   */
+  void set asKeyword(Token token);
+
+  /**
+   * Return the token representing the 'deferred' keyword, or `null` if the
+   * imported URI is not deferred.
+   */
+  Token get deferredKeyword;
+
+  /**
+   * Set the token representing the 'deferred' keyword to the given [token].
+   */
+  void set deferredKeyword(Token token);
+
+  /**
+   * Return the prefix to be used with the imported names, or `null` if the
+   * imported names are not prefixed.
+   */
+  SimpleIdentifier get prefix;
+
+  /**
+   * Set the prefix to be used with the imported names to the given [identifier].
+   */
+  void set prefix(SimpleIdentifier identifier);
+}
+
+/**
+ * An index expression.
+ *
+ * > indexExpression ::=
+ * >     [Expression] '[' [Expression] ']'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class IndexExpression extends Expression {
+  /**
+   * Initialize a newly created index expression.
+   */
+  factory IndexExpression.forCascade(Token period, Token leftBracket,
+      Expression index, Token rightBracket) = IndexExpressionImpl.forCascade;
+
+  /**
+   * Initialize a newly created index expression.
+   */
+  factory IndexExpression.forTarget(Expression target, Token leftBracket,
+      Expression index, Token rightBracket) = IndexExpressionImpl.forTarget;
+
+  /**
+   * Return the auxiliary elements associated with this identifier, or `null` if
+   * this identifier is not in both a getter and setter context. The auxiliary
+   * elements hold the static and propagated elements associated with the getter
+   * context.
+   */
+  // TODO(brianwilkerson) Replace this API.
+  AuxiliaryElements get auxiliaryElements;
+
+  /**
+   * Set the auxiliary elements associated with this identifier to the given
+   * [elements].
+   */
+  // TODO(brianwilkerson) Replace this API.
+  void set auxiliaryElements(AuxiliaryElements elements);
+
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  MethodElement get bestElement;
+
+  /**
+   * Return the expression used to compute the index.
+   */
+  Expression get index;
+
+  /**
+   * Set the expression used to compute the index to the given [expression].
+   */
+  void set index(Expression expression);
+
+  /**
+   * Return `true` if this expression is cascaded. If it is, then the target of
+   * this expression is not stored locally but is stored in the nearest ancestor
+   * that is a [CascadeExpression].
+   */
+  bool get isCascaded;
+
+  /**
+   * Return the left square bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left square bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the period ("..") before a cascaded index expression, or `null` if
+   * this index expression is not part of a cascade expression.
+   */
+  Token get period;
+
+  /**
+   * Set the period ("..") before a cascaded index expression to the given
+   * [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the element associated with the operator based on the propagated
+   * type of the target, or `null` if the AST structure has not been resolved or
+   * if the operator could not be resolved.
+   */
+  MethodElement get propagatedElement;
+
+  /**
+   * Set the element associated with the operator based on the propagated
+   * type of the target to the given [element].
+   */
+  void set propagatedElement(MethodElement element);
+
+  /**
+   * Return the expression used to compute the object being indexed. If this
+   * index expression is not part of a cascade expression, then this is the same
+   * as [target]. If this index expression is part of a cascade expression, then
+   * the target expression stored with the cascade expression is returned.
+   */
+  Expression get realTarget;
+
+  /**
+   * Return the right square bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Return the element associated with the operator based on the static type of
+   * the target, or `null` if the AST structure has not been resolved or if the
+   * operator could not be resolved.
+   */
+  MethodElement get staticElement;
+
+  /**
+   * Set the element associated with the operator based on the static type of
+   * the target to the given [element].
+   */
+  void set staticElement(MethodElement element);
+
+  /**
+   * Return the expression used to compute the object being indexed, or `null`
+   * if this index expression is part of a cascade expression.
+   *
+   * Use [realTarget] to get the target independent of whether this is part of a
+   * cascade expression.
+   */
+  Expression get target;
+
+  /**
+   * Set the expression used to compute the object being indexed to the given
+   * [expression].
+   */
+  void set target(Expression expression);
+
+  /**
+   * Return `true` if this expression is computing a right-hand value (that is,
+   * if this expression is in a context where the operator '[]' will be
+   * invoked).
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+   * are they mutually exclusive. In other words, it is possible for both
+   * methods to return `true` when invoked on the same node.
+   */
+  // TODO(brianwilkerson) Convert this to a getter.
+  bool inGetterContext();
+
+  /**
+   * Return `true` if this expression is computing a left-hand value (that is,
+   * if this expression is in a context where the operator '[]=' will be
+   * invoked).
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+   * are they mutually exclusive. In other words, it is possible for both
+   * methods to return `true` when invoked on the same node.
+   */
+  // TODO(brianwilkerson) Convert this to a getter.
+  bool inSetterContext();
+}
+
+/**
+ * An instance creation expression.
+ *
+ * > newExpression ::=
+ * >     ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InstanceCreationExpression extends Expression {
+  /**
+   * Initialize a newly created instance creation expression.
+   */
+  factory InstanceCreationExpression(
+      Token keyword,
+      ConstructorName constructorName,
+      ArgumentList argumentList) = InstanceCreationExpressionImpl;
+
+  /**
+   * Return the list of arguments to the constructor.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * Set the list of arguments to the constructor to the given [argumentList].
+   */
+  void set argumentList(ArgumentList argumentList);
+
+  /**
+   * Return the name of the constructor to be invoked.
+   */
+  ConstructorName get constructorName;
+
+  /**
+   * Set the name of the constructor to be invoked to the given [name].
+   */
+  void set constructorName(ConstructorName name);
+
+  /**
+   * Return `true` if this creation expression is used to invoke a constant
+   * constructor.
+   */
+  bool get isConst;
+
+  /**
+   * Return the 'new' or 'const' keyword used to indicate how an object should
+   * be created.
+   */
+  Token get keyword;
+
+  /**
+   * Set the 'new' or 'const' keyword used to indicate how an object should be
+   * created to the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement get staticElement;
+
+  /**
+   * Set the element associated with the constructor based on static type
+   * information to the given [element].
+   */
+  void set staticElement(ConstructorElement element);
+}
+
+/**
+ * An integer literal expression.
+ *
+ * > integerLiteral ::=
+ * >     decimalIntegerLiteral
+ * >   | hexadecimalIntegerLiteral
+ * >
+ * > decimalIntegerLiteral ::=
+ * >     decimalDigit+
+ * >
+ * > hexadecimalIntegerLiteral ::=
+ * >     '0x' hexadecimalDigit+
+ * >   | '0X' hexadecimalDigit+
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class IntegerLiteral extends Literal {
+  /**
+   * Initialize a newly created integer literal.
+   */
+  factory IntegerLiteral(Token literal, int value) = IntegerLiteralImpl;
+
+  /**
+   * Return the token representing the literal.
+   */
+  Token get literal;
+
+  /**
+   * Set the token representing the literal to the given [token].
+   */
+  void set literal(Token token);
+
+  /**
+   * Return the value of the literal.
+   */
+  int get value;
+
+  /**
+   * Set the value of the literal to the given [value].
+   */
+  void set value(int value);
+}
+
+/**
+ * A node within a [StringInterpolation].
+ *
+ * > interpolationElement ::=
+ * >     [InterpolationExpression]
+ * >   | [InterpolationString]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InterpolationElement extends AstNode {}
+
+/**
+ * An expression embedded in a string interpolation.
+ *
+ * > interpolationExpression ::=
+ * >     '$' [SimpleIdentifier]
+ * >   | '$' '{' [Expression] '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InterpolationExpression extends InterpolationElement {
+  /**
+   * Initialize a newly created interpolation expression.
+   */
+  factory InterpolationExpression(
+          Token leftBracket, Expression expression, Token rightBracket) =
+      InterpolationExpressionImpl;
+
+  /**
+   * Return the expression to be evaluated for the value to be converted into a
+   * string.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression to be evaluated for the value to be converted into a
+   * string to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the token used to introduce the interpolation expression; either '$'
+   * if the expression is a simple identifier or '${' if the expression is a
+   * full expression.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the token used to introduce the interpolation expression; either '$'
+   * if the expression is a simple identifier or '${' if the expression is a
+   * full expression to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right curly bracket, or `null` if the expression is an
+   * identifier without brackets.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+}
+
+/**
+ * A non-empty substring of an interpolated string.
+ *
+ * > interpolationString ::=
+ * >     characters
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InterpolationString extends InterpolationElement {
+  /**
+   * Initialize a newly created string of characters that are part of a string
+   * interpolation.
+   */
+  factory InterpolationString(Token contents, String value) =
+      InterpolationStringImpl;
+
+  /**
+   * Return the characters that will be added to the string.
+   */
+  Token get contents;
+
+  /**
+   * Set the characters that will be added to the string to the given [token].
+   */
+  void set contents(Token token);
+
+  /**
+   * Return the offset of the after-last contents character.
+   */
+  int get contentsEnd;
+
+  /**
+   * Return the offset of the first contents character.
+   */
+  int get contentsOffset;
+
+  /**
+   * Return the value of the literal.
+   */
+  String get value;
+
+  /**
+   * Set the value of the literal to the given [value].
+   */
+  void set value(String value);
+}
+
+/**
+ * An is expression.
+ *
+ * > isExpression ::=
+ * >     [Expression] 'is' '!'? [TypeName]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class IsExpression extends Expression {
+  /**
+   * Initialize a newly created is expression. The [notOperator] can be `null`
+   * if the sense of the test is not negated.
+   */
+  factory IsExpression(Expression expression, Token isOperator,
+      Token notOperator, TypeName type) = IsExpressionImpl;
+
+  /**
+   * Return the expression used to compute the value whose type is being tested.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression used to compute the value whose type is being tested to
+   * the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the is operator.
+   */
+  Token get isOperator;
+
+  /**
+   * Set the is operator to the given [token].
+   */
+  void set isOperator(Token token);
+
+  /**
+   * Return the not operator, or `null` if the sense of the test is not negated.
+   */
+  Token get notOperator;
+
+  /**
+   * Set the not operator to the given [token].
+   */
+  void set notOperator(Token token);
+
+  /**
+   * Return the name of the type being tested for.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the type being tested for to the given [name].
+   */
+  void set type(TypeName name);
+}
+
+/**
+ * A label on either a [LabeledStatement] or a [NamedExpression].
+ *
+ * > label ::=
+ * >     [SimpleIdentifier] ':'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Label extends AstNode {
+  /**
+   * Initialize a newly created label.
+   */
+  factory Label(SimpleIdentifier label, Token colon) = LabelImpl;
+
+  /**
+   * Return the colon that separates the label from the statement.
+   */
+  Token get colon;
+
+  /**
+   * Set the colon that separates the label from the statement to the given
+   * [token].
+   */
+  void set colon(Token token);
+
+  /**
+   * Return the label being associated with the statement.
+   */
+  SimpleIdentifier get label;
+
+  /**
+   * Set the label being associated with the statement to the given [label].
+   */
+  void set label(SimpleIdentifier label);
+}
+
+/**
+ * A statement that has a label associated with them.
+ *
+ * > labeledStatement ::=
+ * >    [Label]+ [Statement]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LabeledStatement extends Statement {
+  /**
+   * Initialize a newly created labeled statement.
+   */
+  factory LabeledStatement(List<Label> labels, Statement statement) =
+      LabeledStatementImpl;
+
+  /**
+   * Return the labels being associated with the statement.
+   */
+  NodeList<Label> get labels;
+
+  /**
+   * Return the statement with which the labels are being associated.
+   */
+  Statement get statement;
+
+  /**
+   * Set the statement with which the labels are being associated to the given
+   * [statement].
+   */
+  void set statement(Statement statement);
+}
+
+/**
+ * A library directive.
+ *
+ * > libraryDirective ::=
+ * >     [Annotation] 'library' [Identifier] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LibraryDirective extends Directive {
+  /**
+   * Initialize a newly created library directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  factory LibraryDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token libraryKeyword,
+      LibraryIdentifier name,
+      Token semicolon) = LibraryDirectiveImpl;
+
+  /**
+   * Return the token representing the 'library' keyword.
+   */
+  Token get libraryKeyword;
+
+  /**
+   * Set the token representing the 'library' keyword to the given [token].
+   */
+  void set libraryKeyword(Token token);
+
+  /**
+   * Return the name of the library being defined.
+   */
+  LibraryIdentifier get name;
+
+  /**
+   * Set the name of the library being defined to the given [name].
+   */
+  void set name(LibraryIdentifier name);
+
+  /**
+   * Return the semicolon terminating the directive.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the directive to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * The identifier for a library.
+ *
+ * > libraryIdentifier ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class LibraryIdentifier extends Identifier {
+  /**
+   * Initialize a newly created prefixed identifier.
+   */
+  factory LibraryIdentifier(List<SimpleIdentifier> components) =
+      LibraryIdentifierImpl;
+
+  /**
+   * Return the components of the identifier.
+   */
+  NodeList<SimpleIdentifier> get components;
+}
+
+/**
+ * A list literal.
+ *
+ * > listLiteral ::=
+ * >     'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ListLiteral extends TypedLiteral {
+  /**
+   * Initialize a newly created list literal. The [constKeyword] can be `null`
+   * if the literal is not a constant. The [typeArguments] can be `null` if no
+   * type arguments were declared. The list of [elements] can be `null` if the
+   * list is empty.
+   */
+  factory ListLiteral(
+      Token constKeyword,
+      TypeArgumentList typeArguments,
+      Token leftBracket,
+      List<Expression> elements,
+      Token rightBracket) = ListLiteralImpl;
+
+  /**
+   * Return the expressions used to compute the elements of the list.
+   */
+  NodeList<Expression> get elements;
+
+  /**
+   * Return the left square bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left square bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right square bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right square bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+}
+
+/**
+ * A node that represents a literal expression.
+ *
+ * > literal ::=
+ * >     [BooleanLiteral]
+ * >   | [DoubleLiteral]
+ * >   | [IntegerLiteral]
+ * >   | [ListLiteral]
+ * >   | [MapLiteral]
+ * >   | [NullLiteral]
+ * >   | [StringLiteral]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Literal extends Expression {}
+
+/**
+ * A literal map.
+ *
+ * > mapLiteral ::=
+ * >     'const'? ('<' [TypeName] (',' [TypeName])* '>')?
+ * >     '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MapLiteral extends TypedLiteral {
+  /**
+   * Initialize a newly created map literal. The [constKeyword] can be `null` if
+   * the literal is not a constant. The [typeArguments] can be `null` if no type
+   * arguments were declared. The [entries] can be `null` if the map is empty.
+   */
+  factory MapLiteral(
+      Token constKeyword,
+      TypeArgumentList typeArguments,
+      Token leftBracket,
+      List<MapLiteralEntry> entries,
+      Token rightBracket) = MapLiteralImpl;
+
+  /**
+   * Return the entries in the map.
+   */
+  NodeList<MapLiteralEntry> get entries;
+
+  /**
+   * Return the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left curly bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+}
+
+/**
+ * A single key/value pair in a map literal.
+ *
+ * > mapLiteralEntry ::=
+ * >     [Expression] ':' [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MapLiteralEntry extends AstNode {
+  /**
+   * Initialize a newly created map literal entry.
+   */
+  factory MapLiteralEntry(Expression key, Token separator, Expression value) =
+      MapLiteralEntryImpl;
+
+  /**
+   * Return the expression computing the key with which the value will be
+   * associated.
+   */
+  Expression get key;
+
+  /**
+   * Set the expression computing the key with which the value will be
+   * associated to the given [string].
+   */
+  void set key(Expression string);
+
+  /**
+   * Return the colon that separates the key from the value.
+   */
+  Token get separator;
+
+  /**
+   * Set the colon that separates the key from the value to the given [token].
+   */
+  void set separator(Token token);
+
+  /**
+   * Return the expression computing the value that will be associated with the
+   * key.
+   */
+  Expression get value;
+
+  /**
+   * Set the expression computing the value that will be associated with the key
+   * to the given [expression].
+   */
+  void set value(Expression expression);
+}
+
+/**
+ * A method declaration.
+ *
+ * > methodDeclaration ::=
+ * >     methodSignature [FunctionBody]
+ * >
+ * > methodSignature ::=
+ * >     'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
+ * >     methodName [TypeParameterList] [FormalParameterList]
+ * >
+ * > methodName ::=
+ * >     [SimpleIdentifier]
+ * >   | 'operator' [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MethodDeclaration extends ClassMember {
+  /**
+   * Initialize a newly created method declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the method
+   * is not external. The [modifierKeyword] can be `null` if the method is
+   * neither abstract nor static. The [returnType] can be `null` if no return
+   * type was specified. The [propertyKeyword] can be `null` if the method is
+   * neither a getter or a setter. The [operatorKeyword] can be `null` if the
+   * method does not implement an operator. The [parameters] must be `null` if
+   * this method declares a getter.
+   */
+  factory MethodDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      Token externalKeyword,
+      Token modifierKeyword,
+      TypeName returnType,
+      Token propertyKeyword,
+      Token operatorKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      FunctionBody body) = MethodDeclarationImpl;
+
+  /**
+   * Return the body of the method.
+   */
+  FunctionBody get body;
+
+  /**
+   * Set the body of the method to the given [functionBody].
+   */
+  void set body(FunctionBody functionBody);
+
+  @override
+  ExecutableElement get element;
+
+  /**
+   * Return the token for the 'external' keyword, or `null` if the constructor
+   * is not external.
+   */
+  Token get externalKeyword;
+
+  /**
+   * Set the token for the 'external' keyword to the given [token].
+   */
+  void set externalKeyword(Token token);
+
+  /**
+   * Return `true` if this method is declared to be an abstract method.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this method declares a getter.
+   */
+  bool get isGetter;
+
+  /**
+   * Return `true` if this method declares an operator.
+   */
+  bool get isOperator;
+
+  /**
+   * Return `true` if this method declares a setter.
+   */
+  bool get isSetter;
+
+  /**
+   * Return `true` if this method is declared to be a static method.
+   */
+  bool get isStatic;
+
+  /**
+   * Return the token representing the 'abstract' or 'static' keyword, or `null`
+   * if neither modifier was specified.
+   */
+  Token get modifierKeyword;
+
+  /**
+   * Set the token representing the 'abstract' or 'static' keyword to the given
+   * [token].
+   */
+  void set modifierKeyword(Token token);
+
+  /**
+   * Return the name of the method.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the method to the given [identifier].
+   */
+  void set name(SimpleIdentifier identifier);
+
+  /**
+   * Return the token representing the 'operator' keyword, or `null` if this
+   * method does not declare an operator.
+   */
+  Token get operatorKeyword;
+
+  /**
+   * Set the token representing the 'operator' keyword to the given [token].
+   */
+  void set operatorKeyword(Token token);
+
+  /**
+   * Return the parameters associated with the method, or `null` if this method
+   * declares a getter.
+   */
+  FormalParameterList get parameters;
+
+  /**
+   * Set the parameters associated with the method to the given list of
+   * [parameters].
+   */
+  void set parameters(FormalParameterList parameters);
+
+  /**
+   * Return the token representing the 'get' or 'set' keyword, or `null` if this
+   * is a method declaration rather than a property declaration.
+   */
+  Token get propertyKeyword;
+
+  /**
+   * Set the token representing the 'get' or 'set' keyword to the given [token].
+   */
+  void set propertyKeyword(Token token);
+
+  /**
+   * Return the return type of the method, or `null` if no return type was
+   * declared.
+   */
+  TypeName get returnType;
+
+  /**
+   * Set the return type of the method to the given [typeName].
+   */
+  void set returnType(TypeName typeName);
+
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters);
+}
+
+/**
+ * The invocation of either a function or a method. Invocations of functions
+ * resulting from evaluating an expression are represented by
+ * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
+ * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+ *
+ * > methodInvocation ::=
+ * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class MethodInvocation extends Expression {
+  /**
+   * Initialize a newly created method invocation. The [target] and [operator]
+   * can be `null` if there is no target.
+   */
+  factory MethodInvocation(
+      Expression target,
+      Token operator,
+      SimpleIdentifier methodName,
+      TypeArgumentList typeArguments,
+      ArgumentList argumentList) = MethodInvocationImpl;
+
+  /**
+   * Return the list of arguments to the method.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * Set the list of arguments to the method to the given [argumentList].
+   */
+  void set argumentList(ArgumentList argumentList);
+
+  /**
+   * Return `true` if this expression is cascaded. If it is, then the target of
+   * this expression is not stored locally but is stored in the nearest ancestor
+   * that is a [CascadeExpression].
+   */
+  bool get isCascaded;
+
+  /**
+   * Return the name of the method being invoked.
+   */
+  SimpleIdentifier get methodName;
+
+  /**
+   * Set the name of the method being invoked to the given [identifier].
+   */
+  void set methodName(SimpleIdentifier identifier);
+
+  /**
+   * Return the operator that separates the target from the method name, or
+   * `null` if there is no target. In an ordinary method invocation this will be
+   *  * period ('.'). In a cascade section this will be the cascade operator
+   * ('..').
+   */
+  Token get operator;
+
+  /**
+   * Set the operator that separates the target from the method name to the
+   * given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the function type of the method invocation based on the propagated
+   * type information, or `null` if the AST structure has not been resolved, or
+   * if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get propagatedInvokeType;
+
+  /**
+   * Set the function type of the method invocation based on the propagated type
+   * information to the given [type].
+   */
+  void set propagatedInvokeType(DartType type);
+
+  /**
+   * Return the expression used to compute the receiver of the invocation. If
+   * this invocation is not part of a cascade expression, then this is the same
+   * as [target]. If this invocation is part of a cascade expression, then the
+   * target stored with the cascade expression is returned.
+   */
+  Expression get realTarget;
+
+  /**
+   * Return the function type of the method invocation based on the static type
+   * information, or `null` if the AST structure has not been resolved, or if
+   * the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get staticInvokeType;
+
+  /**
+   * Set the function type of the method invocation based on the static type
+   * information to the given [type].
+   */
+  void set staticInvokeType(DartType type);
+
+  /**
+   * Return the expression producing the object on which the method is defined,
+   * or `null` if there is no target (that is, the target is implicitly `this`)
+   * or if this method invocation is part of a cascade expression.
+   *
+   * Use [realTarget] to get the target independent of whether this is part of a
+   * cascade expression.
+   */
+  Expression get target;
+
+  /**
+   * Set the expression producing the object on which the method is defined to
+   * the given [expression].
+   */
+  void set target(Expression expression);
+
+  /**
+   * Return the type arguments to be applied to the method being invoked, or
+   * `null` if no type arguments were provided.
+   */
+  TypeArgumentList get typeArguments;
+
+  /**
+   * Set the type arguments to be applied to the method being invoked to the
+   * given [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments);
+}
+
+/**
+ * A node that declares a single name within the scope of a compilation unit.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NamedCompilationUnitMember extends CompilationUnitMember {
+  /**
+   * Return the name of the member being declared.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the member being declared to the given [identifier].
+   */
+  void set name(SimpleIdentifier identifier);
+}
+
+/**
+ * An expression that has a name associated with it. They are used in method
+ * invocations when there are named parameters.
+ *
+ * > namedExpression ::=
+ * >     [Label] [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NamedExpression extends Expression {
+  /**
+   * Initialize a newly created named expression..
+   */
+  factory NamedExpression(Label name, Expression expression) =
+      NamedExpressionImpl;
+
+  /**
+   * Return the element representing the parameter being named by this
+   * expression, or `null` if the AST structure has not been resolved or if
+   * there is no parameter with the same name as this expression.
+   */
+  ParameterElement get element;
+
+  /**
+   * Return the expression with which the name is associated.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression with which the name is associated to the given
+   * [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the name associated with the expression.
+   */
+  Label get name;
+
+  /**
+   * Set the name associated with the expression to the given [identifier].
+   */
+  void set name(Label identifier);
+}
+
+/**
+ * A node that represents a directive that impacts the namespace of a library.
+ *
+ * > directive ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NamespaceDirective extends UriBasedDirective {
+  /**
+   * Return the combinators used to control how names are imported or exported.
+   */
+  NodeList<Combinator> get combinators;
+
+  /**
+   * Return the configurations used to control which library will actually be
+   * loaded at run-time.
+   */
+  NodeList<Configuration> get configurations;
+
+  /**
+   * Set the token representing the keyword that introduces this directive
+   * ('import', 'export', 'library' or 'part') to the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the semicolon terminating the directive.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the directive to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * The "native" clause in an class declaration.
+ *
+ * > nativeClause ::=
+ * >     'native' [StringLiteral]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NativeClause extends AstNode {
+  /**
+   * Initialize a newly created native clause.
+   */
+  factory NativeClause(Token nativeKeyword, StringLiteral name) =
+      NativeClauseImpl;
+
+  /**
+   * Return the name of the native object that implements the class.
+   */
+  StringLiteral get name;
+
+  /**
+   * Set the name of the native object that implements the class to the given
+   * [name].
+   */
+  void set name(StringLiteral name);
+
+  /**
+   * Return the token representing the 'native' keyword.
+   */
+  Token get nativeKeyword;
+
+  /**
+   * Set the token representing the 'native' keyword to the given [token].
+   */
+  void set nativeKeyword(Token token);
+}
+
+/**
+ * A function body that consists of a native keyword followed by a string
+ * literal.
+ *
+ * > nativeFunctionBody ::=
+ * >     'native' [SimpleStringLiteral] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NativeFunctionBody extends FunctionBody {
+  /**
+   * Initialize a newly created function body consisting of the 'native' token,
+   * a string literal, and a semicolon.
+   */
+  factory NativeFunctionBody(
+          Token nativeKeyword, StringLiteral stringLiteral, Token semicolon) =
+      NativeFunctionBodyImpl;
+
+  /**
+   * Return the token representing 'native' that marks the start of the function
+   * body.
+   */
+  Token get nativeKeyword;
+
+  /**
+   * Set the token representing 'native' that marks the start of the function
+   * body to the given [token].
+   */
+  void set nativeKeyword(Token token);
+
+  /**
+   * Return the token representing the semicolon that marks the end of the
+   * function body.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the token representing the semicolon that marks the end of the
+   * function body to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the string literal representing the string after the 'native' token.
+   */
+  StringLiteral get stringLiteral;
+
+  /**
+   * Set the string literal representing the string after the 'native' token to
+   * the given [stringLiteral].
+   */
+  void set stringLiteral(StringLiteral stringLiteral);
+}
+
+/**
+ * A list of AST nodes that have a common parent.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NodeList<E extends AstNode> implements List<E> {
+  /**
+   * Initialize a newly created list of nodes such that all of the nodes that
+   * are added to the list will have their parent set to the given [owner]. The
+   * list will initially be populated with the given [elements].
+   */
+  factory NodeList(AstNode owner, [List<E> elements]) = NodeListImpl;
+
+  /**
+   * Return the first token included in this node list's source range, or `null`
+   * if the list is empty.
+   */
+  Token get beginToken;
+
+  /**
+   * Return the last token included in this node list's source range, or `null`
+   * if the list is empty.
+   */
+  Token get endToken;
+
+  /**
+   * Return the node that is the parent of each of the elements in the list.
+   */
+  AstNode get owner;
+
+  /**
+   * Set the node that is the parent of each of the elements in the list to the
+   * given [node].
+   */
+  @deprecated // Never intended for public use.
+  void set owner(AstNode node);
+
+  /**
+   * Return the node at the given [index] in the list or throw a [RangeError] if
+   * [index] is out of bounds.
+   */
+  E operator [](int index);
+
+  /**
+   * Set the node at the given [index] in the list to the given [node] or throw
+   * a [RangeError] if [index] is out of bounds.
+   */
+  void operator []=(int index, E node);
+
+  /**
+   * Use the given [visitor] to visit each of the nodes in this list.
+   */
+  accept(AstVisitor visitor);
+}
+
+/**
+ * A formal parameter that is required (is not optional).
+ *
+ * > normalFormalParameter ::=
+ * >     [FunctionTypedFormalParameter]
+ * >   | [FieldFormalParameter]
+ * >   | [SimpleFormalParameter]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NormalFormalParameter extends FormalParameter {
+  /**
+   * Return the documentation comment associated with this parameter, or `null`
+   * if this parameter does not have a documentation comment associated with it.
+   */
+  Comment get documentationComment;
+
+  /**
+   * Set the documentation comment associated with this parameter to the given
+   * [comment].
+   */
+  void set documentationComment(Comment comment);
+
+  /**
+   * Set the name of the parameter being declared to the given [identifier].
+   */
+  void set identifier(SimpleIdentifier identifier);
+
+  /**
+   * Set the metadata associated with this node to the given [metadata].
+   */
+  void set metadata(List<Annotation> metadata);
+
+  /**
+   * Return a list containing the comment and annotations associated with this
+   * parameter, sorted in lexical order.
+   */
+  List<AstNode> get sortedCommentAndAnnotations;
+}
+
+/**
+ * A null literal expression.
+ *
+ * > nullLiteral ::=
+ * >     'null'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class NullLiteral extends Literal {
+  /**
+   * Initialize a newly created null literal.
+   */
+  factory NullLiteral(Token literal) = NullLiteralImpl;
+
+  /**
+   * Return the token representing the literal.
+   */
+  Token get literal;
+
+  /**
+   * Set the token representing the literal to the given [token].
+   */
+  void set literal(Token token);
+}
+
+/**
+ * A parenthesized expression.
+ *
+ * > parenthesizedExpression ::=
+ * >     '(' [Expression] ')'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ParenthesizedExpression extends Expression {
+  /**
+   * Initialize a newly created parenthesized expression.
+   */
+  factory ParenthesizedExpression(Token leftParenthesis, Expression expression,
+      Token rightParenthesis) = ParenthesizedExpressionImpl;
+
+  /**
+   * Return the expression within the parentheses.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression within the parentheses to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+}
+
+/**
+ * A part directive.
+ *
+ * > partDirective ::=
+ * >     [Annotation] 'part' [StringLiteral] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PartDirective extends UriBasedDirective {
+  /**
+   * Initialize a newly created part directive. Either or both of the [comment]
+   * and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  factory PartDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token partKeyword,
+      StringLiteral partUri,
+      Token semicolon) = PartDirectiveImpl;
+
+  /**
+   * Return the token representing the 'part' keyword.
+   */
+  Token get partKeyword;
+
+  /**
+   * Set the token representing the 'part' keyword to the given [token].
+   */
+  void set partKeyword(Token token);
+
+  /**
+   * Return the semicolon terminating the directive.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the directive to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * A part-of directive.
+ *
+ * > partOfDirective ::=
+ * >     [Annotation] 'part' 'of' [Identifier] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PartOfDirective extends Directive {
+  /**
+   * Initialize a newly created part-of directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  factory PartOfDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token partKeyword,
+      Token ofKeyword,
+      LibraryIdentifier libraryName,
+      Token semicolon) = PartOfDirectiveImpl;
+
+  /**
+   * Return the name of the library that the containing compilation unit is part
+   * of.
+   */
+  LibraryIdentifier get libraryName;
+
+  /**
+   * Set the name of the library that the containing compilation unit is part of
+   * to the given [libraryName].
+   */
+  void set libraryName(LibraryIdentifier libraryName);
+
+  /**
+   * Return the token representing the 'of' keyword.
+   */
+  Token get ofKeyword;
+
+  /**
+   * Set the token representing the 'of' keyword to the given [token].
+   */
+  void set ofKeyword(Token token);
+
+  /**
+   * Return the token representing the 'part' keyword.
+   */
+  Token get partKeyword;
+
+  /**
+   * Set the token representing the 'part' keyword to the given [token].
+   */
+  void set partKeyword(Token token);
+
+  /**
+   * Return the semicolon terminating the directive.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the directive to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * A postfix unary expression.
+ *
+ * > postfixExpression ::=
+ * >     [Expression] [Token]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PostfixExpression extends Expression {
+  /**
+   * Initialize a newly created postfix expression.
+   */
+  factory PostfixExpression(Expression operand, Token operator) =
+      PostfixExpressionImpl;
+
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  MethodElement get bestElement;
+
+  /**
+   * Return the expression computing the operand for the operator.
+   */
+  Expression get operand;
+
+  /**
+   * Set the expression computing the operand for the operator to the given
+   * [expression].
+   */
+  void set operand(Expression expression);
+
+  /**
+   * Return the postfix operator being applied to the operand.
+   */
+  Token get operator;
+
+  /**
+   * Set the postfix operator being applied to the operand to the given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the element associated with this the operator based on the
+   * propagated type of the operand, or `null` if the AST structure has not been
+   * resolved, if the operator is not user definable, or if the operator could
+   * not be resolved.
+   */
+  MethodElement get propagatedElement;
+
+  /**
+   * Set the element associated with this the operator based on the propagated
+   * type of the operand to the given [element].
+   */
+  void set propagatedElement(MethodElement element);
+
+  /**
+   * Return the element associated with the operator based on the static type of
+   * the operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement get staticElement;
+
+  /**
+   * Set the element associated with the operator based on the static type of
+   * the operand to the given [element].
+   */
+  void set staticElement(MethodElement element);
+}
+
+/**
+ * An identifier that is prefixed or an access to an object property where the
+ * target of the property access is a simple identifier.
+ *
+ * > prefixedIdentifier ::=
+ * >     [SimpleIdentifier] '.' [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PrefixedIdentifier extends Identifier {
+  /**
+   * Initialize a newly created prefixed identifier.
+   */
+  factory PrefixedIdentifier(
+          SimpleIdentifier prefix, Token period, SimpleIdentifier identifier) =
+      PrefixedIdentifierImpl;
+
+  /**
+   * Return the identifier being prefixed.
+   */
+  SimpleIdentifier get identifier;
+
+  /**
+   * Set the identifier being prefixed to the given [identifier].
+   */
+  void set identifier(SimpleIdentifier identifier);
+
+  /**
+   * Return `true` if this type is a deferred type. If the AST structure has not
+   * been resolved, then return `false`.
+   *
+   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
+   * </i>p.T</i> where <i>p</i> is a deferred prefix.
+   */
+  bool get isDeferred;
+
+  /**
+   * Return the period used to separate the prefix from the identifier.
+   */
+  Token get period;
+
+  /**
+   * Set the period used to separate the prefix from the identifier to the given
+   * [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the prefix associated with the library in which the identifier is
+   * defined.
+   */
+  SimpleIdentifier get prefix;
+
+  /**
+   * Set the prefix associated with the library in which the identifier is
+   * defined to the given [identifier].
+   */
+  void set prefix(SimpleIdentifier identifier);
+}
+
+/**
+ * A prefix unary expression.
+ *
+ * > prefixExpression ::=
+ * >     [Token] [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PrefixExpression extends Expression {
+  /**
+   * Initialize a newly created prefix expression.
+   */
+  factory PrefixExpression(Token operator, Expression operand) =
+      PrefixExpressionImpl;
+
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  MethodElement get bestElement;
+
+  /**
+   * Return the expression computing the operand for the operator.
+   */
+  Expression get operand;
+
+  /**
+   * Set the expression computing the operand for the operator to the given
+   * [expression].
+   */
+  void set operand(Expression expression);
+
+  /**
+   * Return the prefix operator being applied to the operand.
+   */
+  Token get operator;
+
+  /**
+   * Set the prefix operator being applied to the operand to the given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the element associated with the operator based on the propagated
+   * type of the operand, or `null` if the AST structure has not been resolved,
+   * if the operator is not user definable, or if the operator could not be
+   * resolved.
+   */
+  MethodElement get propagatedElement;
+
+  /**
+   * Set the element associated with the operator based on the propagated type
+   * of the operand to the given [element].
+   */
+  void set propagatedElement(MethodElement element);
+
+  /**
+   * Return the element associated with the operator based on the static type of
+   * the operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement get staticElement;
+
+  /**
+   * Set the element associated with the operator based on the static type of
+   * the operand to the given [element].
+   */
+  void set staticElement(MethodElement element);
+}
+
+/**
+ * The access of a property of an object.
+ *
+ * Note, however, that accesses to properties of objects can also be represented
+ * as [PrefixedIdentifier] nodes in cases where the target is also a simple
+ * identifier.
+ *
+ * > propertyAccess ::=
+ * >     [Expression] '.' [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class PropertyAccess extends Expression {
+  /**
+   * Initialize a newly created property access expression.
+   */
+  factory PropertyAccess(
+          Expression target, Token operator, SimpleIdentifier propertyName) =
+      PropertyAccessImpl;
+
+  /**
+   * Return `true` if this expression is cascaded. If it is, then the target of
+   * this expression is not stored locally but is stored in the nearest ancestor
+   * that is a [CascadeExpression].
+   */
+  bool get isCascaded;
+
+  /**
+   * Return the property access operator.
+   */
+  Token get operator;
+
+  /**
+   * Set the property access operator to the given [token].
+   */
+  void set operator(Token token);
+
+  /**
+   * Return the name of the property being accessed.
+   */
+  SimpleIdentifier get propertyName;
+
+  /**
+   * Set the name of the property being accessed to the given [identifier].
+   */
+  void set propertyName(SimpleIdentifier identifier);
+
+  /**
+   * Return the expression used to compute the receiver of the invocation. If
+   * this invocation is not part of a cascade expression, then this is the same
+   * as [target]. If this invocation is part of a cascade expression, then the
+   * target stored with the cascade expression is returned.
+   */
+  Expression get realTarget;
+
+  /**
+   * Return the expression computing the object defining the property being
+   * accessed, or `null` if this property access is part of a cascade expression.
+   *
+   * Use [realTarget] to get the target independent of whether this is part of a
+   * cascade expression.
+   */
+  Expression get target;
+
+  /**
+   * Set the expression computing the object defining the property being
+   * accessed to the given [expression].
+   */
+  void set target(Expression expression);
+}
+
+/**
+ * The invocation of a constructor in the same class from within a constructor's
+ * initialization list.
+ *
+ * > redirectingConstructorInvocation ::=
+ * >     'this' ('.' identifier)? arguments
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class RedirectingConstructorInvocation extends ConstructorInitializer {
+  /**
+   * Initialize a newly created redirecting invocation to invoke the constructor
+   * with the given name with the given arguments. The [constructorName] can be
+   * `null` if the constructor being invoked is the unnamed constructor.
+   */
+  factory RedirectingConstructorInvocation(
+      Token thisKeyword,
+      Token period,
+      SimpleIdentifier constructorName,
+      ArgumentList argumentList) = RedirectingConstructorInvocationImpl;
+
+  /**
+   * Return the list of arguments to the constructor.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * Set the list of arguments to the constructor to the given [argumentList].
+   */
+  void set argumentList(ArgumentList argumentList);
+
+  /**
+   * Return the name of the constructor that is being invoked, or `null` if the
+   * unnamed constructor is being invoked.
+   */
+  SimpleIdentifier get constructorName;
+
+  /**
+   * Set the name of the constructor that is being invoked to the given
+   * [identifier].
+   */
+  void set constructorName(SimpleIdentifier identifier);
+
+  /**
+   * Return the token for the period before the name of the constructor that is
+   * being invoked, or `null` if the unnamed constructor is being invoked.
+   */
+  Token get period;
+
+  /**
+   * Set the token for the period before the name of the constructor that is
+   * being invoked to the given [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement get staticElement;
+
+  /**
+   * Set the element associated with the constructor based on static type
+   * information to the given [element].
+   */
+  void set staticElement(ConstructorElement element);
+
+  /**
+   * Return the token for the 'this' keyword.
+   */
+  Token get thisKeyword;
+
+  /**
+   * Set the token for the 'this' keyword to the given [token].
+   */
+  void set thisKeyword(Token token);
+}
+
+/**
+ * A rethrow expression.
+ *
+ * > rethrowExpression ::=
+ * >     'rethrow'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class RethrowExpression extends Expression {
+  /**
+   * Initialize a newly created rethrow expression.
+   */
+  factory RethrowExpression(Token rethrowKeyword) = RethrowExpressionImpl;
+
+  /**
+   * Return the token representing the 'rethrow' keyword.
+   */
+  Token get rethrowKeyword;
+
+  /**
+   * Set the token representing the 'rethrow' keyword to the given [token].
+   */
+  void set rethrowKeyword(Token token);
+}
+
+/**
+ * A return statement.
+ *
+ * > returnStatement ::=
+ * >     'return' [Expression]? ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ReturnStatement extends Statement {
+  /**
+   * Initialize a newly created return statement. The [expression] can be `null`
+   * if no explicit value was provided.
+   */
+  factory ReturnStatement(
+          Token returnKeyword, Expression expression, Token semicolon) =
+      ReturnStatementImpl;
+
+  /**
+   * Return the expression computing the value to be returned, or `null` if no
+   * explicit value was provided.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression computing the value to be returned to the given
+   * [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the token representing the 'return' keyword.
+   */
+  Token get returnKeyword;
+
+  /**
+   * Set the token representing the 'return' keyword to the given [token].
+   */
+  void set returnKeyword(Token token);
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+}
+
+/**
+ * A script tag that can optionally occur at the beginning of a compilation unit.
+ *
+ * > scriptTag ::=
+ * >     '#!' (~NEWLINE)* NEWLINE
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ScriptTag extends AstNode {
+  /**
+   * Initialize a newly created script tag.
+   */
+  factory ScriptTag(Token scriptTag) = ScriptTagImpl;
+
+  /**
+   * Return the token representing this script tag.
+   */
+  Token get scriptTag;
+
+  /**
+   * Set the token representing this script tag to the given [token].
+   */
+  void set scriptTag(Token token);
+}
+
+/**
+ * A combinator that restricts the names being imported to those in a given list.
+ *
+ * > showCombinator ::=
+ * >     'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ShowCombinator extends Combinator {
+  /**
+   * Initialize a newly created import show combinator.
+   */
+  factory ShowCombinator(Token keyword, List<SimpleIdentifier> shownNames) =
+      ShowCombinatorImpl;
+
+  /**
+   * Return the list of names from the library that are made visible by this
+   * combinator.
+   */
+  NodeList<SimpleIdentifier> get shownNames;
+}
+
+/**
+ * A simple formal parameter.
+ *
+ * > simpleFormalParameter ::=
+ * >     ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SimpleFormalParameter extends NormalFormalParameter {
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  factory SimpleFormalParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      SimpleIdentifier identifier) = SimpleFormalParameterImpl;
+
+  /**
+   * Return the token representing either the 'final', 'const' or 'var' keyword,
+   * or `null` if no keyword was used.
+   */
+  Token get keyword;
+
+  /**
+   * Set the token representing either the 'final', 'const' or 'var' keyword to
+   * the given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the name of the declared type of the parameter, or `null` if the
+   * parameter does not have a declared type.
+   */
+  TypeName get type;
+
+  /**
+   * Set the name of the declared type of the parameter to the given [typeName].
+   */
+  void set type(TypeName typeName);
+}
+
+/**
+ * A simple identifier.
+ *
+ * > simpleIdentifier ::=
+ * >     initialCharacter internalCharacter*
+ * >
+ * > initialCharacter ::= '_' | '$' | letter
+ * >
+ * > internalCharacter ::= '_' | '$' | letter | digit
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SimpleIdentifier extends Identifier {
+  /**
+   * Initialize a newly created identifier.
+   */
+  factory SimpleIdentifier(Token token) = SimpleIdentifierImpl;
+
+  /**
+   * Return the auxiliary elements associated with this identifier, or `null` if
+   * this identifier is not in both a getter and setter context. The auxiliary
+   * elements hold the static and propagated elements associated with the getter
+   * context.
+   */
+  // TODO(brianwilkerson) Replace this API.
+  AuxiliaryElements get auxiliaryElements;
+
+  /**
+   * Set the auxiliary elements associated with this identifier to the given
+   * [elements].
+   */
+  // TODO(brianwilkerson) Replace this API.
+  void set auxiliaryElements(AuxiliaryElements elements);
+
+  /**
+   * Return `true` if this identifier is the "name" part of a prefixed
+   * identifier or a method invocation.
+   */
+  bool get isQualified;
+
+  /**
+   * Set the element associated with this identifier based on propagated type
+   * information to the given [element].
+   */
+  void set propagatedElement(Element element);
+
+  /**
+   * Set the element associated with this identifier based on static type
+   * information to the given [element].
+   */
+  void set staticElement(Element element);
+
+  /**
+   * Return the token representing the identifier.
+   */
+  Token get token;
+
+  /**
+   * Set the token representing the identifier to the given [token].
+   */
+  void set token(Token token);
+
+  /**
+   * Return `true` if this identifier is the name being declared in a
+   * declaration.
+   */
+  // TODO(brianwilkerson) Convert this to a getter.
+  bool inDeclarationContext();
+
+  /**
+   * Return `true` if this expression is computing a right-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+   * are they mutually exclusive. In other words, it is possible for both
+   * methods to return `true` when invoked on the same node.
+   */
+  // TODO(brianwilkerson) Convert this to a getter.
+  bool inGetterContext();
+
+  /**
+   * Return `true` if this expression is computing a left-hand value.
+   *
+   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
+   * are they mutually exclusive. In other words, it is possible for both
+   * methods to return `true` when invoked on the same node.
+   */
+  // TODO(brianwilkerson) Convert this to a getter.
+  bool inSetterContext();
+}
+
+/**
+ * A string literal expression that does not contain any interpolations.
+ *
+ * > simpleStringLiteral ::=
+ * >     rawStringLiteral
+ * >   | basicStringLiteral
+ * >
+ * > rawStringLiteral ::=
+ * >     'r' basicStringLiteral
+ * >
+ * > simpleStringLiteral ::=
+ * >     multiLineStringLiteral
+ * >   | singleLineStringLiteral
+ * >
+ * > multiLineStringLiteral ::=
+ * >     "'''" characters "'''"
+ * >   | '"""' characters '"""'
+ * >
+ * > singleLineStringLiteral ::=
+ * >     "'" characters "'"
+ * >   | '"' characters '"'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SimpleStringLiteral extends SingleStringLiteral {
+  /**
+   * Initialize a newly created simple string literal.
+   */
+  factory SimpleStringLiteral(Token literal, String value) =
+      SimpleStringLiteralImpl;
+
+  /**
+   * Return the token representing the literal.
+   */
+  Token get literal;
+
+  /**
+   * Set the token representing the literal to the given [token].
+   */
+  void set literal(Token token);
+
+  /**
+   * Return the value of the literal.
+   */
+  String get value;
+
+  /**
+   * Set the value of the literal to the given [string].
+   */
+  void set value(String string);
+}
+
+/**
+ * A single string literal expression.
+ *
+ * > singleStringLiteral ::=
+ * >     [SimpleStringLiteral]
+ * >   | [StringInterpolation]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SingleStringLiteral extends StringLiteral {
+  /**
+   * Return the offset of the after-last contents character.
+   */
+  int get contentsEnd;
+
+  /**
+   * Return the offset of the first contents character.
+   * If the string is multiline, then leading whitespaces are skipped.
+   */
+  int get contentsOffset;
+
+  /**
+   * Return `true` if this string literal is a multi-line string.
+   */
+  bool get isMultiline;
+
+  /**
+   * Return `true` if this string literal is a raw string.
+   */
+  bool get isRaw;
+
+  /**
+   * Return `true` if this string literal uses single quotes (' or ''').
+   * Return `false` if this string literal uses double quotes (" or """).
+   */
+  bool get isSingleQuoted;
+}
+
+/**
+ * A node that represents a statement.
+ *
+ * > statement ::=
+ * >     [Block]
+ * >   | [VariableDeclarationStatement]
+ * >   | [ForStatement]
+ * >   | [ForEachStatement]
+ * >   | [WhileStatement]
+ * >   | [DoStatement]
+ * >   | [SwitchStatement]
+ * >   | [IfStatement]
+ * >   | [TryStatement]
+ * >   | [BreakStatement]
+ * >   | [ContinueStatement]
+ * >   | [ReturnStatement]
+ * >   | [ExpressionStatement]
+ * >   | [FunctionDeclarationStatement]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class Statement extends AstNode {
+  /**
+   * If this is a labeled statement, return the unlabeled portion of the
+   * statement, otherwise return the statement itself.
+   */
+  Statement get unlabeled;
+}
+
+/**
+ * A string interpolation literal.
+ *
+ * > stringInterpolation ::=
+ * >     ''' [InterpolationElement]* '''
+ * >   | '"' [InterpolationElement]* '"'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class StringInterpolation extends SingleStringLiteral {
+  /**
+   * Initialize a newly created string interpolation expression.
+   */
+  factory StringInterpolation(List<InterpolationElement> elements) =
+      StringInterpolationImpl;
+
+  /**
+   * Return the elements that will be composed to produce the resulting string.
+   */
+  NodeList<InterpolationElement> get elements;
+}
+
+/**
+ * A string literal expression.
+ *
+ * > stringLiteral ::=
+ * >     [SimpleStringLiteral]
+ * >   | [AdjacentStrings]
+ * >   | [StringInterpolation]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class StringLiteral extends Literal {
+  /**
+   * Return the value of the string literal, or `null` if the string is not a
+   * constant string without any string interpolation.
+   */
+  String get stringValue;
+}
+
+/**
+ * The invocation of a superclass' constructor from within a constructor's
+ * initialization list.
+ *
+ * > superInvocation ::=
+ * >     'super' ('.' [SimpleIdentifier])? [ArgumentList]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SuperConstructorInvocation extends ConstructorInitializer {
+  /**
+   * Initialize a newly created super invocation to invoke the inherited
+   * constructor with the given name with the given arguments. The [period] and
+   * [constructorName] can be `null` if the constructor being invoked is the
+   * unnamed constructor.
+   */
+  factory SuperConstructorInvocation(
+      Token superKeyword,
+      Token period,
+      SimpleIdentifier constructorName,
+      ArgumentList argumentList) = SuperConstructorInvocationImpl;
+
+  /**
+   * Return the list of arguments to the constructor.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * Set the list of arguments to the constructor to the given [argumentList].
+   */
+  void set argumentList(ArgumentList argumentList);
+
+  /**
+   * Return the name of the constructor that is being invoked, or `null` if the
+   * unnamed constructor is being invoked.
+   */
+  SimpleIdentifier get constructorName;
+
+  /**
+   * Set the name of the constructor that is being invoked to the given
+   * [identifier].
+   */
+  void set constructorName(SimpleIdentifier identifier);
+
+  /**
+   * Return the token for the period before the name of the constructor that is
+   * being invoked, or `null` if the unnamed constructor is being invoked.
+   */
+  Token get period;
+
+  /**
+   * Set the token for the period before the name of the constructor that is
+   * being invoked to the given [token].
+   */
+  void set period(Token token);
+
+  /**
+   * Return the element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement get staticElement;
+
+  /**
+   * Set the element associated with the constructor based on static type
+   * information to the given [element].
+   */
+  void set staticElement(ConstructorElement element);
+
+  /**
+   * Return the token for the 'super' keyword.
+   */
+  Token get superKeyword;
+
+  /**
+   * Set the token for the 'super' keyword to the given [token].
+   */
+  void set superKeyword(Token token);
+}
+
+/**
+ * A super expression.
+ *
+ * > superExpression ::=
+ * >     'super'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SuperExpression extends Expression {
+  /**
+   * Initialize a newly created super expression.
+   */
+  factory SuperExpression(Token superKeyword) = SuperExpressionImpl;
+
+  /**
+   * Return the token representing the 'super' keyword.
+   */
+  Token get superKeyword;
+
+  /**
+   * Set the token representing the 'super' keyword to the given [token].
+   */
+  void set superKeyword(Token token);
+}
+
+/**
+ * A case in a switch statement.
+ *
+ * > switchCase ::=
+ * >     [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SwitchCase extends SwitchMember {
+  /**
+   * Initialize a newly created switch case. The list of [labels] can be `null`
+   * if there are no labels.
+   */
+  factory SwitchCase(List<Label> labels, Token keyword, Expression expression,
+      Token colon, List<Statement> statements) = SwitchCaseImpl;
+
+  /**
+   * Return the expression controlling whether the statements will be executed.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression controlling whether the statements will be executed to
+   * the given [expression].
+   */
+  void set expression(Expression expression);
+}
+
+/**
+ * The default case in a switch statement.
+ *
+ * > switchDefault ::=
+ * >     [SimpleIdentifier]* 'default' ':' [Statement]*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SwitchDefault extends SwitchMember {
+  /**
+   * Initialize a newly created switch default. The list of [labels] can be
+   * `null` if there are no labels.
+   */
+  factory SwitchDefault(List<Label> labels, Token keyword, Token colon,
+      List<Statement> statements) = SwitchDefaultImpl;
+}
+
+/**
+ * An element within a switch statement.
+ *
+ * > switchMember ::=
+ * >     switchCase
+ * >   | switchDefault
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SwitchMember extends AstNode {
+  /**
+   * Return the colon separating the keyword or the expression from the
+   * statements.
+   */
+  Token get colon;
+
+  /**
+   * Set the colon separating the keyword or the expression from the
+   * statements to the given [token].
+   */
+  void set colon(Token token);
+
+  /**
+   * Return the token representing the 'case' or 'default' keyword.
+   */
+  Token get keyword;
+
+  /**
+   * Set the token representing the 'case' or 'default' keyword to the given
+   * [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the labels associated with the switch member.
+   */
+  NodeList<Label> get labels;
+
+  /**
+   * Return the statements that will be executed if this switch member is
+   * selected.
+   */
+  NodeList<Statement> get statements;
+}
+
+/**
+ * A switch statement.
+ *
+ * > switchStatement ::=
+ * >     'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SwitchStatement extends Statement {
+  /**
+   * Initialize a newly created switch statement. The list of [members] can be
+   * `null` if there are no switch members.
+   */
+  factory SwitchStatement(
+      Token switchKeyword,
+      Token leftParenthesis,
+      Expression expression,
+      Token rightParenthesis,
+      Token leftBracket,
+      List<SwitchMember> members,
+      Token rightBracket) = SwitchStatementImpl;
+
+  /**
+   * Return the expression used to determine which of the switch members will be
+   * selected.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression used to determine which of the switch members will be
+   * selected to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the left curly bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left curly bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the switch members that can be selected by the expression.
+   */
+  NodeList<SwitchMember> get members;
+
+  /**
+   * Return the right curly bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right curly bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the token representing the 'switch' keyword.
+   */
+  Token get switchKeyword;
+
+  /**
+   * Set the token representing the 'switch' keyword to the given [token].
+   */
+  void set switchKeyword(Token token);
+}
+
+/**
+ * A symbol literal expression.
+ *
+ * > symbolLiteral ::=
+ * >     '#' (operator | (identifier ('.' identifier)*))
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class SymbolLiteral extends Literal {
+  /**
+   * Initialize a newly created symbol literal.
+   */
+  factory SymbolLiteral(Token poundSign, List<Token> components) =
+      SymbolLiteralImpl;
+
+  /**
+   * Return the components of the literal.
+   */
+  List<Token> get components;
+
+  /**
+   * Return the token introducing the literal.
+   */
+  Token get poundSign;
+
+  /**
+   * Set the token introducing the literal to the given [token].
+   */
+  void set poundSign(Token token);
+}
+
+/**
+ * A this expression.
+ *
+ * > thisExpression ::=
+ * >     'this'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ThisExpression extends Expression {
+  /**
+   * Initialize a newly created this expression.
+   */
+  factory ThisExpression(Token thisKeyword) = ThisExpressionImpl;
+
+  /**
+   * Return the token representing the 'this' keyword.
+   */
+  Token get thisKeyword;
+
+  /**
+   * Set the token representing the 'this' keyword to the given [token].
+   */
+  void set thisKeyword(Token token);
+}
+
+/**
+ * A throw expression.
+ *
+ * > throwExpression ::=
+ * >     'throw' [Expression]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ThrowExpression extends Expression {
+  /**
+   * Initialize a newly created throw expression.
+   */
+  factory ThrowExpression(Token throwKeyword, Expression expression) =
+      ThrowExpressionImpl;
+
+  /**
+   * Return the expression computing the exception to be thrown.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression computing the exception to be thrown to the given
+   * [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the token representing the 'throw' keyword.
+   */
+  Token get throwKeyword;
+
+  /**
+   * Set the token representing the 'throw' keyword to the given [token].
+   */
+  void set throwKeyword(Token token);
+}
+
+/**
+ * The declaration of one or more top-level variables of the same type.
+ *
+ * > topLevelVariableDeclaration ::=
+ * >     ('final' | 'const') type? staticFinalDeclarationList ';'
+ * >   | variableDeclaration ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TopLevelVariableDeclaration extends CompilationUnitMember {
+  /**
+   * Initialize a newly created top-level variable declaration. Either or both
+   * of the [comment] and [metadata] can be `null` if the variable does not have
+   * the corresponding attribute.
+   */
+  factory TopLevelVariableDeclaration(
+      Comment comment,
+      List<Annotation> metadata,
+      VariableDeclarationList variableList,
+      Token semicolon) = TopLevelVariableDeclarationImpl;
+
+  /**
+   * Return the semicolon terminating the declaration.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the declaration to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the top-level variables being declared.
+   */
+  VariableDeclarationList get variables;
+
+  /**
+   * Set the top-level variables being declared to the given list of
+   * [variables].
+   */
+  void set variables(VariableDeclarationList variables);
+}
+
+/**
+ * A try statement.
+ *
+ * > tryStatement ::=
+ * >     'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
+ * >
+ * > finallyClause ::=
+ * >     'finally' [Block]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TryStatement extends Statement {
+  /**
+   * Initialize a newly created try statement. The list of [catchClauses] can be
+   * `null` if there are no catch clauses. The [finallyKeyword] and
+   * [finallyBlock] can be `null` if there is no finally clause.
+   */
+  factory TryStatement(
+      Token tryKeyword,
+      Block body,
+      List<CatchClause> catchClauses,
+      Token finallyKeyword,
+      Block finallyBlock) = TryStatementImpl;
+
+  /**
+   * Return the body of the statement.
+   */
+  Block get body;
+
+  /**
+   * Set the body of the statement to the given [block].
+   */
+  void set body(Block block);
+
+  /**
+   * Return the catch clauses contained in the try statement.
+   */
+  NodeList<CatchClause> get catchClauses;
+
+  /**
+   * Return the finally block contained in the try statement, or `null` if the
+   * statement does not contain a finally clause.
+   */
+  Block get finallyBlock;
+
+  /**
+   * Set the finally block contained in the try statement to the given [block].
+   */
+  void set finallyBlock(Block block);
+
+  /**
+   * Return the token representing the 'finally' keyword, or `null` if the
+   * statement does not contain a finally clause.
+   */
+  Token get finallyKeyword;
+
+  /**
+   * Set the token representing the 'finally' keyword to the given [token].
+   */
+  void set finallyKeyword(Token token);
+
+  /**
+   * Return the token representing the 'try' keyword.
+   */
+  Token get tryKeyword;
+
+  /**
+   * Set the token representing the 'try' keyword to the given [token].
+   */
+  void set tryKeyword(Token token);
+}
+
+/**
+ * The declaration of a type alias.
+ *
+ * > typeAlias ::=
+ * >     'typedef' typeAliasBody
+ * >
+ * > typeAliasBody ::=
+ * >     classTypeAlias
+ * >   | functionTypeAlias
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeAlias extends NamedCompilationUnitMember {
+  /**
+   * Return the semicolon terminating the declaration.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the declaration to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the token representing the 'typedef' keyword.
+   */
+  Token get typedefKeyword;
+
+  /**
+   * Set the token representing the 'typedef' keyword to the given [token].
+   */
+  void set typedefKeyword(Token token);
+}
+
+/**
+ * A list of type arguments.
+ *
+ * > typeArguments ::=
+ * >     '<' typeName (',' typeName)* '>'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeArgumentList extends AstNode {
+  /**
+   * Initialize a newly created list of type arguments.
+   */
+  factory TypeArgumentList(
+          Token leftBracket, List<TypeName> arguments, Token rightBracket) =
+      TypeArgumentListImpl;
+
+  /**
+   * Return the type arguments associated with the type.
+   */
+  NodeList<TypeName> get arguments;
+
+  /**
+   * Return the left bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Set the left bracket to the given [token].
+   */
+  void set leftBracket(Token token);
+
+  /**
+   * Return the right bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Set the right bracket to the given [token].
+   */
+  void set rightBracket(Token token);
+}
+
+/**
+ * A literal that has a type associated with it.
+ *
+ * > typedLiteral ::=
+ * >     [ListLiteral]
+ * >   | [MapLiteral]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypedLiteral extends Literal {
+  /**
+   * Return the token representing the 'const' keyword, or `null` if the literal
+   * is not a constant.
+   */
+  Token get constKeyword;
+
+  /**
+   * Set the token representing the 'const' keyword to the given [token].
+   */
+  void set constKeyword(Token token);
+
+  /**
+   * Return the type argument associated with this literal, or `null` if no type
+   * arguments were declared.
+   */
+  TypeArgumentList get typeArguments;
+
+  /**
+   * Set the type argument associated with this literal to the given
+   * [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments);
+}
+
+/**
+ * The name of a type, which can optionally include type arguments.
+ *
+ * > typeName ::=
+ * >     [Identifier] typeArguments?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeName extends AstNode {
+  /**
+   * Initialize a newly created type name. The [typeArguments] can be `null` if
+   * there are no type arguments.
+   */
+  factory TypeName(Identifier name, TypeArgumentList typeArguments) =
+      TypeNameImpl;
+
+  /**
+   * Return `true` if this type is a deferred type.
+   *
+   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
+   * </i>p.T</i> where <i>p</i> is a deferred prefix.
+   */
+  bool get isDeferred;
+
+  /**
+   * Return the name of the type.
+   */
+  Identifier get name;
+
+  /**
+   * Set the name of the type to the given [identifier].
+   */
+  void set name(Identifier identifier);
+
+  /**
+   * Return the type being named, or `null` if the AST structure has not been
+   * resolved.
+   */
+  DartType get type;
+
+  /**
+   * Set the type being named to the given [type].
+   */
+  void set type(DartType type);
+
+  /**
+   * Return the type arguments associated with the type, or `null` if there are
+   * no type arguments.
+   */
+  TypeArgumentList get typeArguments;
+
+  /**
+   * Set the type arguments associated with the type to the given
+   * [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments);
+}
+
+/**
+ * A type parameter.
+ *
+ * > typeParameter ::=
+ * >     [SimpleIdentifier] ('extends' [TypeName])?
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameter extends Declaration {
+  /**
+   * Initialize a newly created type parameter. Either or both of the [comment]
+   * and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
+   * the parameter does not have an upper bound.
+   */
+  factory TypeParameter(
+      Comment comment,
+      List<Annotation> metadata,
+      SimpleIdentifier name,
+      Token extendsKeyword,
+      TypeName bound) = TypeParameterImpl;
+
+  /**
+   * Return the name of the upper bound for legal arguments, or `null` if there
+   * is no explicit upper bound.
+   */
+  TypeName get bound;
+
+  /**
+   * Set the name of the upper bound for legal arguments to the given
+   * [typeName].
+   */
+  void set bound(TypeName typeName);
+
+  /**
+   * Return the token representing the 'extends' keyword, or `null` if there is
+   * no explicit upper bound.
+   */
+  Token get extendsKeyword;
+
+  /**
+   * Set the token representing the 'extends' keyword to the given [token].
+   */
+  void set extendsKeyword(Token token);
+
+  /**
+   * Return the name of the type parameter.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the type parameter to the given [identifier].
+   */
+  void set name(SimpleIdentifier identifier);
+}
+
+/**
+ * Type parameters within a declaration.
+ *
+ * > typeParameterList ::=
+ * >     '<' [TypeParameter] (',' [TypeParameter])* '>'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class TypeParameterList extends AstNode {
+  /**
+   * Initialize a newly created list of type parameters.
+   */
+  factory TypeParameterList(
+      Token leftBracket,
+      List<TypeParameter> typeParameters,
+      Token rightBracket) = TypeParameterListImpl;
+
+  /**
+   * Return the left angle bracket.
+   */
+  Token get leftBracket;
+
+  /**
+   * Return the right angle bracket.
+   */
+  Token get rightBracket;
+
+  /**
+   * Return the type parameters for the type.
+   */
+  NodeList<TypeParameter> get typeParameters;
+}
+
+/**
+ * A directive that references a URI.
+ *
+ * > uriBasedDirective ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ * >   | [PartDirective]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UriBasedDirective extends Directive {
+  /**
+   * Return the source to which the URI was resolved.
+   */
+  Source get source;
+
+  /**
+   * Set the source to which the URI was resolved to the given [source].
+   */
+  void set source(Source source);
+
+  /**
+   * Return the URI referenced by this directive.
+   */
+  StringLiteral get uri;
+
+  /**
+   * Set the URI referenced by this directive to the given [uri].
+   */
+  void set uri(StringLiteral uri);
+
+  /**
+   * Return the content of the URI.
+   */
+  String get uriContent;
+
+  /**
+   * Set the content of the URI to the given [content].
+   */
+  void set uriContent(String content);
+
+  /**
+   * Return the element associated with the URI of this directive, or `null` if
+   * the AST structure has not been resolved or if the URI could not be
+   * resolved. Examples of the latter case include a directive that contains an
+   * invalid URL or a URL that does not exist.
+   */
+  Element get uriElement;
+
+  /**
+   * Validate this directive, but do not check for existence. Return a code
+   * indicating the problem if there is one, or `null` no problem
+   */
+  UriValidationCode validate();
+}
+
+/**
+ * Validation codes returned by [UriBasedDirective.validate].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class UriValidationCode {
+  static const UriValidationCode INVALID_URI =
+      UriValidationCodeImpl.INVALID_URI;
+
+  static const UriValidationCode URI_WITH_INTERPOLATION =
+      UriValidationCodeImpl.URI_WITH_INTERPOLATION;
+
+  static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
+      UriValidationCodeImpl.URI_WITH_DART_EXT_SCHEME;
+}
+
+/**
+ * An identifier that has an initial value associated with it. Instances of this
+ * class are always children of the class [VariableDeclarationList].
+ *
+ * > variableDeclaration ::=
+ * >     [SimpleIdentifier] ('=' [Expression])?
+ *
+ * TODO(paulberry): the grammar does not allow metadata to be associated with
+ * a VariableDeclaration, and currently we don't record comments for it either.
+ * Consider changing the class hierarchy so that [VariableDeclaration] does not
+ * extend [Declaration].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class VariableDeclaration extends Declaration {
+  /**
+   * Initialize a newly created variable declaration. The [equals] and
+   * [initializer] can be `null` if there is no initializer.
+   */
+  factory VariableDeclaration(
+          SimpleIdentifier name, Token equals, Expression initializer) =
+      VariableDeclarationImpl;
+
+  @override
+  VariableElement get element;
+
+  /**
+   * Return the equal sign separating the variable name from the initial value,
+   * or `null` if the initial value was not specified.
+   */
+  Token get equals;
+
+  /**
+   * Set the equal sign separating the variable name from the initial value to
+   * the given [token].
+   */
+  void set equals(Token token);
+
+  /**
+   * Return the expression used to compute the initial value for the variable,
+   * or `null` if the initial value was not specified.
+   */
+  Expression get initializer;
+
+  /**
+   * Set the expression used to compute the initial value for the variable to
+   * the given [expression].
+   */
+  void set initializer(Expression expression);
+
+  /**
+   * 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 the name of the variable being declared.
+   */
+  SimpleIdentifier get name;
+
+  /**
+   * Set the name of the variable being declared to the given [identifier].
+   */
+  void set name(SimpleIdentifier identifier);
+}
+
+/**
+ * The declaration of one or more variables of the same type.
+ *
+ * > variableDeclarationList ::=
+ * >     finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
+ * >
+ * > finalConstVarOrType ::=
+ * >   | 'final' [TypeName]?
+ * >   | 'const' [TypeName]?
+ * >   | 'var'
+ * >   | [TypeName]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class VariableDeclarationList extends AnnotatedNode {
+  /**
+   * Initialize a newly created variable declaration list. Either or both of the
+   * [comment] and [metadata] can be `null` if the variable list does not have
+   * the corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  factory VariableDeclarationList(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName type,
+      List<VariableDeclaration> variables) = VariableDeclarationListImpl;
+
+  /**
+   * Return `true` if the variables in this list were declared with the 'const'
+   * modifier.
+   */
+  bool get isConst;
+
+  /**
+   * Return `true` if the variables in this list were declared with the 'final'
+   * modifier. Variables that are declared with the 'const' modifier will return
+   * `false` even though they are implicitly final. (In other words, this is a
+   * syntactic check rather than a semantic check.)
+   */
+  bool get isFinal;
+
+  /**
+   * Return the token representing the 'final', 'const' or 'var' keyword, or
+   * `null` if no keyword was included.
+   */
+  Token get keyword;
+
+  /**
+   * Set the token representing the 'final', 'const' or 'var' keyword to the
+   * given [token].
+   */
+  void set keyword(Token token);
+
+  /**
+   * Return the type of the variables being declared, or `null` if no type was
+   * provided.
+   */
+  TypeName get type;
+
+  /**
+   * Set the type of the variables being declared to the given [typeName].
+   */
+  void set type(TypeName typeName);
+
+  /**
+   * Return a list containing the individual variables being declared.
+   */
+  NodeList<VariableDeclaration> get variables;
+}
+
+/**
+ * A list of variables that are being declared in a context where a statement is
+ * required.
+ *
+ * > variableDeclarationStatement ::=
+ * >     [VariableDeclarationList] ';'
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class VariableDeclarationStatement extends Statement {
+  /**
+   * Initialize a newly created variable declaration statement.
+   */
+  factory VariableDeclarationStatement(
+          VariableDeclarationList variableList, Token semicolon) =
+      VariableDeclarationStatementImpl;
+
+  /**
+   * Return the semicolon terminating the statement.
+   */
+  Token get semicolon;
+
+  /**
+   * Set the semicolon terminating the statement to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the variables being declared.
+   */
+  VariableDeclarationList get variables;
+
+  /**
+   * Set the variables being declared to the given list of [variables].
+   */
+  void set variables(VariableDeclarationList variables);
+}
+
+/**
+ * A while statement.
+ *
+ * > whileStatement ::=
+ * >     'while' '(' [Expression] ')' [Statement]
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class WhileStatement extends Statement {
+  /**
+   * Initialize a newly created while statement.
+   */
+  factory WhileStatement(
+      Token whileKeyword,
+      Token leftParenthesis,
+      Expression condition,
+      Token rightParenthesis,
+      Statement body) = WhileStatementImpl;
+
+  /**
+   * Return the body of the loop.
+   */
+  Statement get body;
+
+  /**
+   * Set the body of the loop to the given [statement].
+   */
+  void set body(Statement statement);
+
+  /**
+   * Return the expression used to determine whether to execute the body of the
+   * loop.
+   */
+  Expression get condition;
+
+  /**
+   * Set the expression used to determine whether to execute the body of the
+   * loop to the given [expression].
+   */
+  void set condition(Expression expression);
+
+  /**
+   * Return the left parenthesis.
+   */
+  Token get leftParenthesis;
+
+  /**
+   * Set the left parenthesis to the given [token].
+   */
+  void set leftParenthesis(Token token);
+
+  /**
+   * Return the right parenthesis.
+   */
+  Token get rightParenthesis;
+
+  /**
+   * Set the right parenthesis to the given [token].
+   */
+  void set rightParenthesis(Token token);
+
+  /**
+   * Return the token representing the 'while' keyword.
+   */
+  Token get whileKeyword;
+
+  /**
+   * Set the token representing the 'while' keyword to the given [token].
+   */
+  void set whileKeyword(Token token);
+}
+
+/**
+ * The with clause in a class declaration.
+ *
+ * > withClause ::=
+ * >     'with' [TypeName] (',' [TypeName])*
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class WithClause extends AstNode {
+  /**
+   * Initialize a newly created with clause.
+   */
+  factory WithClause(Token withKeyword, List<TypeName> mixinTypes) =
+      WithClauseImpl;
+
+  /**
+   * Return the names of the mixins that were specified.
+   */
+  NodeList<TypeName> get mixinTypes;
+
+  /**
+   * Return the token representing the 'with' keyword.
+   */
+  Token get withKeyword;
+
+  /**
+   * Set the token representing the 'with' keyword to the given [token].
+   */
+  void set withKeyword(Token token);
+}
+
+/**
+ * A yield statement.
+ *
+ * > yieldStatement ::=
+ * >     'yield' '*'? [Expression] ‘;’
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class YieldStatement extends Statement {
+  /**
+   * Initialize a newly created yield expression. The [star] can be `null` if no
+   * star was provided.
+   */
+  factory YieldStatement(Token yieldKeyword, Token star, Expression expression,
+      Token semicolon) = YieldStatementImpl;
+
+  /**
+   * Return the expression whose value will be yielded.
+   */
+  Expression get expression;
+
+  /**
+   * Set the expression whose value will be yielded to the given [expression].
+   */
+  void set expression(Expression expression);
+
+  /**
+   * Return the semicolon following the expression.
+   */
+  Token get semicolon;
+
+  /**
+   * Return the semicolon following the expression to the given [token].
+   */
+  void set semicolon(Token token);
+
+  /**
+   * Return the star optionally following the 'yield' keyword.
+   */
+  Token get star;
+
+  /**
+   * Return the star optionally following the 'yield' keyword to the given [token].
+   */
+  void set star(Token token);
+
+  /**
+   * Return the 'yield' keyword.
+   */
+  Token get yieldKeyword;
+
+  /**
+   * Return the 'yield' keyword to the given [token].
+   */
+  void set yieldKeyword(Token token);
+}
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index c9b345a..7e2848e 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -6,7 +6,7 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 
 /**
  * An AST visitor that will recursively visit all of the nodes in an AST
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index ab468ed..bb52303d 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -4,8 +4,8 @@
 
 library analyzer.dart.element.element;
 
+import 'package:analyzer/dart/ast/ast.dart';
 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';
@@ -1347,6 +1347,11 @@
   bool get isBrowserApplication;
 
   /**
+   * Return `true` if this library is the dart:async library.
+   */
+  bool get isDartAsync;
+
+  /**
    * Return `true` if this library is the dart:core library.
    */
   bool get isDartCore;
@@ -1470,154 +1475,6 @@
 }
 
 /**
- * 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
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 548dc1d..5b92819 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
+import 'package:analyzer/src/generated/type_system.dart' show TypeSystem;
 
 /**
  * The type associated with elements in the element model.
@@ -38,6 +39,12 @@
   bool get isBottom;
 
   /**
+   * Return `true` if this type represents the type 'Future' defined in the
+   * dart:async library.
+   */
+  bool get isDartAsyncFuture;
+
+  /**
    * Return `true` if this type represents the type 'Function' defined in the
    * dart:core library.
    */
@@ -70,6 +77,19 @@
   String get name;
 
   /**
+   * Implements the function "flatten" defined in the spec, where T is this
+   * type:
+   *
+   *     If T = Future<S> then flatten(T) = flatten(S).
+   *
+   *     Otherwise if T <: Future then let S be a type such that T << Future<S>
+   *     and for all R, if T << Future<R> then S << R.  Then flatten(T) = S.
+   *
+   *     In any other circumstance, flatten(T) = T.
+   */
+  DartType flattenFutures(TypeSystem typeSystem);
+
+  /**
    * 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>.
@@ -137,16 +157,6 @@
   List<TypeParameterElement> get boundTypeParameters;
 
   /**
-   * The formal 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 typeFormals;
-
-  /**
    * 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
@@ -184,6 +194,16 @@
   DartType get returnType;
 
   /**
+   * The formal 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 typeFormals;
+
+  /**
    * Return the type resulting from instantiating (replacing) the given
    * [argumentTypes] for this function's bound type parameters.
    */
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index c82e4f3..f77ff7c 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -8,12 +8,18 @@
 import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
-import 'package:path/path.dart' as pathos;
 import 'package:yaml/yaml.dart';
 
+const String _DART_COLON_PREFIX = 'dart:';
+
 /// Given a packageMap, check in each package's lib directory for the
 /// existence of an `_embedder.yaml` file. If the file contains a top level
 /// YamlMap, it will be added to the [embedderYamls] map.
@@ -79,7 +85,6 @@
     embedderYamls[libDir] = yaml;
   }
 
-
   /// Read the contents of [libDir]/[EMBEDDER_FILE_NAME] as a string.
   /// Returns null if the file doesn't exist.
   String _readEmbedderYaml(Folder libDir) {
@@ -104,14 +109,14 @@
 ///
 /// If a key doesn't begin with `dart:` it is ignored.
 ///
-class EmbedderUriResolver extends UriResolver {
-  static const String DART_COLON_PREFIX = 'dart:';
-
+class EmbedderUriResolver extends DartUriResolver {
   final Map<String, String> _urlMappings = <String, String>{};
 
   /// Construct a [EmbedderUriResolver] from a package map
   /// (see [PackageMapProvider]).
-  EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls) {
+  EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls)
+      : super(new EmbedderSdk()) {
+    (dartSdk as EmbedderSdk)._resolver = this;
     if (embedderYamls == null) {
       return;
     }
@@ -126,108 +131,159 @@
     if (embedder_libs is! YamlMap) {
       return;
     }
-    (embedder_libs as YamlMap).forEach((k, v) =>
-        _processEmbedderLibs(k, v, libDir));
+    (embedder_libs as YamlMap)
+        .forEach((k, v) => _processEmbedderLibs(k, v, libDir));
   }
 
   /// Install the mapping from [name] to [libDir]/[file].
   void _processEmbedderLibs(String name, String file, Folder libDir) {
-    if (!name.startsWith(DART_COLON_PREFIX)) {
+    if (!name.startsWith(_DART_COLON_PREFIX)) {
       // SDK libraries must begin with 'dart:'.
       // TODO(pquitslund): Notify developer that something is wrong with the
       // _embedder.yaml file in libDir.
       return;
     }
-    String key = name;
-    String value = libDir.canonicalizePath(file);
-    _urlMappings[key] = value;
+    String libPath = libDir.canonicalizePath(file);
+    _urlMappings[name] = libPath;
+    String shortName = name.substring(_DART_COLON_PREFIX.length);
+    SdkLibraryImpl library = new SdkLibraryImpl(shortName);
+    library.path = libPath;
+    (dartSdk as EmbedderSdk)._librariesMap.setLibrary(name, library);
   }
 
   /// Number of embedder libraries.
   int get length => _urlMappings.length;
 
-  /// Return the path mapping for [libName] or null if there is none.
-  String operator [](String libName) => _urlMappings[libName];
-
-  @override
-  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
-    String libraryName = _libraryName(importUri);
-    String partPath = _partPath(importUri);
-    // Lookup library name in mappings.
-    String mapping = _urlMappings[libraryName];
-    if (mapping == null) {
-      // Not found.
-      return null;
-    }
-    // This mapping points to the main entry file of the dart: library.
-    Uri libraryEntry = new Uri.file(mapping);
-    if (!libraryEntry.isAbsolute) {
-      // We expect an absolute path.
-      return null;
-    }
-
-    if (partPath != null) {
-      return _resolvePart(libraryEntry, partPath, importUri);
-    } else {
-      return _resolveEntry(libraryEntry, importUri);
-    }
-  }
-
   @override
   Uri restoreAbsolute(Source source) {
-    String extensionName = _findExtensionNameFor(source.fullName);
-    if (extensionName != null) {
-      return Uri.parse(extensionName);
-    }
-    // TODO(johnmccutchan): Handle restoring parts.
-    return null;
+    Source sdkSource = dartSdk.fromFileUri(Uri.parse(source.fullName));
+    return sdkSource?.uri;
   }
+}
 
-  /// Return the extension name for [fullName] or `null`.
-  String _findExtensionNameFor(String fullName) {
-    String result;
-    _urlMappings.forEach((extensionName, pathMapping) {
-      if (pathMapping == fullName) {
-        result = extensionName;
+class EmbedderSdk implements DartSdk {
+  // TODO(danrubel) Refactor this with DirectoryBasedDartSdk
+
+  /// The resolver associated with this embedder sdk.
+  EmbedderUriResolver _resolver;
+
+  /// The [AnalysisContext] which is used for all of the sources in this sdk.
+  InternalAnalysisContext _analysisContext;
+
+  /// The library map that is populated by visiting the AST structure parsed from
+  /// the contents of the libraries file.
+  final LibraryMap _librariesMap = new LibraryMap();
+
+  @override
+  AnalysisContext get context {
+    if (_analysisContext == null) {
+      _analysisContext = new SdkAnalysisContext();
+      SourceFactory factory = new SourceFactory([_resolver]);
+      _analysisContext.sourceFactory = factory;
+      List<String> uris = this.uris;
+      ChangeSet changeSet = new ChangeSet();
+      for (String uri in uris) {
+        changeSet.addedSource(factory.forUri(uri));
       }
-    });
-    return result;
-  }
-
-  /// Return the library name of [importUri].
-  String _libraryName(Uri importUri) {
-    String uri = importUri.toString();
-    int index = uri.indexOf('/');
-    if (index >= 0) {
-      return uri.substring(0, index);
+      _analysisContext.applyChanges(changeSet);
     }
-    return uri;
+    return _analysisContext;
   }
 
-  /// Return the part path of [importUri].
-  String _partPath(Uri importUri) {
-    String uri = importUri.toString();
-    int index = uri.indexOf('/');
-    if (index >= 0) {
-      return uri.substring(index + 1);
+  @override
+  List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries;
+
+  // TODO(danrubel) Determine SDK version
+  @override
+  String get sdkVersion => '0';
+
+  @override
+  List<String> get uris => _librariesMap.uris;
+
+  @override
+  Source fromFileUri(Uri uri) {
+    JavaFile file = new JavaFile.fromUri(uri);
+    String filePath = file.getAbsolutePath();
+
+    String path;
+    for (SdkLibrary library in _librariesMap.sdkLibraries) {
+      String libraryPath = library.path.replaceAll('/', JavaFile.separator);
+      if (filePath == libraryPath) {
+        path = '$_DART_COLON_PREFIX${library.shortName}';
+        break;
+      }
+    }
+    if (path == null) {
+      for (SdkLibrary library in _librariesMap.sdkLibraries) {
+        String libraryPath = library.path.replaceAll('/', JavaFile.separator);
+        int index = libraryPath.lastIndexOf(JavaFile.separator);
+        if (index == -1) {
+          continue;
+        }
+        String prefix = libraryPath.substring(0, index + 1);
+        if (!filePath.startsWith(prefix)) {
+          continue;
+        }
+        var relPath = filePath
+            .substring(prefix.length).replaceAll(JavaFile.separator, '/');
+        path = '$_DART_COLON_PREFIX${library.shortName}/$relPath';
+        break;
+      }
+    }
+
+    if (path != null) {
+      try {
+        return new FileBasedSource(file, parseUriWithException(path));
+      } on URISyntaxException catch (exception, stackTrace) {
+        AnalysisEngine.instance.logger.logInformation(
+            "Failed to create URI: $path",
+            new CaughtException(exception, stackTrace));
+        return null;
+      }
     }
     return null;
   }
 
-  /// Resolve an import of an sdk extension.
-  Source _resolveEntry(Uri libraryEntry, Uri importUri) {
-    // Library entry.
-    JavaFile javaFile = new JavaFile.fromUri(libraryEntry);
-    return new FileBasedSource(javaFile, importUri);
-  }
+  @override
+  SdkLibrary getSdkLibrary(String dartUri) => _librariesMap.getLibrary(dartUri);
 
-  /// Resolve a 'part' statement inside an sdk extension.
-  Source _resolvePart(Uri libraryEntry, String partPath, Uri importUri) {
-    // Library part.
-    String directory = pathos.dirname(libraryEntry.path);
-    Uri partUri = new Uri.file(pathos.join(directory, partPath));
-    assert(partUri.isAbsolute);
-    JavaFile javaFile = new JavaFile.fromUri(partUri);
-    return new FileBasedSource(javaFile, importUri);
+  @override
+  Source mapDartUri(String dartUri) {
+    String libraryName;
+    String relativePath;
+    int index = dartUri.indexOf('/');
+    if (index >= 0) {
+      libraryName = dartUri.substring(0, index);
+      relativePath = dartUri.substring(index + 1);
+    } else {
+      libraryName = dartUri;
+      relativePath = "";
+    }
+    SdkLibrary library = getSdkLibrary(libraryName);
+    if (library == null) {
+      return null;
+    }
+    String srcPath;
+    if (relativePath.isEmpty) {
+      srcPath = library.path;
+    } else {
+      String libraryPath = library.path;
+      int index = libraryPath.lastIndexOf(JavaFile.separator);
+      if (index == -1) {
+        index = libraryPath.lastIndexOf('/');
+        if (index == -1) {
+          return null;
+        }
+      }
+      String prefix = libraryPath.substring(0, index + 1);
+      srcPath = '$prefix$relativePath';
+    }
+    String filePath = srcPath.replaceAll('/', JavaFile.separator);
+    try {
+      JavaFile file = new JavaFile(filePath);
+      return new FileBasedSource(file, parseUriWithException(dartUri));
+    } on URISyntaxException {
+      return null;
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 4714557..09c35ac 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -7,14 +7,16 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/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/dart/element/type.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -24,6 +26,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/dart_work_manager.dart';
@@ -185,6 +188,9 @@
    */
   List<AnalysisListener> _listeners = new List<AnalysisListener>();
 
+  @override
+  ResultProvider resultProvider;
+
   /**
    * The most recently incrementally resolved source, or `null` when it was
    * already validated, or the most recent change was not incrementally resolved.
@@ -459,13 +465,19 @@
     if (coreElement == null) {
       throw new AnalysisException("Could not create an element for dart:core");
     }
-    Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
-    if (asyncSource == null) {
-      throw new AnalysisException("Could not create a source for dart:async");
-    }
-    LibraryElement asyncElement = computeLibraryElement(asyncSource);
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not create an element for dart:async");
+    LibraryElement asyncElement;
+    if (analysisOptions.enableAsync) {
+      Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+      if (asyncSource == null) {
+        throw new AnalysisException("Could not create a source for dart:async");
+      }
+      asyncElement = computeLibraryElement(asyncSource);
+      if (asyncElement == null) {
+        throw new AnalysisException(
+            "Could not create an element for dart:async");
+      }
+    } else {
+      asyncElement = createMockAsyncLib(coreElement);
     }
     _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
     return _typeProvider;
@@ -489,26 +501,20 @@
   @override
   bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
     return PerformanceStatistics.summary.makeCurrentWhile(() {
-      AnalysisTarget target = entry.target;
-      // TYPE_PROVIDER
-      if (target is AnalysisContextTarget && result == TYPE_PROVIDER) {
-        DartSdk dartSdk = sourceFactory.dartSdk;
-        if (dartSdk != null) {
-          AnalysisContext sdkContext = dartSdk.context;
-          if (!identical(sdkContext, this) &&
-              sdkContext is InternalAnalysisContext) {
-            return sdkContext.aboutToComputeResult(entry, result);
-          }
+      // Use this helper if it is set.
+      if (resultProvider != null && resultProvider.compute(entry, result)) {
+        return true;
+      }
+      // Ask the SDK.
+      DartSdk dartSdk = sourceFactory.dartSdk;
+      if (dartSdk != null) {
+        AnalysisContext sdkContext = dartSdk.context;
+        if (!identical(sdkContext, this) &&
+            sdkContext is InternalAnalysisContext) {
+          return sdkContext.aboutToComputeResult(entry, result);
         }
       }
-      // A result for a Source.
-      Source source = target.source;
-      if (source != null) {
-        InternalAnalysisContext context = _cache.getContextFor(source);
-        if (!identical(context, this)) {
-          return context.aboutToComputeResult(entry, result);
-        }
-      }
+      // Cannot provide the result.
       return false;
     });
   }
@@ -640,8 +646,8 @@
   }
 
   @override
-  Object /*=V*/ computeResult /*<V>*/ (
-      AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
+  Object/*=V*/ computeResult/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ descriptor) {
     // Make sure we are not trying to invoke the task model in a reentrant
     // fashion.
     assert(!driver.isTaskRunning);
@@ -675,6 +681,54 @@
     ]);
   }
 
+  /**
+   * Create a minimalistic mock dart:async library
+   * to stand in for a real one if one does not exist
+   * facilitating creation a type provider without dart:async.
+   */
+  LibraryElement createMockAsyncLib(LibraryElement coreLibrary) {
+    InterfaceType objType = coreLibrary.getType('Object').type;
+
+    ClassElement _classElement(String typeName, [List<String> parameterNames]) {
+      ClassElementImpl element =
+          new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
+      element.supertype = objType;
+      InterfaceTypeImpl type = new InterfaceTypeImpl(element);
+      element.type = type;
+      if (parameterNames != null) {
+        int count = parameterNames.length;
+        if (count > 0) {
+          List<TypeParameterElementImpl> typeParameters =
+              new List<TypeParameterElementImpl>(count);
+          List<TypeParameterTypeImpl> typeArguments =
+              new List<TypeParameterTypeImpl>(count);
+          for (int i = 0; i < count; i++) {
+            TypeParameterElementImpl typeParameter =
+                new TypeParameterElementImpl.forNode(
+                    AstFactory.identifier3(parameterNames[i]));
+            typeParameters[i] = typeParameter;
+            typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
+            typeParameter.type = typeArguments[i];
+          }
+          element.typeParameters = typeParameters;
+          type.typeArguments = typeArguments;
+        }
+      }
+      return element;
+    }
+
+    InterfaceType futureType = _classElement('Future', ['T']).type;
+    InterfaceType streamType = _classElement('Stream', ['T']).type;
+    CompilationUnitElementImpl asyncUnit =
+        new CompilationUnitElementImpl("mock_async.dart");
+    asyncUnit.types = <ClassElement>[futureType.element, streamType.element];
+    LibraryElementImpl mockLib = new LibraryElementImpl.forNode(
+        this, AstFactory.libraryIdentifier2(["dart.async"]));
+    mockLib.definingCompilationUnit = asyncUnit;
+    mockLib.publicNamespace = new PublicNamespaceBuilder().build(mockLib);
+    return mockLib;
+  }
+
   @override
   void dispose() {
     _disposed = true;
@@ -2023,6 +2077,24 @@
 }
 
 /**
+ * Provider for analysis results.
+ */
+abstract class ResultProvider {
+  /**
+   * This method is invoked by an [InternalAnalysisContext] when the state of
+   * the [result] of the [entry] is [CacheState.INVALID], so it is about to be
+   * computed.
+   *
+   * If the provider knows how to provide the value, it sets the value into
+   * the [entry] with all required dependencies, and returns `true`.
+   *
+   * Otherwise, it returns `false` to indicate that the result should be
+   * computed as usually.
+   */
+  bool compute(CacheEntry entry, ResultDescriptor result);
+}
+
+/**
  * An [AnalysisContext] that only contains sources for a Dart SDK.
  */
 class SdkAnalysisContext extends AnalysisContextImpl {
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
new file mode 100644
index 0000000..26e3b76
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -0,0 +1,10805 @@
+// 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.ast.ast;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/utilities.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';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * Two or more string literals that are implicitly concatenated because of being
+ * adjacent (separated only by whitespace).
+ *
+ * While the grammar only allows adjacent strings when all of the strings are of
+ * the same kind (single line or multi-line), this class doesn't enforce that
+ * restriction.
+ *
+ * > adjacentStrings ::=
+ * >     [StringLiteral] [StringLiteral]+
+ */
+class AdjacentStringsImpl extends StringLiteralImpl implements AdjacentStrings {
+  /**
+   * The strings that are implicitly concatenated.
+   */
+  NodeList<StringLiteral> _strings;
+
+  /**
+   * Initialize a newly created list of adjacent strings. To be syntactically
+   * valid, the list of [strings] must contain at least two elements.
+   */
+  AdjacentStringsImpl(List<StringLiteral> strings) {
+    _strings = new NodeList<StringLiteral>(this, strings);
+  }
+
+  @override
+  Token get beginToken => _strings.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..addAll(_strings);
+
+  @override
+  Token get endToken => _strings.endToken;
+
+  @override
+  NodeList<StringLiteral> get strings => _strings;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAdjacentStrings(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _strings.accept(visitor);
+  }
+
+  @override
+  void _appendStringValue(StringBuffer buffer) {
+    for (StringLiteralImpl stringLiteral in strings) {
+      stringLiteral._appendStringValue(buffer);
+    }
+  }
+}
+
+/**
+ * An AST node that can be annotated with both a documentation comment and a
+ * list of annotations.
+ */
+abstract class AnnotatedNodeImpl extends AstNodeImpl implements AnnotatedNode {
+  /**
+   * The documentation comment associated with this node, or `null` if this node
+   * does not have a documentation comment associated with it.
+   */
+  Comment _comment;
+
+  /**
+   * The annotations associated with this node.
+   */
+  NodeList<Annotation> _metadata;
+
+  /**
+   * Initialize a newly created annotated node. Either or both of the [comment]
+   * and [metadata] can be `null` if the node does not have the corresponding
+   * attribute.
+   */
+  AnnotatedNodeImpl(Comment comment, List<Annotation> metadata) {
+    _comment = _becomeParentOf(comment);
+    _metadata = new NodeList<Annotation>(this, metadata);
+  }
+
+  @override
+  Token get beginToken {
+    if (_comment == null) {
+      if (_metadata.isEmpty) {
+        return firstTokenAfterCommentAndMetadata;
+      }
+      return _metadata.beginToken;
+    } else if (_metadata.isEmpty) {
+      return _comment.beginToken;
+    }
+    Token commentToken = _comment.beginToken;
+    Token metadataToken = _metadata.beginToken;
+    if (commentToken.offset < metadataToken.offset) {
+      return commentToken;
+    }
+    return metadataToken;
+  }
+
+  @override
+  Comment get documentationComment => _comment;
+
+  @override
+  void set documentationComment(Comment comment) {
+    _comment = _becomeParentOf(comment);
+  }
+
+  @override
+  NodeList<Annotation> get metadata => _metadata;
+
+  @override
+  List<AstNode> get sortedCommentAndAnnotations {
+    return <AstNode>[]
+      ..add(_comment)
+      ..addAll(_metadata)
+      ..sort(AstNode.LEXICAL_ORDER);
+  }
+
+  /**
+   * Return a holder of child entities that subclasses can add to.
+   */
+  ChildEntities get _childEntities {
+    ChildEntities result = new ChildEntities();
+    if (_commentIsBeforeAnnotations()) {
+      result
+        ..add(_comment)
+        ..addAll(_metadata);
+    } else {
+      result.addAll(sortedCommentAndAnnotations);
+    }
+    return result;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    if (_commentIsBeforeAnnotations()) {
+      _safelyVisitChild(_comment, visitor);
+      _metadata.accept(visitor);
+    } else {
+      for (AstNode child in sortedCommentAndAnnotations) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Return `true` if there are no annotations before the comment. Note that a
+   * result of `true` does not imply that there is a comment, nor that there are
+   * annotations associated with this node.
+   */
+  bool _commentIsBeforeAnnotations() {
+    if (_comment == null || _metadata.isEmpty) {
+      return true;
+    }
+    Annotation firstAnnotation = _metadata[0];
+    return _comment.offset < firstAnnotation.offset;
+  }
+}
+
+/**
+ * An annotation that can be associated with an AST node.
+ *
+ * > metadata ::=
+ * >     annotation*
+ * >
+ * > annotation ::=
+ * >     '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
+ */
+class AnnotationImpl extends AstNodeImpl implements Annotation {
+  /**
+   * The at sign that introduced the annotation.
+   */
+  Token atSign;
+
+  /**
+   * The name of the class defining the constructor that is being invoked or the
+   * name of the field that is being referenced.
+   */
+  Identifier _name;
+
+  /**
+   * The period before the constructor name, or `null` if this annotation is not
+   * the invocation of a named constructor.
+   */
+  Token period;
+
+  /**
+   * The name of the constructor being invoked, or `null` if this annotation is
+   * not the invocation of a named constructor.
+   */
+  SimpleIdentifier _constructorName;
+
+  /**
+   * The arguments to the constructor being invoked, or `null` if this
+   * annotation is not the invocation of a constructor.
+   */
+  ArgumentList _arguments;
+
+  /**
+   * The element associated with this annotation, or `null` if the AST structure
+   * has not been resolved or if this annotation could not be resolved.
+   */
+  Element _element;
+
+  /**
+   * The element annotation representing this annotation in the element model.
+   */
+  ElementAnnotation elementAnnotation;
+
+  /**
+   * Initialize a newly created annotation. Both the [period] and the
+   * [constructorName] can be `null` if the annotation is not referencing a
+   * named constructor. The [arguments] can be `null` if the annotation is not
+   * referencing a constructor.
+   */
+  AnnotationImpl(this.atSign, Identifier name, this.period,
+      SimpleIdentifier constructorName, ArgumentList arguments) {
+    _name = _becomeParentOf(name);
+    _constructorName = _becomeParentOf(constructorName);
+    _arguments = _becomeParentOf(arguments);
+  }
+
+  @override
+  ArgumentList get arguments => _arguments;
+
+  @override
+  void set arguments(ArgumentList arguments) {
+    _arguments = _becomeParentOf(arguments);
+  }
+
+  @override
+  Token get beginToken => atSign;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(atSign)
+    ..add(_name)
+    ..add(period)
+    ..add(_constructorName)
+    ..add(_arguments);
+
+  @override
+  SimpleIdentifier get constructorName => _constructorName;
+
+  @override
+  void set constructorName(SimpleIdentifier name) {
+    _constructorName = _becomeParentOf(name);
+  }
+
+  @override
+  Element get element {
+    if (_element != null) {
+      return _element;
+    } else if (_name != null) {
+      return _name.staticElement;
+    }
+    return null;
+  }
+
+  @override
+  void set element(Element element) {
+    _element = element;
+  }
+
+  @override
+  Token get endToken {
+    if (_arguments != null) {
+      return _arguments.endToken;
+    } else if (_constructorName != null) {
+      return _constructorName.endToken;
+    }
+    return _name.endToken;
+  }
+
+  @override
+  Identifier get name => _name;
+
+  @override
+  void set name(Identifier name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAnnotation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_constructorName, visitor);
+    _safelyVisitChild(_arguments, visitor);
+  }
+}
+
+/**
+ * A list of arguments in the invocation of an executable element (that is, a
+ * function, method, or constructor).
+ *
+ * > argumentList ::=
+ * >     '(' arguments? ')'
+ * >
+ * > arguments ::=
+ * >     [NamedExpression] (',' [NamedExpression])*
+ * >   | [Expression] (',' [Expression])* (',' [NamedExpression])*
+ */
+class ArgumentListImpl extends AstNodeImpl implements ArgumentList {
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The expressions producing the values of the arguments.
+   */
+  NodeList<Expression> _arguments;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * A list containing the elements representing the parameters corresponding to
+   * each of the arguments in this list, or `null` if the AST has not been
+   * resolved or if the function or method being invoked could not be determined
+   * based on static type information. The list must be the same length as the
+   * number of arguments, but can contain `null` entries if a given argument
+   * does not correspond to a formal parameter.
+   */
+  List<ParameterElement> _correspondingStaticParameters;
+
+  /**
+   * A list containing the elements representing the parameters corresponding to
+   * each of the arguments in this list, or `null` if the AST has not been
+   * resolved or if the function or method being invoked could not be determined
+   * based on propagated type information. The list must be the same length as
+   * the number of arguments, but can contain `null` entries if a given argument
+   * does not correspond to a formal parameter.
+   */
+  List<ParameterElement> _correspondingPropagatedParameters;
+
+  /**
+   * Initialize a newly created list of arguments. The list of [arguments] can
+   * be `null` if there are no arguments.
+   */
+  ArgumentListImpl(
+      this.leftParenthesis, List<Expression> arguments, this.rightParenthesis) {
+    _arguments = new NodeList<Expression>(this, arguments);
+  }
+
+  @override
+  NodeList<Expression> get arguments => _arguments;
+
+  @override
+  Token get beginToken => leftParenthesis;
+
+  @override
+  // TODO(paulberry): Add commas.
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftParenthesis)
+    ..addAll(_arguments)
+    ..add(rightParenthesis);
+
+  @override
+  void set correspondingPropagatedParameters(
+      List<ParameterElement> parameters) {
+    if (parameters.length != _arguments.length) {
+      throw new IllegalArgumentException(
+          "Expected ${_arguments.length} parameters, not ${parameters.length}");
+    }
+    _correspondingPropagatedParameters = parameters;
+  }
+
+  @override
+  void set correspondingStaticParameters(List<ParameterElement> parameters) {
+    if (parameters.length != _arguments.length) {
+      throw new IllegalArgumentException(
+          "Expected ${_arguments.length} parameters, not ${parameters.length}");
+    }
+    _correspondingStaticParameters = parameters;
+  }
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitArgumentList(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _arguments.accept(visitor);
+  }
+
+  /**
+   * If
+   * * the given [expression] is a child of this list,
+   * * the AST structure has been resolved,
+   * * the function being invoked is known based on propagated type information,
+   *   and
+   * * the expression corresponds to one of the parameters of the function being
+   *   invoked,
+   * then return the parameter element representing the parameter to which the
+   * value of the given expression will be bound. Otherwise, return `null`.
+   */
+  ParameterElement _getPropagatedParameterElementFor(Expression expression) {
+    if (_correspondingPropagatedParameters == null ||
+        _correspondingPropagatedParameters.length != _arguments.length) {
+      // Either the AST structure has not been resolved, the invocation of which
+      // this list is a part could not be resolved, or the argument list was
+      // modified after the parameters were set.
+      return null;
+    }
+    int index = _arguments.indexOf(expression);
+    if (index < 0) {
+      // The expression isn't a child of this node.
+      return null;
+    }
+    return _correspondingPropagatedParameters[index];
+  }
+
+  /**
+   * If
+   * * the given [expression] is a child of this list,
+   * * the AST structure has been resolved,
+   * * the function being invoked is known based on static type information, and
+   * * the expression corresponds to one of the parameters of the function being
+   *   invoked,
+   * then return the parameter element representing the parameter to which the
+   * value of the given expression will be bound. Otherwise, return `null`.
+   */
+  ParameterElement _getStaticParameterElementFor(Expression expression) {
+    if (_correspondingStaticParameters == null ||
+        _correspondingStaticParameters.length != _arguments.length) {
+      // Either the AST structure has not been resolved, the invocation of which
+      // this list is a part could not be resolved, or the argument list was
+      // modified after the parameters were set.
+      return null;
+    }
+    int index = _arguments.indexOf(expression);
+    if (index < 0) {
+      // The expression isn't a child of this node.
+      return null;
+    }
+    return _correspondingStaticParameters[index];
+  }
+}
+
+/**
+ * An as expression.
+ *
+ * > asExpression ::=
+ * >     [Expression] 'as' [TypeName]
+ */
+class AsExpressionImpl extends ExpressionImpl implements AsExpression {
+  /**
+   * The expression used to compute the value being cast.
+   */
+  Expression _expression;
+
+  /**
+   * The 'as' operator.
+   */
+  Token asOperator;
+
+  /**
+   * The name of the type being cast to.
+   */
+  TypeName _type;
+
+  /**
+   * Initialize a newly created as expression.
+   */
+  AsExpressionImpl(Expression expression, this.asOperator, TypeName type) {
+    _expression = _becomeParentOf(expression);
+    _type = _becomeParentOf(type);
+  }
+
+  @override
+  Token get beginToken => _expression.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_expression)..add(asOperator)..add(_type);
+
+  @override
+  Token get endToken => _type.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 7;
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName name) {
+    _type = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAsExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+    _safelyVisitChild(_type, visitor);
+  }
+}
+
+/**
+ * An assert statement.
+ *
+ * > assertStatement ::=
+ * >     'assert' '(' [Expression] ')' ';'
+ */
+class AssertStatementImpl extends StatementImpl implements AssertStatement {
+  /**
+   * The token representing the 'assert' keyword.
+   */
+  Token assertKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The condition that is being asserted to be `true`.
+   */
+  Expression _condition;
+
+  /**
+   * The comma, if a message expression was supplied.  Otherwise `null`.
+   */
+  Token comma;
+
+  /**
+   * The message to report if the assertion fails.  `null` if no message was
+   * supplied.
+   */
+  Expression _message;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created assert statement.
+   */
+  AssertStatementImpl(
+      this.assertKeyword,
+      this.leftParenthesis,
+      Expression condition,
+      this.comma,
+      Expression message,
+      this.rightParenthesis,
+      this.semicolon) {
+    _condition = _becomeParentOf(condition);
+    _message = _becomeParentOf(message);
+  }
+
+  @override
+  Token get beginToken => assertKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(assertKeyword)
+    ..add(leftParenthesis)
+    ..add(_condition)
+    ..add(comma)
+    ..add(_message)
+    ..add(rightParenthesis)
+    ..add(semicolon);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression condition) {
+    _condition = _becomeParentOf(condition);
+  }
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Expression get message => _message;
+
+  @override
+  void set message(Expression expression) {
+    _message = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAssertStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(message, visitor);
+  }
+}
+
+/**
+ * An assignment expression.
+ *
+ * > assignmentExpression ::=
+ * >     [Expression] operator [Expression]
+ */
+class AssignmentExpressionImpl extends ExpressionImpl
+    implements AssignmentExpression {
+  /**
+   * The expression used to compute the left hand side.
+   */
+  Expression _leftHandSide;
+
+  /**
+   * The assignment operator being applied.
+   */
+  Token operator;
+
+  /**
+   * The expression used to compute the right hand side.
+   */
+  Expression _rightHandSide;
+
+  /**
+   * The element associated with the operator based on the static type of the
+   * left-hand-side, or `null` if the AST structure has not been resolved, if
+   * the operator is not a compound operator, or if the operator could not be
+   * resolved.
+   */
+  MethodElement staticElement;
+
+  /**
+   * The element associated with the operator based on the propagated type of
+   * the left-hand-side, or `null` if the AST structure has not been resolved,
+   * if the operator is not a compound operator, or if the operator could not be
+   * resolved.
+   */
+  MethodElement propagatedElement;
+
+  /**
+   * Initialize a newly created assignment expression.
+   */
+  AssignmentExpressionImpl(
+      Expression leftHandSide, this.operator, Expression rightHandSide) {
+    if (leftHandSide == null || rightHandSide == null) {
+      String message;
+      if (leftHandSide == null) {
+        if (rightHandSide == null) {
+          message = "Both the left-hand and right-hand sides are null";
+        } else {
+          message = "The left-hand size is null";
+        }
+      } else {
+        message = "The right-hand size is null";
+      }
+      AnalysisEngine.instance.logger.logError(
+          message, new CaughtException(new AnalysisException(message), null));
+    }
+    _leftHandSide = _becomeParentOf(leftHandSide);
+    _rightHandSide = _becomeParentOf(rightHandSide);
+  }
+
+  @override
+  Token get beginToken => _leftHandSide.beginToken;
+
+  @override
+  MethodElement get bestElement {
+    MethodElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_leftHandSide)
+    ..add(operator)
+    ..add(_rightHandSide);
+
+  @override
+  Token get endToken => _rightHandSide.endToken;
+
+  @override
+  Expression get leftHandSide => _leftHandSide;
+
+  @override
+  void set leftHandSide(Expression expression) {
+    _leftHandSide = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 1;
+
+  @override
+  Expression get rightHandSide => _rightHandSide;
+
+  @override
+  void set rightHandSide(Expression expression) {
+    _rightHandSide = _becomeParentOf(expression);
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on propagated type information, then return the parameter
+   * element representing the parameter to which the value of the right operand
+   * will be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _propagatedParameterElementForRightHandSide {
+    ExecutableElement executableElement = null;
+    if (propagatedElement != null) {
+      executableElement = propagatedElement;
+    } else {
+      if (_leftHandSide is Identifier) {
+        Identifier identifier = _leftHandSide as Identifier;
+        Element leftElement = identifier.propagatedElement;
+        if (leftElement is ExecutableElement) {
+          executableElement = leftElement;
+        }
+      }
+      if (_leftHandSide is PropertyAccess) {
+        SimpleIdentifier identifier =
+            (_leftHandSide as PropertyAccess).propertyName;
+        Element leftElement = identifier.propagatedElement;
+        if (leftElement is ExecutableElement) {
+          executableElement = leftElement;
+        }
+      }
+    }
+    if (executableElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = executableElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on static type information, then return the parameter element
+   * representing the parameter to which the value of the right operand will be
+   * bound. Otherwise, return `null`.
+   */
+  ParameterElement get _staticParameterElementForRightHandSide {
+    ExecutableElement executableElement = null;
+    if (staticElement != null) {
+      executableElement = staticElement;
+    } else {
+      if (_leftHandSide is Identifier) {
+        Element leftElement = (_leftHandSide as Identifier).staticElement;
+        if (leftElement is ExecutableElement) {
+          executableElement = leftElement;
+        }
+      }
+      if (_leftHandSide is PropertyAccess) {
+        Element leftElement =
+            (_leftHandSide as PropertyAccess).propertyName.staticElement;
+        if (leftElement is ExecutableElement) {
+          executableElement = leftElement;
+        }
+      }
+    }
+    if (executableElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = executableElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAssignmentExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_leftHandSide, visitor);
+    _safelyVisitChild(_rightHandSide, visitor);
+  }
+}
+
+/**
+ * A node in the AST structure for a Dart program.
+ */
+abstract class AstNodeImpl implements AstNode {
+  /**
+   * The parent of the node, or `null` if the node is the root of an AST
+   * structure.
+   */
+  AstNode _parent;
+
+  /**
+   * A table mapping the names of properties to their values, or `null` if this
+   * node does not have any properties associated with it.
+   */
+  Map<String, Object> _propertyMap;
+
+  @override
+  int get end => offset + length;
+
+  @override
+  bool get isSynthetic => false;
+
+  @override
+  int get length {
+    Token beginToken = this.beginToken;
+    Token endToken = this.endToken;
+    if (beginToken == null || endToken == null) {
+      return -1;
+    }
+    return endToken.offset + endToken.length - beginToken.offset;
+  }
+
+  @override
+  int get offset {
+    Token beginToken = this.beginToken;
+    if (beginToken == null) {
+      return -1;
+    }
+    return beginToken.offset;
+  }
+
+  @override
+  AstNode get parent => _parent;
+
+  @override
+  AstNode get root {
+    AstNode root = this;
+    AstNode parent = this.parent;
+    while (parent != null) {
+      root = parent;
+      parent = root.parent;
+    }
+    return root;
+  }
+
+  @override
+  AstNode getAncestor(Predicate<AstNode> predicate) {
+    // TODO(brianwilkerson) It is a bug that this method can return `this`.
+    AstNode node = this;
+    while (node != null && !predicate(node)) {
+      node = node.parent;
+    }
+    return node;
+  }
+
+  @override
+  Object getProperty(String name) {
+    if (_propertyMap == null) {
+      return null;
+    }
+    return _propertyMap[name];
+  }
+
+  @override
+  void setProperty(String name, Object value) {
+    if (value == null) {
+      if (_propertyMap != null) {
+        _propertyMap.remove(name);
+        if (_propertyMap.isEmpty) {
+          _propertyMap = null;
+        }
+      }
+    } else {
+      if (_propertyMap == null) {
+        _propertyMap = new HashMap<String, Object>();
+      }
+      _propertyMap[name] = value;
+    }
+  }
+
+  @override
+  String toSource() {
+    PrintStringWriter writer = new PrintStringWriter();
+    accept(new ToSourceVisitor(writer));
+    return writer.toString();
+  }
+
+  @override
+  String toString() => toSource();
+
+  /**
+   * Make this node the parent of the given [child] node. Return the child node.
+   */
+  AstNode _becomeParentOf(AstNode child) {
+    if (child != null) {
+      (child as AstNodeImpl)._parent = this;
+    }
+    return child;
+  }
+
+  /**
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
+   */
+  void _safelyVisitChild(AstNode child, AstVisitor visitor) {
+    if (child != null) {
+      child.accept(visitor);
+    }
+  }
+}
+
+/**
+ * An await expression.
+ *
+ * > awaitExpression ::=
+ * >     'await' [Expression]
+ */
+class AwaitExpressionImpl extends ExpressionImpl implements AwaitExpression {
+  /**
+   * The 'await' keyword.
+   */
+  Token awaitKeyword;
+
+  /**
+   * The expression whose value is being waited on.
+   */
+  Expression _expression;
+
+  /**
+   * Initialize a newly created await expression.
+   */
+  AwaitExpressionImpl(this.awaitKeyword, Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken {
+    if (awaitKeyword != null) {
+      return awaitKeyword;
+    }
+    return _expression.beginToken;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(awaitKeyword)..add(_expression);
+
+  @override
+  Token get endToken => _expression.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 0;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAwaitExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A binary (infix) expression.
+ *
+ * > binaryExpression ::=
+ * >     [Expression] [Token] [Expression]
+ */
+class BinaryExpressionImpl extends ExpressionImpl implements BinaryExpression {
+  /**
+   * The expression used to compute the left operand.
+   */
+  Expression _leftOperand;
+
+  /**
+   * The binary operator being applied.
+   */
+  Token operator;
+
+  /**
+   * The expression used to compute the right operand.
+   */
+  Expression _rightOperand;
+
+  /**
+   * The element associated with the operator based on the static type of the
+   * left operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement staticElement;
+
+  /**
+   * The element associated with the operator based on the propagated type of
+   * the left operand, or `null` if the AST structure has not been resolved, if
+   * the operator is not user definable, or if the operator could not be
+   * resolved.
+   */
+  MethodElement propagatedElement;
+
+  /**
+   * Initialize a newly created binary expression.
+   */
+  BinaryExpressionImpl(
+      Expression leftOperand, this.operator, Expression rightOperand) {
+    _leftOperand = _becomeParentOf(leftOperand);
+    _rightOperand = _becomeParentOf(rightOperand);
+  }
+
+  @override
+  Token get beginToken => _leftOperand.beginToken;
+
+  @override
+  MethodElement get bestElement {
+    MethodElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_leftOperand)..add(operator)..add(_rightOperand);
+
+  @override
+  Token get endToken => _rightOperand.endToken;
+
+  @override
+  Expression get leftOperand => _leftOperand;
+
+  @override
+  void set leftOperand(Expression expression) {
+    _leftOperand = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => operator.type.precedence;
+
+  @override
+  Expression get rightOperand => _rightOperand;
+
+  @override
+  void set rightOperand(Expression expression) {
+    _rightOperand = _becomeParentOf(expression);
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on propagated type information, then return the parameter
+   * element representing the parameter to which the value of the right operand
+   * will be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _propagatedParameterElementForRightOperand {
+    if (propagatedElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = propagatedElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on static type information, then return the parameter element
+   * representing the parameter to which the value of the right operand will be
+   * bound. Otherwise, return `null`.
+   */
+  ParameterElement get _staticParameterElementForRightOperand {
+    if (staticElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = staticElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitBinaryExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_leftOperand, visitor);
+    _safelyVisitChild(_rightOperand, visitor);
+  }
+}
+
+/**
+ * A function body that consists of a block of statements.
+ *
+ * > blockFunctionBody ::=
+ * >     ('async' | 'async' '*' | 'sync' '*')? [Block]
+ */
+class BlockFunctionBodyImpl extends FunctionBodyImpl
+    implements BlockFunctionBody {
+  /**
+   * The token representing the 'async' or 'sync' keyword, or `null` if there is
+   * no such keyword.
+   */
+  Token keyword;
+
+  /**
+   * The star optionally following the 'async' or 'sync' keyword, or `null` if
+   * there is wither no such keyword or no star.
+   */
+  Token star;
+
+  /**
+   * The block representing the body of the function.
+   */
+  Block _block;
+
+  /**
+   * Initialize a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if there is no keyword specified
+   * for the block. The [star] can be `null` if there is no star following the
+   * keyword (and must be `null` if there is no keyword).
+   */
+  BlockFunctionBodyImpl(this.keyword, this.star, Block block) {
+    _block = _becomeParentOf(block);
+  }
+
+  @override
+  Token get beginToken {
+    if (keyword != null) {
+      return keyword;
+    }
+    return _block.beginToken;
+  }
+
+  @override
+  Block get block => _block;
+
+  @override
+  void set block(Block block) {
+    _block = _becomeParentOf(block);
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(keyword)..add(star)..add(_block);
+
+  @override
+  Token get endToken => _block.endToken;
+
+  @override
+  bool get isAsynchronous => keyword != null && keyword.lexeme == Parser.ASYNC;
+
+  @override
+  bool get isGenerator => star != null;
+
+  @override
+  bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitBlockFunctionBody(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_block, visitor);
+  }
+}
+
+/**
+ * A sequence of statements.
+ *
+ * > block ::=
+ * >     '{' statement* '}'
+ */
+class BlockImpl extends StatementImpl implements Block {
+  /**
+   * The left curly bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The statements contained in the block.
+   */
+  NodeList<Statement> _statements;
+
+  /**
+   * The right curly bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created block of code.
+   */
+  BlockImpl(this.leftBracket, List<Statement> statements, this.rightBracket) {
+    _statements = new NodeList<Statement>(this, statements);
+  }
+
+  @override
+  Token get beginToken => leftBracket;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftBracket)
+    ..addAll(_statements)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<Statement> get statements => _statements;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitBlock(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _statements.accept(visitor);
+  }
+}
+
+/**
+ * A boolean literal expression.
+ *
+ * > booleanLiteral ::=
+ * >     'false' | 'true'
+ */
+class BooleanLiteralImpl extends LiteralImpl implements BooleanLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token literal;
+
+  /**
+   * The value of the literal.
+   */
+  bool value = false;
+
+  /**
+   * Initialize a newly created boolean literal.
+   */
+  BooleanLiteralImpl(this.literal, this.value);
+
+  @override
+  Token get beginToken => literal;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(literal);
+
+  @override
+  Token get endToken => literal;
+
+  @override
+  bool get isSynthetic => literal.isSynthetic;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitBooleanLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A break statement.
+ *
+ * > breakStatement ::=
+ * >     'break' [SimpleIdentifier]? ';'
+ */
+class BreakStatementImpl extends StatementImpl implements BreakStatement {
+  /**
+   * The token representing the 'break' keyword.
+   */
+  Token breakKeyword;
+
+  /**
+   * The label associated with the statement, or `null` if there is no label.
+   */
+  SimpleIdentifier _label;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * The AstNode which this break statement is breaking from.  This will be
+   * either a [Statement] (in the case of breaking out of a loop), a
+   * [SwitchMember] (in the case of a labeled break statement whose label
+   * matches a label on a switch case in an enclosing switch statement), or
+   * `null` if the AST has not yet been resolved or if the target could not be
+   * resolved. Note that if the source code has errors, the target might be
+   * invalid (e.g. trying to break to a switch case).
+   */
+  AstNode target;
+
+  /**
+   * Initialize a newly created break statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  BreakStatementImpl(
+      this.breakKeyword, SimpleIdentifier label, this.semicolon) {
+    _label = _becomeParentOf(label);
+  }
+
+  @override
+  Token get beginToken => breakKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(breakKeyword)..add(_label)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  SimpleIdentifier get label => _label;
+
+  @override
+  void set label(SimpleIdentifier identifier) {
+    _label = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitBreakStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_label, visitor);
+  }
+}
+
+/**
+ * A sequence of cascaded expressions: expressions that share a common target.
+ * There are three kinds of expressions that can be used in a cascade
+ * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
+ *
+ * > cascadeExpression ::=
+ * >     [Expression] cascadeSection*
+ * >
+ * > cascadeSection ::=
+ * >     '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
+ * >     (assignmentOperator expressionWithoutCascade)?
+ * >
+ * > cascadeSelector ::=
+ * >     '[ ' expression '] '
+ * >   | identifier
+ */
+class CascadeExpressionImpl extends ExpressionImpl
+    implements CascadeExpression {
+  /**
+   * The target of the cascade sections.
+   */
+  Expression _target;
+
+  /**
+   * The cascade sections sharing the common target.
+   */
+  NodeList<Expression> _cascadeSections;
+
+  /**
+   * Initialize a newly created cascade expression. The list of
+   * [cascadeSections] must contain at least one element.
+   */
+  CascadeExpressionImpl(Expression target, List<Expression> cascadeSections) {
+    _target = _becomeParentOf(target);
+    _cascadeSections = new NodeList<Expression>(this, cascadeSections);
+  }
+
+  @override
+  Token get beginToken => _target.beginToken;
+
+  @override
+  NodeList<Expression> get cascadeSections => _cascadeSections;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_target)
+    ..addAll(_cascadeSections);
+
+  @override
+  Token get endToken => _cascadeSections.endToken;
+
+  @override
+  int get precedence => 2;
+
+  @override
+  Expression get target => _target;
+
+  @override
+  void set target(Expression target) {
+    _target = _becomeParentOf(target);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitCascadeExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_target, visitor);
+    _cascadeSections.accept(visitor);
+  }
+}
+
+/**
+ * A catch clause within a try statement.
+ *
+ * > onPart ::=
+ * >     catchPart [Block]
+ * >   | 'on' type catchPart? [Block]
+ * >
+ * > catchPart ::=
+ * >     'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
+ */
+class CatchClauseImpl extends AstNodeImpl implements CatchClause {
+  /**
+   * The token representing the 'on' keyword, or `null` if there is no 'on'
+   * keyword.
+   */
+  Token onKeyword;
+
+  /**
+   * The type of exceptions caught by this catch clause, or `null` if this catch
+   * clause catches every type of exception.
+   */
+  TypeName _exceptionType;
+
+  /**
+   * The token representing the 'catch' keyword, or `null` if there is no
+   * 'catch' keyword.
+   */
+  Token catchKeyword;
+
+  /**
+   * The left parenthesis, or `null` if there is no 'catch' keyword.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The parameter whose value will be the exception that was thrown, or `null`
+   * if there is no 'catch' keyword.
+   */
+  SimpleIdentifier _exceptionParameter;
+
+  /**
+   * The comma separating the exception parameter from the stack trace
+   * parameter, or `null` if there is no stack trace parameter.
+   */
+  Token comma;
+
+  /**
+   * The parameter whose value will be the stack trace associated with the
+   * exception, or `null` if there is no stack trace parameter.
+   */
+  SimpleIdentifier _stackTraceParameter;
+
+  /**
+   * The right parenthesis, or `null` if there is no 'catch' keyword.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The body of the catch block.
+   */
+  Block _body;
+
+  /**
+   * Initialize a newly created catch clause. The [onKeyword] and
+   * [exceptionType] can be `null` if the clause will catch all exceptions. The
+   * [comma] and [stackTraceParameter] can be `null` if the stack trace
+   * parameter is not defined.
+   */
+  CatchClauseImpl(
+      this.onKeyword,
+      TypeName exceptionType,
+      this.catchKeyword,
+      this.leftParenthesis,
+      SimpleIdentifier exceptionParameter,
+      this.comma,
+      SimpleIdentifier stackTraceParameter,
+      this.rightParenthesis,
+      Block body) {
+    _exceptionType = _becomeParentOf(exceptionType);
+    _exceptionParameter = _becomeParentOf(exceptionParameter);
+    _stackTraceParameter = _becomeParentOf(stackTraceParameter);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Token get beginToken {
+    if (onKeyword != null) {
+      return onKeyword;
+    }
+    return catchKeyword;
+  }
+
+  @override
+  Block get body => _body;
+
+  @override
+  void set body(Block block) {
+    _body = _becomeParentOf(block);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(onKeyword)
+    ..add(_exceptionType)
+    ..add(catchKeyword)
+    ..add(leftParenthesis)
+    ..add(_exceptionParameter)
+    ..add(comma)
+    ..add(_stackTraceParameter)
+    ..add(rightParenthesis)
+    ..add(_body);
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  SimpleIdentifier get exceptionParameter => _exceptionParameter;
+
+  @override
+  void set exceptionParameter(SimpleIdentifier parameter) {
+    _exceptionParameter = _becomeParentOf(parameter);
+  }
+
+  @override
+  TypeName get exceptionType => _exceptionType;
+
+  @override
+  void set exceptionType(TypeName exceptionType) {
+    _exceptionType = _becomeParentOf(exceptionType);
+  }
+
+  @override
+  SimpleIdentifier get stackTraceParameter => _stackTraceParameter;
+
+  @override
+  void set stackTraceParameter(SimpleIdentifier parameter) {
+    _stackTraceParameter = _becomeParentOf(parameter);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitCatchClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_exceptionType, visitor);
+    _safelyVisitChild(_exceptionParameter, visitor);
+    _safelyVisitChild(_stackTraceParameter, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * Helper class to allow iteration of child entities of an AST node.
+ */
+class ChildEntities extends Object with IterableMixin implements Iterable {
+  /**
+   * The list of child entities to be iterated over.
+   */
+  List _entities = [];
+
+  @override
+  Iterator get iterator => _entities.iterator;
+
+  /**
+   * Add an AST node or token as the next child entity, if it is not null.
+   */
+  void add(entity) {
+    if (entity != null) {
+      assert(entity is Token || entity is AstNode);
+      _entities.add(entity);
+    }
+  }
+
+  /**
+   * Add the given items as the next child entities, if [items] is not null.
+   */
+  void addAll(Iterable items) {
+    if (items != null) {
+      _entities.addAll(items);
+    }
+  }
+}
+
+/**
+ * The declaration of a class.
+ *
+ * > classDeclaration ::=
+ * >     'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
+ * >     ([ExtendsClause] [WithClause]?)?
+ * >     [ImplementsClause]?
+ * >     '{' [ClassMember]* '}'
+ */
+class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl
+    implements ClassDeclaration {
+  /**
+   * The 'abstract' keyword, or `null` if the keyword was absent.
+   */
+  Token abstractKeyword;
+
+  /**
+   * The token representing the 'class' keyword.
+   */
+  Token classKeyword;
+
+  /**
+   * The type parameters for the class, or `null` if the class does not have any
+   * type parameters.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The extends clause for the class, or `null` if the class does not extend
+   * any other class.
+   */
+  ExtendsClause _extendsClause;
+
+  /**
+   * The with clause for the class, or `null` if the class does not have a with
+   * clause.
+   */
+  WithClause _withClause;
+
+  /**
+   * The implements clause for the class, or `null` if the class does not
+   * implement any interfaces.
+   */
+  ImplementsClause _implementsClause;
+
+  /**
+   * The native clause for the class, or `null` if the class does not have a
+   * native clause.
+   */
+  NativeClause _nativeClause;
+
+  /**
+   * The left curly bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The members defined by the class.
+   */
+  NodeList<ClassMember> _members;
+
+  /**
+   * The right curly bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created class declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the class does not have the
+   * corresponding attribute. The [abstractKeyword] can be `null` if the class
+   * is not abstract. The [typeParameters] can be `null` if the class does not
+   * have any type parameters. Any or all of the [extendsClause], [withClause],
+   * and [implementsClause] can be `null` if the class does not have the
+   * corresponding clause. The list of [members] can be `null` if the class does
+   * not have any members.
+   */
+  ClassDeclarationImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.abstractKeyword,
+      this.classKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      ExtendsClause extendsClause,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      this.leftBracket,
+      List<ClassMember> members,
+      this.rightBracket)
+      : super(comment, metadata, name) {
+    _typeParameters = _becomeParentOf(typeParameters);
+    _extendsClause = _becomeParentOf(extendsClause);
+    _withClause = _becomeParentOf(withClause);
+    _implementsClause = _becomeParentOf(implementsClause);
+    _members = new NodeList<ClassMember>(this, members);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(abstractKeyword)
+    ..add(classKeyword)
+    ..add(_name)
+    ..add(_typeParameters)
+    ..add(_extendsClause)
+    ..add(_withClause)
+    ..add(_implementsClause)
+    ..add(_nativeClause)
+    ..add(leftBracket)
+    ..addAll(members)
+    ..add(rightBracket);
+
+  @override
+  ClassElement get element =>
+      _name != null ? (_name.staticElement as ClassElement) : null;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  ExtendsClause get extendsClause => _extendsClause;
+
+  @override
+  void set extendsClause(ExtendsClause extendsClause) {
+    _extendsClause = _becomeParentOf(extendsClause);
+  }
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (abstractKeyword != null) {
+      return abstractKeyword;
+    }
+    return classKeyword;
+  }
+
+  @override
+  ImplementsClause get implementsClause => _implementsClause;
+
+  @override
+  void set implementsClause(ImplementsClause implementsClause) {
+    _implementsClause = _becomeParentOf(implementsClause);
+  }
+
+  @override
+  bool get isAbstract => abstractKeyword != null;
+
+  @override
+  NodeList<ClassMember> get members => _members;
+
+  @override
+  NativeClause get nativeClause => _nativeClause;
+
+  @override
+  void set nativeClause(NativeClause nativeClause) {
+    _nativeClause = _becomeParentOf(nativeClause);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  WithClause get withClause => _withClause;
+
+  @override
+  void set withClause(WithClause withClause) {
+    _withClause = _becomeParentOf(withClause);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitClassDeclaration(this);
+
+  @override
+  ConstructorDeclaration getConstructor(String name) {
+    for (ClassMember classMember in _members) {
+      if (classMember is ConstructorDeclaration) {
+        ConstructorDeclaration constructor = classMember;
+        SimpleIdentifier constructorName = constructor.name;
+        if (name == null && constructorName == null) {
+          return constructor;
+        }
+        if (constructorName != null && constructorName.name == name) {
+          return constructor;
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  VariableDeclaration getField(String name) {
+    for (ClassMember classMember in _members) {
+      if (classMember is FieldDeclaration) {
+        FieldDeclaration fieldDeclaration = classMember;
+        NodeList<VariableDeclaration> fields =
+            fieldDeclaration.fields.variables;
+        for (VariableDeclaration field in fields) {
+          SimpleIdentifier fieldName = field.name;
+          if (fieldName != null && name == fieldName.name) {
+            return field;
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  MethodDeclaration getMethod(String name) {
+    for (ClassMember classMember in _members) {
+      if (classMember is MethodDeclaration) {
+        MethodDeclaration method = classMember;
+        SimpleIdentifier methodName = method.name;
+        if (methodName != null && name == methodName.name) {
+          return method;
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_extendsClause, visitor);
+    _safelyVisitChild(_withClause, visitor);
+    _safelyVisitChild(_implementsClause, visitor);
+    _safelyVisitChild(_nativeClause, visitor);
+    members.accept(visitor);
+  }
+}
+
+/**
+ * A node that declares a name within the scope of a class.
+ */
+abstract class ClassMemberImpl extends DeclarationImpl implements ClassMember {
+  /**
+   * Initialize a newly created member of a class. Either or both of the
+   * [comment] and [metadata] can be `null` if the member does not have the
+   * corresponding attribute.
+   */
+  ClassMemberImpl(Comment comment, List<Annotation> metadata)
+      : super(comment, metadata);
+}
+
+/**
+ * A class type alias.
+ *
+ * > classTypeAlias ::=
+ * >     [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication
+ * >
+ * > mixinApplication ::=
+ * >     [TypeName] [WithClause] [ImplementsClause]? ';'
+ */
+class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias {
+  /**
+   * The type parameters for the class, or `null` if the class does not have any
+   * type parameters.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The token for the '=' separating the name from the definition.
+   */
+  Token equals;
+
+  /**
+   * The token for the 'abstract' keyword, or `null` if this is not defining an
+   * abstract class.
+   */
+  Token abstractKeyword;
+
+  /**
+   * The name of the superclass of the class being declared.
+   */
+  TypeName _superclass;
+
+  /**
+   * The with clause for this class.
+   */
+  WithClause _withClause;
+
+  /**
+   * The implements clause for this class, or `null` if there is no implements
+   * clause.
+   */
+  ImplementsClause _implementsClause;
+
+  /**
+   * Initialize a newly created class type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the class type alias does not
+   * have the corresponding attribute. The [typeParameters] can be `null` if the
+   * class does not have any type parameters. The [abstractKeyword] can be
+   * `null` if the class is not abstract. The [implementsClause] can be `null`
+   * if the class does not implement any interfaces.
+   */
+  ClassTypeAliasImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      this.equals,
+      this.abstractKeyword,
+      TypeName superclass,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      Token semicolon)
+      : super(comment, metadata, keyword, name, semicolon) {
+    _typeParameters = _becomeParentOf(typeParameters);
+    _superclass = _becomeParentOf(superclass);
+    _withClause = _becomeParentOf(withClause);
+    _implementsClause = _becomeParentOf(implementsClause);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(typedefKeyword)
+    ..add(_name)
+    ..add(_typeParameters)
+    ..add(equals)
+    ..add(abstractKeyword)
+    ..add(_superclass)
+    ..add(_withClause)
+    ..add(_implementsClause)
+    ..add(semicolon);
+
+  @override
+  ClassElement get element =>
+      _name != null ? (_name.staticElement as ClassElement) : null;
+
+  @override
+  ImplementsClause get implementsClause => _implementsClause;
+
+  @override
+  void set implementsClause(ImplementsClause implementsClause) {
+    _implementsClause = _becomeParentOf(implementsClause);
+  }
+
+  @override
+  bool get isAbstract => abstractKeyword != null;
+
+  @override
+  TypeName get superclass => _superclass;
+
+  @override
+  void set superclass(TypeName superclass) {
+    _superclass = _becomeParentOf(superclass);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  WithClause get withClause => _withClause;
+
+  @override
+  void set withClause(WithClause withClause) {
+    _withClause = _becomeParentOf(withClause);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitClassTypeAlias(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_superclass, visitor);
+    _safelyVisitChild(_withClause, visitor);
+    _safelyVisitChild(_implementsClause, visitor);
+  }
+}
+
+/**
+ * A combinator associated with an import or export directive.
+ *
+ * > combinator ::=
+ * >     [HideCombinator]
+ * >   | [ShowCombinator]
+ */
+abstract class CombinatorImpl extends AstNodeImpl implements Combinator {
+  /**
+   * The 'hide' or 'show' keyword specifying what kind of processing is to be
+   * done on the names.
+   */
+  Token keyword;
+
+  /**
+   * Initialize a newly created combinator.
+   */
+  CombinatorImpl(this.keyword);
+
+  @override
+  Token get beginToken => keyword;
+}
+
+/**
+ * A comment within the source code.
+ *
+ * > comment ::=
+ * >     endOfLineComment
+ * >   | blockComment
+ * >   | documentationComment
+ * >
+ * > endOfLineComment ::=
+ * >     '//' (CHARACTER - EOL)* EOL
+ * >
+ * > blockComment ::=
+ * >     '/ *' CHARACTER* '&#42;/'
+ * >
+ * > documentationComment ::=
+ * >     '/ **' (CHARACTER | [CommentReference])* '&#42;/'
+ * >   | ('///' (CHARACTER - EOL)* EOL)+
+ */
+class CommentImpl extends AstNodeImpl implements Comment {
+  /**
+   * The tokens representing the comment.
+   */
+  final List<Token> tokens;
+
+  /**
+   * The type of the comment.
+   */
+  final CommentType _type;
+
+  /**
+   * The references embedded within the documentation comment. This list will be
+   * empty unless this is a documentation comment that has references embedded
+   * within it.
+   */
+  NodeList<CommentReference> _references;
+
+  /**
+   * Initialize a newly created comment. The list of [tokens] must contain at
+   * least one token. The [type] is the type of the comment. The list of
+   * [references] can be empty if the comment does not contain any embedded
+   * references.
+   */
+  CommentImpl(this.tokens, this._type, List<CommentReference> references) {
+    _references = new NodeList<CommentReference>(this, references);
+  }
+
+  @override
+  Token get beginToken => tokens[0];
+
+  @override
+  Iterable get childEntities => new ChildEntities()..addAll(tokens);
+
+  @override
+  Token get endToken => tokens[tokens.length - 1];
+
+  @override
+  bool get isBlock => _type == CommentType.BLOCK;
+
+  @override
+  bool get isDocumentation => _type == CommentType.DOCUMENTATION;
+
+  @override
+  bool get isEndOfLine => _type == CommentType.END_OF_LINE;
+
+  @override
+  NodeList<CommentReference> get references => _references;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitComment(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _references.accept(visitor);
+  }
+
+  /**
+   * Create a block comment consisting of the given [tokens].
+   */
+  static Comment createBlockComment(List<Token> tokens) =>
+      new CommentImpl(tokens, CommentType.BLOCK, null);
+
+  /**
+   * Create a documentation comment consisting of the given [tokens].
+   */
+  static Comment createDocumentationComment(List<Token> tokens) =>
+      new CommentImpl(
+          tokens, CommentType.DOCUMENTATION, new List<CommentReference>());
+
+  /**
+   * Create a documentation comment consisting of the given [tokens] and having
+   * the given [references] embedded within it.
+   */
+  static Comment createDocumentationCommentWithReferences(
+          List<Token> tokens, List<CommentReference> references) =>
+      new CommentImpl(tokens, CommentType.DOCUMENTATION, references);
+
+  /**
+   * Create an end-of-line comment consisting of the given [tokens].
+   */
+  static Comment createEndOfLineComment(List<Token> tokens) =>
+      new CommentImpl(tokens, CommentType.END_OF_LINE, null);
+}
+
+/**
+ * A reference to a Dart element that is found within a documentation comment.
+ *
+ * > commentReference ::=
+ * >     '[' 'new'? [Identifier] ']'
+ */
+class CommentReferenceImpl extends AstNodeImpl implements CommentReference {
+  /**
+   * The token representing the 'new' keyword, or `null` if there was no 'new'
+   * keyword.
+   */
+  Token newKeyword;
+
+  /**
+   * The identifier being referenced.
+   */
+  Identifier _identifier;
+
+  /**
+   * Initialize a newly created reference to a Dart element. The [newKeyword]
+   * can be `null` if the reference is not to a constructor.
+   */
+  CommentReferenceImpl(this.newKeyword, Identifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Token get beginToken => _identifier.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(newKeyword)..add(_identifier);
+
+  @override
+  Token get endToken => _identifier.endToken;
+
+  @override
+  Identifier get identifier => _identifier;
+
+  @override
+  void set identifier(Identifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitCommentReference(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_identifier, visitor);
+  }
+}
+
+/**
+ * The possible types of comments that are recognized by the parser.
+ */
+class CommentType {
+  /**
+   * A block comment.
+   */
+  static const CommentType BLOCK = const CommentType('BLOCK');
+
+  /**
+   * A documentation comment.
+   */
+  static const CommentType DOCUMENTATION = const CommentType('DOCUMENTATION');
+
+  /**
+   * An end-of-line comment.
+   */
+  static const CommentType END_OF_LINE = const CommentType('END_OF_LINE');
+
+  /**
+   * The name of the comment type.
+   */
+  final String name;
+
+  /**
+   * Initialize a newly created comment type to have the given [name].
+   */
+  const CommentType(this.name);
+
+  @override
+  String toString() => name;
+}
+
+/**
+ * A compilation unit.
+ *
+ * While the grammar restricts the order of the directives and declarations
+ * within a compilation unit, this class does not enforce those restrictions.
+ * In particular, the children of a compilation unit will be visited in lexical
+ * order even if lexical order does not conform to the restrictions of the
+ * grammar.
+ *
+ * > compilationUnit ::=
+ * >     directives declarations
+ * >
+ * > directives ::=
+ * >     [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
+ * >   | [PartOfDirective]
+ * >
+ * > namespaceDirective ::=
+ * >     [ImportDirective]
+ * >   | [ExportDirective]
+ * >
+ * > declarations ::=
+ * >     [CompilationUnitMember]*
+ */
+class CompilationUnitImpl extends AstNodeImpl implements CompilationUnit {
+  /**
+   * The first token in the token stream that was parsed to form this
+   * compilation unit.
+   */
+  Token beginToken;
+
+  /**
+   * The script tag at the beginning of the compilation unit, or `null` if there
+   * is no script tag in this compilation unit.
+   */
+  ScriptTag _scriptTag;
+
+  /**
+   * The directives contained in this compilation unit.
+   */
+  NodeList<Directive> _directives;
+
+  /**
+   * The declarations contained in this compilation unit.
+   */
+  NodeList<CompilationUnitMember> _declarations;
+
+  /**
+   * The last token in the token stream that was parsed to form this compilation
+   * unit. This token should always have a type of [TokenType.EOF].
+   */
+  Token endToken;
+
+  /**
+   * The element associated with this compilation unit, or `null` if the AST
+   * structure has not been resolved.
+   */
+  CompilationUnitElement element;
+
+  /**
+   * The line information for this compilation unit.
+   */
+  LineInfo lineInfo;
+
+  /**
+   * Initialize a newly created compilation unit to have the given directives
+   * and declarations. The [scriptTag] can be `null` if there is no script tag
+   * in the compilation unit. The list of [directives] can be `null` if there
+   * are no directives in the compilation unit. The list of [declarations] can
+   * be `null` if there are no declarations in the compilation unit.
+   */
+  CompilationUnitImpl(
+      this.beginToken,
+      ScriptTag scriptTag,
+      List<Directive> directives,
+      List<CompilationUnitMember> declarations,
+      this.endToken) {
+    _scriptTag = _becomeParentOf(scriptTag);
+    _directives = new NodeList<Directive>(this, directives);
+    _declarations = new NodeList<CompilationUnitMember>(this, declarations);
+  }
+
+  @override
+  Iterable get childEntities {
+    ChildEntities result = new ChildEntities()..add(_scriptTag);
+    if (_directivesAreBeforeDeclarations) {
+      result..addAll(_directives)..addAll(_declarations);
+    } else {
+      result.addAll(sortedDirectivesAndDeclarations);
+    }
+    return result;
+  }
+
+  @override
+  NodeList<CompilationUnitMember> get declarations => _declarations;
+
+  @override
+  NodeList<Directive> get directives => _directives;
+
+  @override
+  int get length {
+    Token endToken = this.endToken;
+    if (endToken == null) {
+      return 0;
+    }
+    return endToken.offset + endToken.length;
+  }
+
+  @override
+  int get offset => 0;
+
+  @override
+  ScriptTag get scriptTag => _scriptTag;
+
+  @override
+  void set scriptTag(ScriptTag scriptTag) {
+    _scriptTag = _becomeParentOf(scriptTag);
+  }
+
+  @override
+  List<AstNode> get sortedDirectivesAndDeclarations {
+    return <AstNode>[]
+      ..addAll(_directives)
+      ..addAll(_declarations)
+      ..sort(AstNode.LEXICAL_ORDER);
+  }
+
+  /**
+   * Return `true` if all of the directives are lexically before any
+   * declarations.
+   */
+  bool get _directivesAreBeforeDeclarations {
+    if (_directives.isEmpty || _declarations.isEmpty) {
+      return true;
+    }
+    Directive lastDirective = _directives[_directives.length - 1];
+    CompilationUnitMember firstDeclaration = _declarations[0];
+    return lastDirective.offset < firstDeclaration.offset;
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitCompilationUnit(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_scriptTag, visitor);
+    if (_directivesAreBeforeDeclarations) {
+      _directives.accept(visitor);
+      _declarations.accept(visitor);
+    } else {
+      for (AstNode child in sortedDirectivesAndDeclarations) {
+        child.accept(visitor);
+      }
+    }
+  }
+}
+
+/**
+ * A node that declares one or more names within the scope of a compilation
+ * unit.
+ *
+ * > compilationUnitMember ::=
+ * >     [ClassDeclaration]
+ * >   | [TypeAlias]
+ * >   | [FunctionDeclaration]
+ * >   | [MethodDeclaration]
+ * >   | [VariableDeclaration]
+ * >   | [VariableDeclaration]
+ */
+abstract class CompilationUnitMemberImpl extends DeclarationImpl
+    implements CompilationUnitMember {
+  /**
+   * Initialize a newly created generic compilation unit member. Either or both
+   * of the [comment] and [metadata] can be `null` if the member does not have
+   * the corresponding attribute.
+   */
+  CompilationUnitMemberImpl(Comment comment, List<Annotation> metadata)
+      : super(comment, metadata);
+}
+
+/**
+ * A conditional expression.
+ *
+ * > conditionalExpression ::=
+ * >     [Expression] '?' [Expression] ':' [Expression]
+ */
+class ConditionalExpressionImpl extends ExpressionImpl
+    implements ConditionalExpression {
+  /**
+   * The condition used to determine which of the expressions is executed next.
+   */
+  Expression _condition;
+
+  /**
+   * The token used to separate the condition from the then expression.
+   */
+  Token question;
+
+  /**
+   * The expression that is executed if the condition evaluates to `true`.
+   */
+  Expression _thenExpression;
+
+  /**
+   * The token used to separate the then expression from the else expression.
+   */
+  Token colon;
+
+  /**
+   * The expression that is executed if the condition evaluates to `false`.
+   */
+  Expression _elseExpression;
+
+  /**
+   * Initialize a newly created conditional expression.
+   */
+  ConditionalExpressionImpl(Expression condition, this.question,
+      Expression thenExpression, this.colon, Expression elseExpression) {
+    _condition = _becomeParentOf(condition);
+    _thenExpression = _becomeParentOf(thenExpression);
+    _elseExpression = _becomeParentOf(elseExpression);
+  }
+
+  @override
+  Token get beginToken => _condition.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_condition)
+    ..add(question)
+    ..add(_thenExpression)
+    ..add(colon)
+    ..add(_elseExpression);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression);
+  }
+
+  @override
+  Expression get elseExpression => _elseExpression;
+
+  @override
+  void set elseExpression(Expression expression) {
+    _elseExpression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get endToken => _elseExpression.endToken;
+
+  @override
+  int get precedence => 3;
+
+  @override
+  Expression get thenExpression => _thenExpression;
+
+  @override
+  void set thenExpression(Expression expression) {
+    _thenExpression = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConditionalExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(_thenExpression, visitor);
+    _safelyVisitChild(_elseExpression, visitor);
+  }
+}
+
+/**
+ * A configuration in either an import or export directive.
+ *
+ *     configuration ::=
+ *         'if' '(' test ')' uri
+ *
+ *     test ::=
+ *         dottedName ('==' stringLiteral)?
+ *
+ *     dottedName ::=
+ *         identifier ('.' identifier)*
+ */
+class ConfigurationImpl extends AstNodeImpl implements Configuration {
+  Token ifKeyword;
+  Token leftParenthesis;
+  DottedName _name;
+  Token equalToken;
+  StringLiteral _value;
+  Token rightParenthesis;
+  StringLiteral _libraryUri;
+
+  ConfigurationImpl(
+      this.ifKeyword,
+      this.leftParenthesis,
+      DottedName name,
+      this.equalToken,
+      StringLiteral value,
+      this.rightParenthesis,
+      StringLiteral libraryUri) {
+    _name = _becomeParentOf(name);
+    _value = _becomeParentOf(value);
+    _libraryUri = _becomeParentOf(libraryUri);
+  }
+
+  @override
+  Token get beginToken => ifKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(ifKeyword)
+    ..add(leftParenthesis)
+    ..add(_name)
+    ..add(equalToken)
+    ..add(_value)
+    ..add(rightParenthesis)
+    ..add(_libraryUri);
+
+  @override
+  Token get endToken => _libraryUri.endToken;
+
+  @override
+  StringLiteral get libraryUri => _libraryUri;
+
+  @override
+  void set libraryUri(StringLiteral libraryUri) {
+    _libraryUri = _becomeParentOf(libraryUri);
+  }
+
+  @override
+  DottedName get name => _name;
+
+  @override
+  void set name(DottedName name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  StringLiteral get value => _value;
+
+  @override
+  void set value(StringLiteral value) {
+    _value = _becomeParentOf(value);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConfiguration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_value, visitor);
+    _safelyVisitChild(_libraryUri, visitor);
+  }
+}
+
+/**
+ * A constructor declaration.
+ *
+ * > constructorDeclaration ::=
+ * >     constructorSignature [FunctionBody]?
+ * >   | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments
+ * >
+ * > constructorSignature ::=
+ * >     'external'? constructorName formalParameterList initializerList?
+ * >   | 'external'? 'factory' factoryName formalParameterList initializerList?
+ * >   | 'external'? 'const'  constructorName formalParameterList initializerList?
+ * >
+ * > constructorName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])?
+ * >
+ * > factoryName ::=
+ * >     [Identifier] ('.' [SimpleIdentifier])?
+ * >
+ * > initializerList ::=
+ * >     ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
+ */
+class ConstructorDeclarationImpl extends ClassMemberImpl
+    implements ConstructorDeclaration {
+  /**
+   * The token for the 'external' keyword, or `null` if the constructor is not
+   * external.
+   */
+  Token externalKeyword;
+
+  /**
+   * The token for the 'const' keyword, or `null` if the constructor is not a
+   * const constructor.
+   */
+  Token constKeyword;
+
+  /**
+   * The token for the 'factory' keyword, or `null` if the constructor is not a
+   * factory constructor.
+   */
+  Token factoryKeyword;
+
+  /**
+   * The type of object being created. This can be different than the type in
+   * which the constructor is being declared if the constructor is the
+   * implementation of a factory constructor.
+   */
+  Identifier _returnType;
+
+  /**
+   * The token for the period before the constructor name, or `null` if the
+   * constructor being declared is unnamed.
+   */
+  Token period;
+
+  /**
+   * The name of the constructor, or `null` if the constructor being declared is
+   * unnamed.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * The parameters associated with the constructor.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * The token for the separator (colon or equals) before the initializer list
+   * or redirection, or `null` if there are no initializers.
+   */
+  Token separator;
+
+  /**
+   * The initializers associated with the constructor.
+   */
+  NodeList<ConstructorInitializer> _initializers;
+
+  /**
+   * The name of the constructor to which this constructor will be redirected,
+   * or `null` if this is not a redirecting factory constructor.
+   */
+  ConstructorName _redirectedConstructor;
+
+  /**
+   * The body of the constructor, or `null` if the constructor does not have a
+   * body.
+   */
+  FunctionBody _body;
+
+  /**
+   * The element associated with this constructor, or `null` if the AST
+   * structure has not been resolved or if this constructor could not be
+   * resolved.
+   */
+  ConstructorElement element;
+
+  /**
+   * Initialize a newly created constructor declaration. The [externalKeyword]
+   * can be `null` if the constructor is not external. Either or both of the
+   * [comment] and [metadata] can be `null` if the constructor does not have the
+   * corresponding attribute. The [constKeyword] can be `null` if the
+   * constructor cannot be used to create a constant. The [factoryKeyword] can
+   * be `null` if the constructor is not a factory. The [period] and [name] can
+   * both be `null` if the constructor is not a named constructor. The
+   * [separator] can be `null` if the constructor does not have any initializers
+   * and does not redirect to a different constructor. The list of
+   * [initializers] can be `null` if the constructor does not have any
+   * initializers. The [redirectedConstructor] can be `null` if the constructor
+   * does not redirect to a different constructor. The [body] can be `null` if
+   * the constructor does not have a body.
+   */
+  ConstructorDeclarationImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.externalKeyword,
+      this.constKeyword,
+      this.factoryKeyword,
+      Identifier returnType,
+      this.period,
+      SimpleIdentifier name,
+      FormalParameterList parameters,
+      this.separator,
+      List<ConstructorInitializer> initializers,
+      ConstructorName redirectedConstructor,
+      FunctionBody body)
+      : super(comment, metadata) {
+    _returnType = _becomeParentOf(returnType);
+    _name = _becomeParentOf(name);
+    _parameters = _becomeParentOf(parameters);
+    _initializers = new NodeList<ConstructorInitializer>(this, initializers);
+    _redirectedConstructor = _becomeParentOf(redirectedConstructor);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  FunctionBody get body => _body;
+
+  @override
+  void set body(FunctionBody functionBody) {
+    _body = _becomeParentOf(functionBody);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(externalKeyword)
+    ..add(constKeyword)
+    ..add(factoryKeyword)
+    ..add(_returnType)
+    ..add(period)
+    ..add(_name)
+    ..add(_parameters)
+    ..add(separator)
+    ..addAll(initializers)
+    ..add(_redirectedConstructor)
+    ..add(_body);
+
+  @override
+  Token get endToken {
+    if (_body != null) {
+      return _body.endToken;
+    } else if (!_initializers.isEmpty) {
+      return _initializers.endToken;
+    }
+    return _parameters.endToken;
+  }
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    Token leftMost =
+        Token.lexicallyFirst([externalKeyword, constKeyword, factoryKeyword]);
+    if (leftMost != null) {
+      return leftMost;
+    }
+    return _returnType.beginToken;
+  }
+
+  @override
+  NodeList<ConstructorInitializer> get initializers => _initializers;
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  ConstructorName get redirectedConstructor => _redirectedConstructor;
+
+  @override
+  void set redirectedConstructor(ConstructorName redirectedConstructor) {
+    _redirectedConstructor = _becomeParentOf(redirectedConstructor);
+  }
+
+  @override
+  Identifier get returnType => _returnType;
+
+  @override
+  void set returnType(Identifier typeName) {
+    _returnType = _becomeParentOf(typeName);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConstructorDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_returnType, visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_parameters, visitor);
+    _initializers.accept(visitor);
+    _safelyVisitChild(_redirectedConstructor, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * The initialization of a field within a constructor's initialization list.
+ *
+ * > fieldInitializer ::=
+ * >     ('this' '.')? [SimpleIdentifier] '=' [Expression]
+ */
+class ConstructorFieldInitializerImpl extends ConstructorInitializerImpl
+    implements ConstructorFieldInitializer {
+  /**
+   * The token for the 'this' keyword, or `null` if there is no 'this' keyword.
+   */
+  Token thisKeyword;
+
+  /**
+   * The token for the period after the 'this' keyword, or `null` if there is no
+   * 'this' keyword.
+   */
+  Token period;
+
+  /**
+   * The name of the field being initialized.
+   */
+  SimpleIdentifier _fieldName;
+
+  /**
+   * The token for the equal sign between the field name and the expression.
+   */
+  Token equals;
+
+  /**
+   * The expression computing the value to which the field will be initialized.
+   */
+  Expression _expression;
+
+  /**
+   * Initialize a newly created field initializer to initialize the field with
+   * the given name to the value of the given expression. The [thisKeyword] and
+   * [period] can be `null` if the 'this' keyword was not specified.
+   */
+  ConstructorFieldInitializerImpl(this.thisKeyword, this.period,
+      SimpleIdentifier fieldName, this.equals, Expression expression) {
+    _fieldName = _becomeParentOf(fieldName);
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken {
+    if (thisKeyword != null) {
+      return thisKeyword;
+    }
+    return _fieldName.beginToken;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(thisKeyword)
+    ..add(period)
+    ..add(_fieldName)
+    ..add(equals)
+    ..add(_expression);
+
+  @override
+  Token get endToken => _expression.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  SimpleIdentifier get fieldName => _fieldName;
+
+  @override
+  void set fieldName(SimpleIdentifier identifier) {
+    _fieldName = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_fieldName, visitor);
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A node that can occur in the initializer list of a constructor declaration.
+ *
+ * > constructorInitializer ::=
+ * >     [SuperConstructorInvocation]
+ * >   | [ConstructorFieldInitializer]
+ * >   | [RedirectingConstructorInvocation]
+ */
+abstract class ConstructorInitializerImpl extends AstNodeImpl
+    implements ConstructorInitializer {}
+
+/**
+ * The name of the constructor.
+ *
+ * > constructorName ::=
+ * >     type ('.' identifier)?
+ */
+class ConstructorNameImpl extends AstNodeImpl implements ConstructorName {
+  /**
+   * The name of the type defining the constructor.
+   */
+  TypeName _type;
+
+  /**
+   * The token for the period before the constructor name, or `null` if the
+   * specified constructor is the unnamed constructor.
+   */
+  Token period;
+
+  /**
+   * The name of the constructor, or `null` if the specified constructor is the
+   * unnamed constructor.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * The element associated with this constructor name based on static type
+   * information, or `null` if the AST structure has not been resolved or if
+   * this constructor name could not be resolved.
+   */
+  ConstructorElement staticElement;
+
+  /**
+   * Initialize a newly created constructor name. The [period] and [name] can be
+   * `null` if the constructor being named is the unnamed constructor.
+   */
+  ConstructorNameImpl(TypeName type, this.period, SimpleIdentifier name) {
+    _type = _becomeParentOf(type);
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  Token get beginToken => _type.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_type)..add(period)..add(_name);
+
+  @override
+  Token get endToken {
+    if (_name != null) {
+      return _name.endToken;
+    }
+    return _type.endToken;
+  }
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName type) {
+    _type = _becomeParentOf(type);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConstructorName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_type, visitor);
+    _safelyVisitChild(_name, visitor);
+  }
+}
+
+/**
+ * A continue statement.
+ *
+ * > continueStatement ::=
+ * >     'continue' [SimpleIdentifier]? ';'
+ */
+class ContinueStatementImpl extends StatementImpl implements ContinueStatement {
+  /**
+   * The token representing the 'continue' keyword.
+   */
+  Token continueKeyword;
+
+  /**
+   * The label associated with the statement, or `null` if there is no label.
+   */
+  SimpleIdentifier _label;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * The AstNode which this continue statement is continuing to.  This will be
+   * either a Statement (in the case of continuing a loop) or a SwitchMember
+   * (in the case of continuing from one switch case to another).  Null if the
+   * AST has not yet been resolved or if the target could not be resolved.
+   * Note that if the source code has errors, the target may be invalid (e.g.
+   * the target may be in an enclosing function).
+   */
+  AstNode target;
+
+  /**
+   * Initialize a newly created continue statement. The [label] can be `null` if
+   * there is no label associated with the statement.
+   */
+  ContinueStatementImpl(
+      this.continueKeyword, SimpleIdentifier label, this.semicolon) {
+    _label = _becomeParentOf(label);
+  }
+
+  @override
+  Token get beginToken => continueKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(continueKeyword)..add(_label)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  SimpleIdentifier get label => _label;
+
+  @override
+  void set label(SimpleIdentifier identifier) {
+    _label = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitContinueStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_label, visitor);
+  }
+}
+
+/**
+ * A node that represents the declaration of one or more names. Each declared
+ * name is visible within a name scope.
+ */
+abstract class DeclarationImpl extends AnnotatedNodeImpl
+    implements Declaration {
+  /**
+   * Initialize a newly created declaration. Either or both of the [comment] and
+   * [metadata] can be `null` if the declaration does not have the corresponding
+   * attribute.
+   */
+  DeclarationImpl(Comment comment, List<Annotation> metadata)
+      : super(comment, metadata);
+}
+
+/**
+ * The declaration of a single identifier.
+ *
+ * > declaredIdentifier ::=
+ * >     [Annotation] finalConstVarOrType [SimpleIdentifier]
+ */
+class DeclaredIdentifierImpl extends DeclarationImpl
+    implements DeclaredIdentifier {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or
+   * `null` if no keyword was used.
+   */
+  Token keyword;
+
+  /**
+   * The name of the declared type of the parameter, or `null` if the parameter
+   * does not have a declared type.
+   */
+  TypeName _type;
+
+  /**
+   * The name of the variable being declared.
+   */
+  SimpleIdentifier _identifier;
+
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type name is
+   * given. The [type] must be `null` if the keyword is 'var'.
+   */
+  DeclaredIdentifierImpl(Comment comment, List<Annotation> metadata,
+      this.keyword, TypeName type, SimpleIdentifier identifier)
+      : super(comment, metadata) {
+    _type = _becomeParentOf(type);
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(keyword)..add(_type)..add(_identifier);
+
+  @override
+  LocalVariableElement get element {
+    if (_identifier == null) {
+      return null;
+    }
+    return _identifier.staticElement as LocalVariableElement;
+  }
+
+  @override
+  Token get endToken => _identifier.endToken;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (keyword != null) {
+      return keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return _identifier.beginToken;
+  }
+
+  @override
+  SimpleIdentifier get identifier => _identifier;
+
+  @override
+  void set identifier(SimpleIdentifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  bool get isConst =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.CONST;
+
+  @override
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.FINAL;
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName typeName) {
+    _type = _becomeParentOf(typeName);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDeclaredIdentifier(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_type, visitor);
+    _safelyVisitChild(_identifier, visitor);
+  }
+}
+
+/**
+ * A formal parameter with a default value. There are two kinds of parameters
+ * that are both represented by this class: named formal parameters and
+ * positional formal parameters.
+ *
+ * > defaultFormalParameter ::=
+ * >     [NormalFormalParameter] ('=' [Expression])?
+ * >
+ * > defaultNamedParameter ::=
+ * >     [NormalFormalParameter] (':' [Expression])?
+ */
+class DefaultFormalParameterImpl extends FormalParameterImpl
+    implements DefaultFormalParameter {
+  /**
+   * The formal parameter with which the default value is associated.
+   */
+  NormalFormalParameter _parameter;
+
+  /**
+   * The kind of this parameter.
+   */
+  ParameterKind kind;
+
+  /**
+   * The token separating the parameter from the default value, or `null` if
+   * there is no default value.
+   */
+  Token separator;
+
+  /**
+   * The expression computing the default value for the parameter, or `null` if
+   * there is no default value.
+   */
+  Expression _defaultValue;
+
+  /**
+   * Initialize a newly created default formal parameter. The [separator] and
+   * [defaultValue] can be `null` if there is no default value.
+   */
+  DefaultFormalParameterImpl(NormalFormalParameter parameter, this.kind,
+      this.separator, Expression defaultValue) {
+    _parameter = _becomeParentOf(parameter);
+    _defaultValue = _becomeParentOf(defaultValue);
+  }
+
+  @override
+  Token get beginToken => _parameter.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_parameter)..add(separator)..add(_defaultValue);
+
+  @override
+  Expression get defaultValue => _defaultValue;
+
+  @override
+  void set defaultValue(Expression expression) {
+    _defaultValue = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get endToken {
+    if (_defaultValue != null) {
+      return _defaultValue.endToken;
+    }
+    return _parameter.endToken;
+  }
+
+  @override
+  SimpleIdentifier get identifier => _parameter.identifier;
+
+  @override
+  bool get isConst => _parameter != null && _parameter.isConst;
+
+  @override
+  bool get isFinal => _parameter != null && _parameter.isFinal;
+
+  @override
+  NodeList<Annotation> get metadata => _parameter.metadata;
+
+  @override
+  NormalFormalParameter get parameter => _parameter;
+
+  @override
+  void set parameter(NormalFormalParameter formalParameter) {
+    _parameter = _becomeParentOf(formalParameter);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDefaultFormalParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_parameter, visitor);
+    _safelyVisitChild(_defaultValue, visitor);
+  }
+}
+
+/**
+ * A node that represents a directive.
+ *
+ * > directive ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ * >   | [LibraryDirective]
+ * >   | [PartDirective]
+ * >   | [PartOfDirective]
+ */
+abstract class DirectiveImpl extends AnnotatedNodeImpl implements Directive {
+  /**
+   * The element associated with this directive, or `null` if the AST structure
+   * has not been resolved or if this directive could not be resolved.
+   */
+  Element element;
+
+  /**
+   * Initialize a newly create directive. Either or both of the [comment] and
+   * [metadata] can be `null` if the directive does not have the corresponding
+   * attribute.
+   */
+  DirectiveImpl(Comment comment, List<Annotation> metadata)
+      : super(comment, metadata);
+}
+
+/**
+ * A do statement.
+ *
+ * > doStatement ::=
+ * >     'do' [Statement] 'while' '(' [Expression] ')' ';'
+ */
+class DoStatementImpl extends StatementImpl implements DoStatement {
+  /**
+   * The token representing the 'do' keyword.
+   */
+  Token doKeyword;
+
+  /**
+   * The body of the loop.
+   */
+  Statement _body;
+
+  /**
+   * The token representing the 'while' keyword.
+   */
+  Token whileKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The condition that determines when the loop will terminate.
+   */
+  Expression _condition;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created do loop.
+   */
+  DoStatementImpl(
+      this.doKeyword,
+      Statement body,
+      this.whileKeyword,
+      this.leftParenthesis,
+      Expression condition,
+      this.rightParenthesis,
+      this.semicolon) {
+    _body = _becomeParentOf(body);
+    _condition = _becomeParentOf(condition);
+  }
+
+  @override
+  Token get beginToken => doKeyword;
+
+  @override
+  Statement get body => _body;
+
+  @override
+  void set body(Statement statement) {
+    _body = _becomeParentOf(statement);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(doKeyword)
+    ..add(_body)
+    ..add(whileKeyword)
+    ..add(leftParenthesis)
+    ..add(_condition)
+    ..add(rightParenthesis)
+    ..add(semicolon);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDoStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_body, visitor);
+    _safelyVisitChild(_condition, visitor);
+  }
+}
+
+/**
+ * A dotted name, used in a configuration within an import or export directive.
+ *
+ * > dottedName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ */
+class DottedNameImpl extends AstNodeImpl implements DottedName {
+  /**
+   * The components of the identifier.
+   */
+  NodeList<SimpleIdentifier> _components;
+
+  /**
+   * Initialize a newly created dotted name.
+   */
+  DottedNameImpl(List<SimpleIdentifier> components) {
+    _components = new NodeList<SimpleIdentifier>(this, components);
+  }
+
+  @override
+  Token get beginToken => _components.beginToken;
+
+  @override
+  // TODO(paulberry): add "." tokens.
+  Iterable get childEntities => new ChildEntities()..addAll(_components);
+
+  @override
+  NodeList<SimpleIdentifier> get components => _components;
+
+  @override
+  Token get endToken => _components.endToken;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDottedName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _components.accept(visitor);
+  }
+}
+
+/**
+ * A floating point literal expression.
+ *
+ * > doubleLiteral ::=
+ * >     decimalDigit+ ('.' decimalDigit*)? exponent?
+ * >   | '.' decimalDigit+ exponent?
+ * >
+ * > exponent ::=
+ * >     ('e' | 'E') ('+' | '-')? decimalDigit+
+ */
+class DoubleLiteralImpl extends LiteralImpl implements DoubleLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token literal;
+
+  /**
+   * The value of the literal.
+   */
+  double value;
+
+  /**
+   * Initialize a newly created floating point literal.
+   */
+  DoubleLiteralImpl(this.literal, this.value);
+
+  @override
+  Token get beginToken => literal;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(literal);
+
+  @override
+  Token get endToken => literal;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDoubleLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * An empty function body, which can only appear in constructors or abstract
+ * methods.
+ *
+ * > emptyFunctionBody ::=
+ * >     ';'
+ */
+class EmptyFunctionBodyImpl extends FunctionBodyImpl
+    implements EmptyFunctionBody {
+  /**
+   * The token representing the semicolon that marks the end of the function
+   * body.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created function body.
+   */
+  EmptyFunctionBodyImpl(this.semicolon);
+
+  @override
+  Token get beginToken => semicolon;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitEmptyFunctionBody(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // Empty function bodies have no children.
+  }
+}
+
+/**
+ * An empty statement.
+ *
+ * > emptyStatement ::=
+ * >     ';'
+ */
+class EmptyStatementImpl extends StatementImpl implements EmptyStatement {
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created empty statement.
+   */
+  EmptyStatementImpl(this.semicolon);
+
+  @override
+  Token get beginToken => semicolon;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitEmptyStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * The declaration of an enum constant.
+ */
+class EnumConstantDeclarationImpl extends DeclarationImpl
+    implements EnumConstantDeclaration {
+  /**
+   * The name of the constant.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * Initialize a newly created enum constant declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the constant does not have the
+   * corresponding attribute. (Technically, enum constants cannot have metadata,
+   * but we allow it for consistency.)
+   */
+  EnumConstantDeclarationImpl(
+      Comment comment, List<Annotation> metadata, SimpleIdentifier name)
+      : super(comment, metadata) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities..add(_name);
+
+  @override
+  FieldElement get element =>
+      _name == null ? null : (_name.staticElement as FieldElement);
+
+  @override
+  Token get endToken => _name.endToken;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitEnumConstantDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+  }
+}
+
+/**
+ * The declaration of an enumeration.
+ *
+ * > enumType ::=
+ * >     metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
+ */
+class EnumDeclarationImpl extends NamedCompilationUnitMemberImpl
+    implements EnumDeclaration {
+  /**
+   * The 'enum' keyword.
+   */
+  Token enumKeyword;
+
+  /**
+   * The left curly bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The enumeration constants being declared.
+   */
+  NodeList<EnumConstantDeclaration> _constants;
+
+  /**
+   * The right curly bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created enumeration declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The list of [constants] must contain at least one
+   * value.
+   */
+  EnumDeclarationImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.enumKeyword,
+      SimpleIdentifier name,
+      this.leftBracket,
+      List<EnumConstantDeclaration> constants,
+      this.rightBracket)
+      : super(comment, metadata, name) {
+    _constants = new NodeList<EnumConstantDeclaration>(this, constants);
+  }
+
+  @override
+  // TODO(brianwilkerson) Add commas?
+  Iterable get childEntities => super._childEntities
+    ..add(enumKeyword)
+    ..add(_name)
+    ..add(leftBracket)
+    ..addAll(_constants)
+    ..add(rightBracket);
+
+  @override
+  NodeList<EnumConstantDeclaration> get constants => _constants;
+
+  @override
+  ClassElement get element =>
+      _name != null ? (_name.staticElement as ClassElement) : null;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => enumKeyword;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+    _constants.accept(visitor);
+  }
+}
+
+/**
+ * Ephemeral identifiers are created as needed to mimic the presence of an empty
+ * identifier.
+ */
+class EphemeralIdentifier extends SimpleIdentifierImpl {
+  EphemeralIdentifier(AstNode parent, int location)
+      : super(new StringToken(TokenType.IDENTIFIER, "", location)) {
+    (parent as AstNodeImpl)._becomeParentOf(this);
+  }
+}
+
+/**
+ * An export directive.
+ *
+ * > exportDirective ::=
+ * >     [Annotation] 'export' [StringLiteral] [Combinator]* ';'
+ */
+class ExportDirectiveImpl extends NamespaceDirectiveImpl
+    implements ExportDirective {
+  /**
+   * Initialize a newly created export directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  ExportDirectiveImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      Token semicolon)
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon);
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(_uri)
+    ..addAll(combinators)
+    ..add(semicolon);
+
+  @override
+  ExportElement get element => super.element as ExportElement;
+
+  @override
+  LibraryElement get uriElement {
+    if (element != null) {
+      return element.exportedLibrary;
+    }
+    return null;
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitExportDirective(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    combinators.accept(visitor);
+  }
+}
+
+/**
+ * A function body consisting of a single expression.
+ *
+ * > expressionFunctionBody ::=
+ * >     'async'? '=>' [Expression] ';'
+ */
+class ExpressionFunctionBodyImpl extends FunctionBodyImpl
+    implements ExpressionFunctionBody {
+  /**
+   * The token representing the 'async' keyword, or `null` if there is no such
+   * keyword.
+   */
+  Token keyword;
+
+  /**
+   * The token introducing the expression that represents the body of the
+   * function.
+   */
+  Token functionDefinition;
+
+  /**
+   * The expression representing the body of the function.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created function body consisting of a block of
+   * statements. The [keyword] can be `null` if the function body is not an
+   * async function body.
+   */
+  ExpressionFunctionBodyImpl(this.keyword, this.functionDefinition,
+      Expression expression, this.semicolon) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken {
+    if (keyword != null) {
+      return keyword;
+    }
+    return functionDefinition;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(keyword)
+    ..add(functionDefinition)
+    ..add(_expression)
+    ..add(semicolon);
+
+  @override
+  Token get endToken {
+    if (semicolon != null) {
+      return semicolon;
+    }
+    return _expression.endToken;
+  }
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  bool get isAsynchronous => keyword != null;
+
+  @override
+  bool get isSynchronous => keyword == null;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitExpressionFunctionBody(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A node that represents an expression.
+ *
+ * > expression ::=
+ * >     [AssignmentExpression]
+ * >   | [ConditionalExpression] cascadeSection*
+ * >   | [ThrowExpression]
+ */
+abstract class ExpressionImpl extends AstNodeImpl implements Expression {
+  /**
+   * The static type of this expression, or `null` if the AST structure has not
+   * been resolved.
+   */
+  DartType staticType;
+
+  /**
+   * The propagated type of this expression, or `null` if type propagation has
+   * not been performed on the AST structure.
+   */
+  DartType propagatedType;
+
+  /**
+   * Return the best parameter element information available for this
+   * expression. If type propagation was able to find a better parameter element
+   * than static analysis, that type will be returned. Otherwise, the result of
+   * static analysis will be returned.
+   */
+  ParameterElement get bestParameterElement {
+    ParameterElement propagatedElement = propagatedParameterElement;
+    if (propagatedElement != null) {
+      return propagatedElement;
+    }
+    return staticParameterElement;
+  }
+
+  @override
+  DartType get bestType {
+    if (propagatedType != null) {
+      return propagatedType;
+    } else if (staticType != null) {
+      return staticType;
+    }
+    return DynamicTypeImpl.instance;
+  }
+
+  @override
+  bool get isAssignable => false;
+
+  @override
+  ParameterElement get propagatedParameterElement {
+    AstNode parent = this.parent;
+    if (parent is ArgumentListImpl) {
+      return parent._getPropagatedParameterElementFor(this);
+    } else if (parent is IndexExpressionImpl) {
+      if (identical(parent.index, this)) {
+        return parent._propagatedParameterElementForIndex;
+      }
+    } else if (parent is BinaryExpressionImpl) {
+      if (identical(parent.rightOperand, this)) {
+        return parent._propagatedParameterElementForRightOperand;
+      }
+    } else if (parent is AssignmentExpressionImpl) {
+      if (identical(parent.rightHandSide, this)) {
+        return parent._propagatedParameterElementForRightHandSide;
+      }
+    } else if (parent is PrefixExpressionImpl) {
+      return parent._propagatedParameterElementForOperand;
+    } else if (parent is PostfixExpressionImpl) {
+      return parent._propagatedParameterElementForOperand;
+    }
+    return null;
+  }
+
+  @override
+  ParameterElement get staticParameterElement {
+    AstNode parent = this.parent;
+    if (parent is ArgumentListImpl) {
+      return parent._getStaticParameterElementFor(this);
+    } else if (parent is IndexExpressionImpl) {
+      if (identical(parent.index, this)) {
+        return parent._staticParameterElementForIndex;
+      }
+    } else if (parent is BinaryExpressionImpl) {
+      if (identical(parent.rightOperand, this)) {
+        return parent._staticParameterElementForRightOperand;
+      }
+    } else if (parent is AssignmentExpressionImpl) {
+      if (identical(parent.rightHandSide, this)) {
+        return parent._staticParameterElementForRightHandSide;
+      }
+    } else if (parent is PrefixExpressionImpl) {
+      return parent._staticParameterElementForOperand;
+    } else if (parent is PostfixExpressionImpl) {
+      return parent._staticParameterElementForOperand;
+    }
+    return null;
+  }
+}
+
+/**
+ * An expression used as a statement.
+ *
+ * > expressionStatement ::=
+ * >     [Expression]? ';'
+ */
+class ExpressionStatementImpl extends StatementImpl
+    implements ExpressionStatement {
+  /**
+   * The expression that comprises the statement.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon terminating the statement, or `null` if the expression is a
+   * function expression and therefore isn't followed by a semicolon.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created expression statement.
+   */
+  ExpressionStatementImpl(Expression expression, this.semicolon) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => _expression.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_expression)..add(semicolon);
+
+  @override
+  Token get endToken {
+    if (semicolon != null) {
+      return semicolon;
+    }
+    return _expression.endToken;
+  }
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  bool get isSynthetic => _expression.isSynthetic && semicolon.isSynthetic;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitExpressionStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * The "extends" clause in a class declaration.
+ *
+ * > extendsClause ::=
+ * >     'extends' [TypeName]
+ */
+class ExtendsClauseImpl extends AstNodeImpl implements ExtendsClause {
+  /**
+   * The token representing the 'extends' keyword.
+   */
+  Token extendsKeyword;
+
+  /**
+   * The name of the class that is being extended.
+   */
+  TypeName _superclass;
+
+  /**
+   * Initialize a newly created extends clause.
+   */
+  ExtendsClauseImpl(this.extendsKeyword, TypeName superclass) {
+    _superclass = _becomeParentOf(superclass);
+  }
+
+  @override
+  Token get beginToken => extendsKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(extendsKeyword)..add(_superclass);
+
+  @override
+  Token get endToken => _superclass.endToken;
+
+  @override
+  TypeName get superclass => _superclass;
+
+  @override
+  void set superclass(TypeName name) {
+    _superclass = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitExtendsClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_superclass, visitor);
+  }
+}
+
+/**
+ * The declaration of one or more fields of the same type.
+ *
+ * > fieldDeclaration ::=
+ * >     'static'? [VariableDeclarationList] ';'
+ */
+class FieldDeclarationImpl extends ClassMemberImpl implements FieldDeclaration {
+  /**
+   * The token representing the 'static' keyword, or `null` if the fields are
+   * not static.
+   */
+  Token staticKeyword;
+
+  /**
+   * The fields being declared.
+   */
+  VariableDeclarationList _fieldList;
+
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created field declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [staticKeyword] can be `null` if the field is
+   * not a static field.
+   */
+  FieldDeclarationImpl(Comment comment, List<Annotation> metadata,
+      this.staticKeyword, VariableDeclarationList fieldList, this.semicolon)
+      : super(comment, metadata) {
+    _fieldList = _becomeParentOf(fieldList);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(staticKeyword)..add(_fieldList)..add(semicolon);
+
+  @override
+  Element get element => null;
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  VariableDeclarationList get fields => _fieldList;
+
+  @override
+  void set fields(VariableDeclarationList fields) {
+    _fieldList = _becomeParentOf(fields);
+  }
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (staticKeyword != null) {
+      return staticKeyword;
+    }
+    return _fieldList.beginToken;
+  }
+
+  @override
+  bool get isStatic => staticKeyword != null;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFieldDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_fieldList, visitor);
+  }
+}
+
+/**
+ * A field formal parameter.
+ *
+ * > fieldFormalParameter ::=
+ * >     ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
+ * >     'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
+ */
+class FieldFormalParameterImpl extends NormalFormalParameterImpl
+    implements FieldFormalParameter {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or
+   * `null` if no keyword was used.
+   */
+  Token keyword;
+
+  /**
+   * The name of the declared type of the parameter, or `null` if the parameter
+   * does not have a declared type.
+   */
+  TypeName _type;
+
+  /**
+   * The token representing the 'this' keyword.
+   */
+  Token thisKeyword;
+
+  /**
+   * The token representing the period.
+   */
+  Token period;
+
+  /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The parameters of the function-typed parameter, or `null` if this is not a
+   * function-typed field formal parameter.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if there is a type.
+   * The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
+   * [period] can be `null` if the keyword 'this' was not provided.  The
+   * [parameters] can be `null` if this is not a function-typed field formal
+   * parameter.
+   */
+  FieldFormalParameterImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.keyword,
+      TypeName type,
+      this.thisKeyword,
+      this.period,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters)
+      : super(comment, metadata, identifier) {
+    _type = _becomeParentOf(type);
+    _typeParameters = _becomeParentOf(typeParameters);
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  Token get beginToken {
+    if (keyword != null) {
+      return keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return thisKeyword;
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(keyword)
+    ..add(_type)
+    ..add(thisKeyword)
+    ..add(period)
+    ..add(identifier)
+    ..add(_parameters);
+
+  @override
+  Token get endToken {
+    if (_parameters != null) {
+      return _parameters.endToken;
+    }
+    return identifier.endToken;
+  }
+
+  @override
+  bool get isConst =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.CONST;
+
+  @override
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.FINAL;
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName typeName) {
+    _type = _becomeParentOf(typeName);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFieldFormalParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_type, visitor);
+    _safelyVisitChild(identifier, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_parameters, visitor);
+  }
+}
+
+/**
+ * A for-each statement.
+ *
+ * > forEachStatement ::=
+ * >     'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
+ * >   | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
+ */
+class ForEachStatementImpl extends StatementImpl implements ForEachStatement {
+  /**
+   * The token representing the 'await' keyword, or `null` if there is no
+   * 'await' keyword.
+   */
+  Token awaitKeyword;
+
+  /**
+   * The token representing the 'for' keyword.
+   */
+  Token forKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The declaration of the loop variable, or `null` if the loop variable is a
+   * simple identifier.
+   */
+  DeclaredIdentifier _loopVariable;
+
+  /**
+   * The loop variable, or `null` if the loop variable is declared in the 'for'.
+   */
+  SimpleIdentifier _identifier;
+
+  /**
+   * The token representing the 'in' keyword.
+   */
+  Token inKeyword;
+
+  /**
+   * The expression evaluated to produce the iterator.
+   */
+  Expression _iterable;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The body of the loop.
+   */
+  Statement _body;
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared internally (in the for-loop part). The [awaitKeyword] can be
+   * `null` if this is not an asynchronous for loop.
+   */
+  ForEachStatementImpl.withDeclaration(
+      this.awaitKeyword,
+      this.forKeyword,
+      this.leftParenthesis,
+      DeclaredIdentifier loopVariable,
+      this.inKeyword,
+      Expression iterator,
+      this.rightParenthesis,
+      Statement body) {
+    _loopVariable = _becomeParentOf(loopVariable);
+    _iterable = _becomeParentOf(iterator);
+    _body = _becomeParentOf(body);
+  }
+
+  /**
+   * Initialize a newly created for-each statement whose loop control variable
+   * is declared outside the for loop. The [awaitKeyword] can be `null` if this
+   * is not an asynchronous for loop.
+   */
+  ForEachStatementImpl.withReference(
+      this.awaitKeyword,
+      this.forKeyword,
+      this.leftParenthesis,
+      SimpleIdentifier identifier,
+      this.inKeyword,
+      Expression iterator,
+      this.rightParenthesis,
+      Statement body) {
+    _identifier = _becomeParentOf(identifier);
+    _iterable = _becomeParentOf(iterator);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Token get beginToken => forKeyword;
+
+  @override
+  Statement get body => _body;
+
+  @override
+  void set body(Statement statement) {
+    _body = _becomeParentOf(statement);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(awaitKeyword)
+    ..add(forKeyword)
+    ..add(leftParenthesis)
+    ..add(_loopVariable)
+    ..add(_identifier)
+    ..add(inKeyword)
+    ..add(_iterable)
+    ..add(rightParenthesis)
+    ..add(_body);
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  SimpleIdentifier get identifier => _identifier;
+
+  @override
+  void set identifier(SimpleIdentifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Expression get iterable => _iterable;
+
+  @override
+  void set iterable(Expression expression) {
+    _iterable = _becomeParentOf(expression);
+  }
+
+  @override
+  DeclaredIdentifier get loopVariable => _loopVariable;
+
+  @override
+  void set loopVariable(DeclaredIdentifier variable) {
+    _loopVariable = _becomeParentOf(variable);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitForEachStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_loopVariable, visitor);
+    _safelyVisitChild(_identifier, visitor);
+    _safelyVisitChild(_iterable, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * A node representing a parameter to a function.
+ *
+ * > formalParameter ::=
+ * >     [NormalFormalParameter]
+ * >   | [DefaultFormalParameter]
+ */
+abstract class FormalParameterImpl extends AstNodeImpl
+    implements FormalParameter {
+  @override
+  ParameterElement get element {
+    SimpleIdentifier identifier = this.identifier;
+    if (identifier == null) {
+      return null;
+    }
+    return identifier.staticElement as ParameterElement;
+  }
+}
+
+/**
+ * The formal parameter list of a method declaration, function declaration, or
+ * function type alias.
+ *
+ * While the grammar requires all optional formal parameters to follow all of
+ * the normal formal parameters and at most one grouping of optional formal
+ * parameters, this class does not enforce those constraints. All parameters are
+ * flattened into a single list, which can have any or all kinds of parameters
+ * (normal, named, and positional) in any order.
+ *
+ * > formalParameterList ::=
+ * >     '(' ')'
+ * >   | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+ * >   | '(' optionalFormalParameters ')'
+ * >
+ * > normalFormalParameters ::=
+ * >     [NormalFormalParameter] (',' [NormalFormalParameter])*
+ * >
+ * > optionalFormalParameters ::=
+ * >     optionalPositionalFormalParameters
+ * >   | namedFormalParameters
+ * >
+ * > optionalPositionalFormalParameters ::=
+ * >     '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
+ * >
+ * > namedFormalParameters ::=
+ * >     '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
+ */
+class FormalParameterListImpl extends AstNodeImpl
+    implements FormalParameterList {
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The parameters associated with the method.
+   */
+  NodeList<FormalParameter> _parameters;
+
+  /**
+   * The left square bracket ('[') or left curly brace ('{') introducing the
+   * optional parameters, or `null` if there are no optional parameters.
+   */
+  Token leftDelimiter;
+
+  /**
+   * The right square bracket (']') or right curly brace ('}') terminating the
+   * optional parameters, or `null` if there are no optional parameters.
+   */
+  Token rightDelimiter;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * Initialize a newly created parameter list. The list of [parameters] can be
+   * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
+   * can be `null` if there are no optional parameters.
+   */
+  FormalParameterListImpl(
+      this.leftParenthesis,
+      List<FormalParameter> parameters,
+      this.leftDelimiter,
+      this.rightDelimiter,
+      this.rightParenthesis) {
+    _parameters = new NodeList<FormalParameter>(this, parameters);
+  }
+
+  @override
+  Token get beginToken => leftParenthesis;
+
+  @override
+  Iterable get childEntities {
+    // TODO(paulberry): include commas.
+    ChildEntities result = new ChildEntities()..add(leftParenthesis);
+    bool leftDelimiterNeeded = leftDelimiter != null;
+    for (FormalParameter parameter in _parameters) {
+      if (leftDelimiterNeeded && leftDelimiter.offset < parameter.offset) {
+        result.add(leftDelimiter);
+        leftDelimiterNeeded = false;
+      }
+      result.add(parameter);
+    }
+    return result..add(rightDelimiter)..add(rightParenthesis);
+  }
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  List<ParameterElement> get parameterElements {
+    int count = _parameters.length;
+    List<ParameterElement> types = new List<ParameterElement>(count);
+    for (int i = 0; i < count; i++) {
+      types[i] = _parameters[i].element;
+    }
+    return types;
+  }
+
+  @override
+  NodeList<FormalParameter> get parameters => _parameters;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFormalParameterList(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _parameters.accept(visitor);
+  }
+}
+
+/**
+ * A for statement.
+ *
+ * > forStatement ::=
+ * >     'for' '(' forLoopParts ')' [Statement]
+ * >
+ * > forLoopParts ::=
+ * >     forInitializerStatement ';' [Expression]? ';' [Expression]?
+ * >
+ * > forInitializerStatement ::=
+ * >     [DefaultFormalParameter]
+ * >   | [Expression]?
+ */
+class ForStatementImpl extends StatementImpl implements ForStatement {
+  /**
+   * The token representing the 'for' keyword.
+   */
+  Token forKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The declaration of the loop variables, or `null` if there are no variables.
+   * Note that a for statement cannot have both a variable list and an
+   * initialization expression, but can validly have neither.
+   */
+  VariableDeclarationList _variableList;
+
+  /**
+   * The initialization expression, or `null` if there is no initialization
+   * expression. Note that a for statement cannot have both a variable list and
+   * an initialization expression, but can validly have neither.
+   */
+  Expression _initialization;
+
+  /**
+   * The semicolon separating the initializer and the condition.
+   */
+  Token leftSeparator;
+
+  /**
+   * The condition used to determine when to terminate the loop, or `null` if
+   * there is no condition.
+   */
+  Expression _condition;
+
+  /**
+   * The semicolon separating the condition and the updater.
+   */
+  Token rightSeparator;
+
+  /**
+   * The list of expressions run after each execution of the loop body.
+   */
+  NodeList<Expression> _updaters;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The body of the loop.
+   */
+  Statement _body;
+
+  /**
+   * Initialize a newly created for statement. Either the [variableList] or the
+   * [initialization] must be `null`. Either the [condition] and the list of
+   * [updaters] can be `null` if the loop does not have the corresponding
+   * attribute.
+   */
+  ForStatementImpl(
+      this.forKeyword,
+      this.leftParenthesis,
+      VariableDeclarationList variableList,
+      Expression initialization,
+      this.leftSeparator,
+      Expression condition,
+      this.rightSeparator,
+      List<Expression> updaters,
+      this.rightParenthesis,
+      Statement body) {
+    _variableList = _becomeParentOf(variableList);
+    _initialization = _becomeParentOf(initialization);
+    _condition = _becomeParentOf(condition);
+    _updaters = new NodeList<Expression>(this, updaters);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Token get beginToken => forKeyword;
+
+  @override
+  Statement get body => _body;
+
+  @override
+  void set body(Statement statement) {
+    _body = _becomeParentOf(statement);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(forKeyword)
+    ..add(leftParenthesis)
+    ..add(_variableList)
+    ..add(_initialization)
+    ..add(leftSeparator)
+    ..add(_condition)
+    ..add(rightSeparator)
+    ..addAll(_updaters)
+    ..add(rightParenthesis)
+    ..add(_body);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  Expression get initialization => _initialization;
+
+  @override
+  void set initialization(Expression initialization) {
+    _initialization = _becomeParentOf(initialization);
+  }
+
+  @override
+  NodeList<Expression> get updaters => _updaters;
+
+  @override
+  VariableDeclarationList get variables => _variableList;
+
+  @override
+  void set variables(VariableDeclarationList variableList) {
+    _variableList = _becomeParentOf(variableList);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitForStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_variableList, visitor);
+    _safelyVisitChild(_initialization, visitor);
+    _safelyVisitChild(_condition, visitor);
+    _updaters.accept(visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * A node representing the body of a function or method.
+ *
+ * > functionBody ::=
+ * >     [BlockFunctionBody]
+ * >   | [EmptyFunctionBody]
+ * >   | [ExpressionFunctionBody]
+ */
+abstract class FunctionBodyImpl extends AstNodeImpl implements FunctionBody {
+  /**
+   * Return `true` if this function body is asynchronous.
+   */
+  bool get isAsynchronous => false;
+
+  /**
+   * Return `true` if this function body is a generator.
+   */
+  bool get isGenerator => false;
+
+  /**
+   * Return `true` if this function body is synchronous.
+   */
+  bool get isSynchronous => true;
+
+  /**
+   * Return the token representing the 'async' or 'sync' keyword, or `null` if
+   * there is no such keyword.
+   */
+  Token get keyword => null;
+
+  /**
+   * Return the star following the 'async' or 'sync' keyword, or `null` if there
+   * is no star.
+   */
+  Token get star => null;
+}
+
+/**
+ * A top-level declaration.
+ *
+ * > functionDeclaration ::=
+ * >     'external' functionSignature
+ * >   | functionSignature [FunctionBody]
+ * >
+ * > functionSignature ::=
+ * >     [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
+ */
+class FunctionDeclarationImpl extends NamedCompilationUnitMemberImpl
+    implements FunctionDeclaration {
+  /**
+   * The token representing the 'external' keyword, or `null` if this is not an
+   * external function.
+   */
+  Token externalKeyword;
+
+  /**
+   * The return type of the function, or `null` if no return type was declared.
+   */
+  TypeName _returnType;
+
+  /**
+   * The token representing the 'get' or 'set' keyword, or `null` if this is a
+   * function declaration rather than a property declaration.
+   */
+  Token propertyKeyword;
+
+  /**
+   * The function expression being wrapped.
+   */
+  FunctionExpression _functionExpression;
+
+  /**
+   * Initialize a newly created function declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the
+   * function is not an external function. The [returnType] can be `null` if no
+   * return type was specified. The [propertyKeyword] can be `null` if the
+   * function is neither a getter or a setter.
+   */
+  FunctionDeclarationImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.externalKeyword,
+      TypeName returnType,
+      this.propertyKeyword,
+      SimpleIdentifier name,
+      FunctionExpression functionExpression)
+      : super(comment, metadata, name) {
+    _returnType = _becomeParentOf(returnType);
+    _functionExpression = _becomeParentOf(functionExpression);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(externalKeyword)
+    ..add(_returnType)
+    ..add(propertyKeyword)
+    ..add(_name)
+    ..add(_functionExpression);
+
+  @override
+  ExecutableElement get element =>
+      _name != null ? (_name.staticElement as ExecutableElement) : null;
+
+  @override
+  Token get endToken => _functionExpression.endToken;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (externalKeyword != null) {
+      return externalKeyword;
+    } else if (_returnType != null) {
+      return _returnType.beginToken;
+    } else if (propertyKeyword != null) {
+      return propertyKeyword;
+    } else if (_name != null) {
+      return _name.beginToken;
+    }
+    return _functionExpression.beginToken;
+  }
+
+  @override
+  FunctionExpression get functionExpression => _functionExpression;
+
+  @override
+  void set functionExpression(FunctionExpression functionExpression) {
+    _functionExpression = _becomeParentOf(functionExpression);
+  }
+
+  @override
+  bool get isGetter =>
+      propertyKeyword != null &&
+      (propertyKeyword as KeywordToken).keyword == Keyword.GET;
+
+  @override
+  bool get isSetter =>
+      propertyKeyword != null &&
+      (propertyKeyword as KeywordToken).keyword == Keyword.SET;
+
+  @override
+  TypeName get returnType => _returnType;
+
+  @override
+  void set returnType(TypeName returnType) {
+    _returnType = _becomeParentOf(returnType);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_returnType, visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_functionExpression, visitor);
+  }
+}
+
+/**
+ * A [FunctionDeclaration] used as a statement.
+ */
+class FunctionDeclarationStatementImpl extends StatementImpl
+    implements FunctionDeclarationStatement {
+  /**
+   * The function declaration being wrapped.
+   */
+  FunctionDeclaration _functionDeclaration;
+
+  /**
+   * Initialize a newly created function declaration statement.
+   */
+  FunctionDeclarationStatementImpl(FunctionDeclaration functionDeclaration) {
+    _functionDeclaration = _becomeParentOf(functionDeclaration);
+  }
+
+  @override
+  Token get beginToken => _functionDeclaration.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(_functionDeclaration);
+
+  @override
+  Token get endToken => _functionDeclaration.endToken;
+
+  @override
+  FunctionDeclaration get functionDeclaration => _functionDeclaration;
+
+  @override
+  void set functionDeclaration(FunctionDeclaration functionDeclaration) {
+    _functionDeclaration = _becomeParentOf(functionDeclaration);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionDeclarationStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_functionDeclaration, visitor);
+  }
+}
+
+/**
+ * A function expression.
+ *
+ * > functionExpression ::=
+ * >     [TypeParameterList]? [FormalParameterList] [FunctionBody]
+ */
+class FunctionExpressionImpl extends ExpressionImpl
+    implements FunctionExpression {
+  /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The parameters associated with the function.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * The body of the function, or `null` if this is an external function.
+   */
+  FunctionBody _body;
+
+  /**
+   * The element associated with the function, or `null` if the AST structure
+   * has not been resolved.
+   */
+  ExecutableElement element;
+
+  /**
+   * Initialize a newly created function declaration.
+   */
+  FunctionExpressionImpl(TypeParameterList typeParameters,
+      FormalParameterList parameters, FunctionBody body) {
+    _typeParameters = _becomeParentOf(typeParameters);
+    _parameters = _becomeParentOf(parameters);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Token get beginToken {
+    if (_typeParameters != null) {
+      return _typeParameters.beginToken;
+    } else if (_parameters != null) {
+      return _parameters.beginToken;
+    } else if (_body != null) {
+      return _body.beginToken;
+    }
+    // This should never be reached because external functions must be named,
+    // hence either the body or the name should be non-null.
+    throw new IllegalStateException("Non-external functions must have a body");
+  }
+
+  @override
+  FunctionBody get body => _body;
+
+  @override
+  void set body(FunctionBody functionBody) {
+    _body = _becomeParentOf(functionBody);
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_parameters)..add(_body);
+
+  @override
+  Token get endToken {
+    if (_body != null) {
+      return _body.endToken;
+    } else if (_parameters != null) {
+      return _parameters.endToken;
+    }
+    // This should never be reached because external functions must be named,
+    // hence either the body or the name should be non-null.
+    throw new IllegalStateException("Non-external functions must have a body");
+  }
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  int get precedence => 16;
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_parameters, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * The invocation of a function resulting from evaluating an expression.
+ * Invocations of methods and other forms of functions are represented by
+ * [MethodInvocation] nodes. Invocations of getters and setters are represented
+ * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+ *
+ * > functionExpressionInvocation ::=
+ * >     [Expression] [TypeArgumentList]? [ArgumentList]
+ */
+class FunctionExpressionInvocationImpl extends ExpressionImpl
+    implements FunctionExpressionInvocation {
+  /**
+   * The expression producing the function being invoked.
+   */
+  Expression _function;
+
+  /**
+   * The type arguments to be applied to the method being invoked, or `null` if
+   * no type arguments were provided.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
+   * The list of arguments to the function.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The element associated with the function being invoked based on static type
+   * information, or `null` if the AST structure has not been resolved or the
+   * function could not be resolved.
+   */
+  ExecutableElement staticElement;
+
+  /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
+   * The element associated with the function being invoked based on propagated
+   * type information, or `null` if the AST structure has not been resolved or
+   * the function could not be resolved.
+   */
+  ExecutableElement propagatedElement;
+
+  /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
+   * Initialize a newly created function expression invocation.
+   */
+  FunctionExpressionInvocationImpl(Expression function,
+      TypeArgumentList typeArguments, ArgumentList argumentList) {
+    _function = _becomeParentOf(function);
+    _typeArguments = _becomeParentOf(typeArguments);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  Token get beginToken => _function.beginToken;
+
+  @override
+  ExecutableElement get bestElement {
+    ExecutableElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_function)..add(_argumentList);
+
+  @override
+  Token get endToken => _argumentList.endToken;
+
+  @override
+  Expression get function => _function;
+
+  @override
+  void set function(Expression expression) {
+    _function = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 15;
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  @override
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_function, visitor);
+    _safelyVisitChild(_typeArguments, visitor);
+    _safelyVisitChild(_argumentList, visitor);
+  }
+}
+
+/**
+ * A function type alias.
+ *
+ * > functionTypeAlias ::=
+ * >     functionPrefix [TypeParameterList]? [FormalParameterList] ';'
+ * >
+ * > functionPrefix ::=
+ * >     [TypeName]? [SimpleIdentifier]
+ */
+class FunctionTypeAliasImpl extends TypeAliasImpl implements FunctionTypeAlias {
+  /**
+   * The name of the return type of the function type being defined, or `null`
+   * if no return type was given.
+   */
+  TypeName _returnType;
+
+  /**
+   * The type parameters for the function type, or `null` if the function type
+   * does not have any type parameters.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The parameters associated with the function type.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * Initialize a newly created function type alias. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified. The [typeParameters] can be `null` if the function has no
+   * type parameters.
+   */
+  FunctionTypeAliasImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      TypeName returnType,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      Token semicolon)
+      : super(comment, metadata, keyword, name, semicolon) {
+    _returnType = _becomeParentOf(returnType);
+    _typeParameters = _becomeParentOf(typeParameters);
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(typedefKeyword)
+    ..add(_returnType)
+    ..add(_name)
+    ..add(_typeParameters)
+    ..add(_parameters)
+    ..add(semicolon);
+
+  @override
+  FunctionTypeAliasElement get element =>
+      _name != null ? (_name.staticElement as FunctionTypeAliasElement) : null;
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  TypeName get returnType => _returnType;
+
+  @override
+  void set returnType(TypeName typeName) {
+    _returnType = _becomeParentOf(typeName);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionTypeAlias(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_returnType, visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_parameters, visitor);
+  }
+}
+
+/**
+ * A function-typed formal parameter.
+ *
+ * > functionSignature ::=
+ * >     [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
+ */
+class FunctionTypedFormalParameterImpl extends NormalFormalParameterImpl
+    implements FunctionTypedFormalParameter {
+  /**
+   * The return type of the function, or `null` if the function does not have a
+   * return type.
+   */
+  TypeName _returnType;
+
+  /**
+   * The type parameters associated with the function, or `null` if the function
+   * is not a generic function.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The parameters of the function-typed parameter.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [returnType] can be `null` if no return type
+   * was specified.
+   */
+  FunctionTypedFormalParameterImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      TypeName returnType,
+      SimpleIdentifier identifier,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters)
+      : super(comment, metadata, identifier) {
+    _returnType = _becomeParentOf(returnType);
+    _typeParameters = _becomeParentOf(typeParameters);
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  Token get beginToken {
+    if (_returnType != null) {
+      return _returnType.beginToken;
+    }
+    return identifier.beginToken;
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(_returnType)..add(identifier)..add(parameters);
+
+  @override
+  Token get endToken => _parameters.endToken;
+
+  @override
+  bool get isConst => false;
+
+  @override
+  bool get isFinal => false;
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  TypeName get returnType => _returnType;
+
+  @override
+  void set returnType(TypeName type) {
+    _returnType = _becomeParentOf(type);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_returnType, visitor);
+    _safelyVisitChild(identifier, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_parameters, visitor);
+  }
+}
+
+/**
+ * A combinator that restricts the names being imported to those that are not in
+ * a given list.
+ *
+ * > hideCombinator ::=
+ * >     'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
+ */
+class HideCombinatorImpl extends CombinatorImpl implements HideCombinator {
+  /**
+   * The list of names from the library that are hidden by this combinator.
+   */
+  NodeList<SimpleIdentifier> _hiddenNames;
+
+  /**
+   * Initialize a newly created import show combinator.
+   */
+  HideCombinatorImpl(Token keyword, List<SimpleIdentifier> hiddenNames)
+      : super(keyword) {
+    _hiddenNames = new NodeList<SimpleIdentifier>(this, hiddenNames);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(keyword)
+    ..addAll(_hiddenNames);
+
+  @override
+  Token get endToken => _hiddenNames.endToken;
+
+  @override
+  NodeList<SimpleIdentifier> get hiddenNames => _hiddenNames;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitHideCombinator(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _hiddenNames.accept(visitor);
+  }
+}
+
+/**
+ * A node that represents an identifier.
+ *
+ * > identifier ::=
+ * >     [SimpleIdentifier]
+ * >   | [PrefixedIdentifier]
+ */
+abstract class IdentifierImpl extends ExpressionImpl implements Identifier {
+  /**
+   * Return the best element available for this operator. If resolution was able
+   * to find a better element based on type propagation, that element will be
+   * returned. Otherwise, the element found using the result of static analysis
+   * will be returned. If resolution has not been performed, then `null` will be
+   * returned.
+   */
+  Element get bestElement;
+
+  @override
+  bool get isAssignable => true;
+}
+
+/**
+ * An if statement.
+ *
+ * > ifStatement ::=
+ * >     'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
+ */
+class IfStatementImpl extends StatementImpl implements IfStatement {
+  /**
+   * The token representing the 'if' keyword.
+   */
+  Token ifKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The condition used to determine which of the statements is executed next.
+   */
+  Expression _condition;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The statement that is executed if the condition evaluates to `true`.
+   */
+  Statement _thenStatement;
+
+  /**
+   * The token representing the 'else' keyword, or `null` if there is no else
+   * statement.
+   */
+  Token elseKeyword;
+
+  /**
+   * The statement that is executed if the condition evaluates to `false`, or
+   * `null` if there is no else statement.
+   */
+  Statement _elseStatement;
+
+  /**
+   * Initialize a newly created if statement. The [elseKeyword] and
+   * [elseStatement] can be `null` if there is no else clause.
+   */
+  IfStatementImpl(
+      this.ifKeyword,
+      this.leftParenthesis,
+      Expression condition,
+      this.rightParenthesis,
+      Statement thenStatement,
+      this.elseKeyword,
+      Statement elseStatement) {
+    _condition = _becomeParentOf(condition);
+    _thenStatement = _becomeParentOf(thenStatement);
+    _elseStatement = _becomeParentOf(elseStatement);
+  }
+
+  @override
+  Token get beginToken => ifKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(ifKeyword)
+    ..add(leftParenthesis)
+    ..add(_condition)
+    ..add(rightParenthesis)
+    ..add(_thenStatement)
+    ..add(elseKeyword)
+    ..add(_elseStatement);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression);
+  }
+
+  @override
+  Statement get elseStatement => _elseStatement;
+
+  @override
+  void set elseStatement(Statement statement) {
+    _elseStatement = _becomeParentOf(statement);
+  }
+
+  @override
+  Token get endToken {
+    if (_elseStatement != null) {
+      return _elseStatement.endToken;
+    }
+    return _thenStatement.endToken;
+  }
+
+  @override
+  Statement get thenStatement => _thenStatement;
+
+  @override
+  void set thenStatement(Statement statement) {
+    _thenStatement = _becomeParentOf(statement);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitIfStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(_thenStatement, visitor);
+    _safelyVisitChild(_elseStatement, visitor);
+  }
+}
+
+/**
+ * The "implements" clause in an class declaration.
+ *
+ * > implementsClause ::=
+ * >     'implements' [TypeName] (',' [TypeName])*
+ */
+class ImplementsClauseImpl extends AstNodeImpl implements ImplementsClause {
+  /**
+   * The token representing the 'implements' keyword.
+   */
+  Token implementsKeyword;
+
+  /**
+   * The interfaces that are being implemented.
+   */
+  NodeList<TypeName> _interfaces;
+
+  /**
+   * Initialize a newly created implements clause.
+   */
+  ImplementsClauseImpl(this.implementsKeyword, List<TypeName> interfaces) {
+    _interfaces = new NodeList<TypeName>(this, interfaces);
+  }
+
+  @override
+  Token get beginToken => implementsKeyword;
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable get childEntities => new ChildEntities()
+    ..add(implementsKeyword)
+    ..addAll(interfaces);
+
+  @override
+  Token get endToken => _interfaces.endToken;
+
+  @override
+  NodeList<TypeName> get interfaces => _interfaces;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _interfaces.accept(visitor);
+  }
+}
+
+/**
+ * An import directive.
+ *
+ * > importDirective ::=
+ * >     [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
+ * >   | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
+ */
+class ImportDirectiveImpl extends NamespaceDirectiveImpl
+    implements ImportDirective {
+  /**
+   * The token representing the 'deferred' keyword, or `null` if the imported is
+   * not deferred.
+   */
+  Token deferredKeyword;
+
+  /**
+   * The token representing the 'as' keyword, or `null` if the imported names are
+   * not prefixed.
+   */
+  Token asKeyword;
+
+  /**
+   * The prefix to be used with the imported names, or `null` if the imported
+   * names are not prefixed.
+   */
+  SimpleIdentifier _prefix;
+
+  /**
+   * Initialize a newly created import directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the function does not have the
+   * corresponding attribute. The [deferredKeyword] can be `null` if the import
+   * is not deferred. The [asKeyword] and [prefix] can be `null` if the import
+   * does not specify a prefix. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  ImportDirectiveImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      this.deferredKeyword,
+      this.asKeyword,
+      SimpleIdentifier prefix,
+      List<Combinator> combinators,
+      Token semicolon)
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon) {
+    _prefix = _becomeParentOf(prefix);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(_uri)
+    ..add(deferredKeyword)
+    ..add(asKeyword)
+    ..add(_prefix)
+    ..addAll(combinators)
+    ..add(semicolon);
+
+  @override
+  ImportElement get element => super.element as ImportElement;
+
+  @override
+  SimpleIdentifier get prefix => _prefix;
+
+  @override
+  void set prefix(SimpleIdentifier identifier) {
+    _prefix = _becomeParentOf(identifier);
+  }
+
+  @override
+  LibraryElement get uriElement {
+    ImportElement element = this.element;
+    if (element == null) {
+      return null;
+    }
+    return element.importedLibrary;
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitImportDirective(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_prefix, visitor);
+    combinators.accept(visitor);
+  }
+}
+
+/**
+ * An index expression.
+ *
+ * > indexExpression ::=
+ * >     [Expression] '[' [Expression] ']'
+ */
+class IndexExpressionImpl extends ExpressionImpl implements IndexExpression {
+  /**
+   * The expression used to compute the object being indexed, or `null` if this
+   * index expression is part of a cascade expression.
+   */
+  Expression _target;
+
+  /**
+   * The period ("..") before a cascaded index expression, or `null` if this
+   * index expression is not part of a cascade expression.
+   */
+  Token period;
+
+  /**
+   * The left square bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The expression used to compute the index.
+   */
+  Expression _index;
+
+  /**
+   * The right square bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * The element associated with the operator based on the static type of the
+   * target, or `null` if the AST structure has not been resolved or if the
+   * operator could not be resolved.
+   */
+  MethodElement staticElement;
+
+  /**
+   * The element associated with the operator based on the propagated type of
+   * the target, or `null` if the AST structure has not been resolved or if the
+   * operator could not be resolved.
+   */
+  MethodElement propagatedElement;
+
+  /**
+   * If this expression is both in a getter and setter context, the
+   * [AuxiliaryElements] will be set to hold onto the static and propagated
+   * information. The auxiliary element will hold onto the elements from the
+   * getter context.
+   */
+  AuxiliaryElements auxiliaryElements = null;
+
+  /**
+   * Initialize a newly created index expression.
+   */
+  IndexExpressionImpl.forCascade(
+      this.period, this.leftBracket, Expression index, this.rightBracket) {
+    _index = _becomeParentOf(index);
+  }
+
+  /**
+   * Initialize a newly created index expression.
+   */
+  IndexExpressionImpl.forTarget(Expression target, this.leftBracket,
+      Expression index, this.rightBracket) {
+    _target = _becomeParentOf(target);
+    _index = _becomeParentOf(index);
+  }
+
+  @override
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    }
+    return period;
+  }
+
+  @override
+  MethodElement get bestElement {
+    MethodElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_target)
+    ..add(period)
+    ..add(leftBracket)
+    ..add(_index)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  Expression get index => _index;
+
+  @override
+  void set index(Expression expression) {
+    _index = _becomeParentOf(expression);
+  }
+
+  @override
+  bool get isAssignable => true;
+
+  @override
+  bool get isCascaded => period != null;
+
+  @override
+  int get precedence => 15;
+
+  @override
+  Expression get realTarget {
+    if (isCascaded) {
+      AstNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+
+  @override
+  Expression get target => _target;
+
+  @override
+  void set target(Expression expression) {
+    _target = _becomeParentOf(expression);
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on propagated type information, then return the parameter
+   * element representing the parameter to which the value of the index
+   * expression will be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _propagatedParameterElementForIndex {
+    if (propagatedElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = propagatedElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on static type information, then return the parameter element
+   * representing the parameter to which the value of the index expression will
+   * be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _staticParameterElementForIndex {
+    if (staticElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = staticElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitIndexExpression(this);
+
+  @override
+  bool inGetterContext() {
+    // TODO(brianwilkerson) Convert this to a getter.
+    AstNode parent = this.parent;
+    if (parent is AssignmentExpression) {
+      AssignmentExpression assignment = parent;
+      if (identical(assignment.leftHandSide, this) &&
+          assignment.operator.type == TokenType.EQ) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool inSetterContext() {
+    // TODO(brianwilkerson) Convert this to a getter.
+    AstNode parent = this.parent;
+    if (parent is PrefixExpression) {
+      return parent.operator.type.isIncrementOperator;
+    } else if (parent is PostfixExpression) {
+      return true;
+    } else if (parent is AssignmentExpression) {
+      return identical(parent.leftHandSide, this);
+    }
+    return false;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_target, visitor);
+    _safelyVisitChild(_index, visitor);
+  }
+}
+
+/**
+ * An instance creation expression.
+ *
+ * > newExpression ::=
+ * >     ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+ */
+class InstanceCreationExpressionImpl extends ExpressionImpl
+    implements InstanceCreationExpression {
+  /**
+   * The 'new' or 'const' keyword used to indicate how an object should be
+   * created.
+   */
+  Token keyword;
+
+  /**
+   * The name of the constructor to be invoked.
+   */
+  ConstructorName _constructorName;
+
+  /**
+   * The list of arguments to the constructor.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement staticElement;
+
+  /**
+   * Initialize a newly created instance creation expression.
+   */
+  InstanceCreationExpressionImpl(this.keyword, ConstructorName constructorName,
+      ArgumentList argumentList) {
+    _constructorName = _becomeParentOf(constructorName);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  Token get beginToken => keyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(keyword)
+    ..add(_constructorName)
+    ..add(_argumentList);
+
+  @override
+  ConstructorName get constructorName => _constructorName;
+
+  @override
+  void set constructorName(ConstructorName name) {
+    _constructorName = _becomeParentOf(name);
+  }
+
+  @override
+  Token get endToken => _argumentList.endToken;
+
+  @override
+  bool get isConst =>
+      keyword is KeywordToken &&
+      (keyword as KeywordToken).keyword == Keyword.CONST;
+
+  @override
+  int get precedence => 16;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitInstanceCreationExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_constructorName, visitor);
+    _safelyVisitChild(_argumentList, visitor);
+  }
+}
+
+/**
+ * An integer literal expression.
+ *
+ * > integerLiteral ::=
+ * >     decimalIntegerLiteral
+ * >   | hexadecimalIntegerLiteral
+ * >
+ * > decimalIntegerLiteral ::=
+ * >     decimalDigit+
+ * >
+ * > hexadecimalIntegerLiteral ::=
+ * >     '0x' hexadecimalDigit+
+ * >   | '0X' hexadecimalDigit+
+ */
+class IntegerLiteralImpl extends LiteralImpl implements IntegerLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token literal;
+
+  /**
+   * The value of the literal.
+   */
+  int value = 0;
+
+  /**
+   * Initialize a newly created integer literal.
+   */
+  IntegerLiteralImpl(this.literal, this.value);
+
+  @override
+  Token get beginToken => literal;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(literal);
+
+  @override
+  Token get endToken => literal;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitIntegerLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A node within a [StringInterpolation].
+ *
+ * > interpolationElement ::=
+ * >     [InterpolationExpression]
+ * >   | [InterpolationString]
+ */
+abstract class InterpolationElementImpl extends AstNodeImpl
+    implements InterpolationElement {}
+
+/**
+ * An expression embedded in a string interpolation.
+ *
+ * > interpolationExpression ::=
+ * >     '$' [SimpleIdentifier]
+ * >   | '$' '{' [Expression] '}'
+ */
+class InterpolationExpressionImpl extends InterpolationElementImpl
+    implements InterpolationExpression {
+  /**
+   * The token used to introduce the interpolation expression; either '$' if the
+   * expression is a simple identifier or '${' if the expression is a full
+   * expression.
+   */
+  Token leftBracket;
+
+  /**
+   * The expression to be evaluated for the value to be converted into a string.
+   */
+  Expression _expression;
+
+  /**
+   * The right curly bracket, or `null` if the expression is an identifier
+   * without brackets.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created interpolation expression.
+   */
+  InterpolationExpressionImpl(
+      this.leftBracket, Expression expression, this.rightBracket) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => leftBracket;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftBracket)
+    ..add(_expression)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken {
+    if (rightBracket != null) {
+      return rightBracket;
+    }
+    return _expression.endToken;
+  }
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitInterpolationExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A non-empty substring of an interpolated string.
+ *
+ * > interpolationString ::=
+ * >     characters
+ */
+class InterpolationStringImpl extends InterpolationElementImpl
+    implements InterpolationString {
+  /**
+   * The characters that will be added to the string.
+   */
+  Token contents;
+
+  /**
+   * The value of the literal.
+   */
+  String value;
+
+  /**
+   * Initialize a newly created string of characters that are part of a string
+   * interpolation.
+   */
+  InterpolationStringImpl(this.contents, this.value);
+
+  @override
+  Token get beginToken => contents;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(contents);
+
+  @override
+  int get contentsEnd {
+    String lexeme = contents.lexeme;
+    return offset + new StringLexemeHelper(lexeme, true, true).end;
+  }
+
+  @override
+  int get contentsOffset {
+    int offset = contents.offset;
+    String lexeme = contents.lexeme;
+    return offset + new StringLexemeHelper(lexeme, true, true).start;
+  }
+
+  @override
+  Token get endToken => contents;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitInterpolationString(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {}
+}
+
+/**
+ * An is expression.
+ *
+ * > isExpression ::=
+ * >     [Expression] 'is' '!'? [TypeName]
+ */
+class IsExpressionImpl extends ExpressionImpl implements IsExpression {
+  /**
+   * The expression used to compute the value whose type is being tested.
+   */
+  Expression _expression;
+
+  /**
+   * The is operator.
+   */
+  Token isOperator;
+
+  /**
+   * The not operator, or `null` if the sense of the test is not negated.
+   */
+  Token notOperator;
+
+  /**
+   * The name of the type being tested for.
+   */
+  TypeName _type;
+
+  /**
+   * Initialize a newly created is expression. The [notOperator] can be `null`
+   * if the sense of the test is not negated.
+   */
+  IsExpressionImpl(
+      Expression expression, this.isOperator, this.notOperator, TypeName type) {
+    _expression = _becomeParentOf(expression);
+    _type = _becomeParentOf(type);
+  }
+
+  @override
+  Token get beginToken => _expression.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_expression)
+    ..add(isOperator)
+    ..add(notOperator)
+    ..add(_type);
+
+  @override
+  Token get endToken => _type.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 7;
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName name) {
+    _type = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitIsExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+    _safelyVisitChild(_type, visitor);
+  }
+}
+
+/**
+ * A statement that has a label associated with them.
+ *
+ * > labeledStatement ::=
+ * >    [Label]+ [Statement]
+ */
+class LabeledStatementImpl extends StatementImpl implements LabeledStatement {
+  /**
+   * The labels being associated with the statement.
+   */
+  NodeList<Label> _labels;
+
+  /**
+   * The statement with which the labels are being associated.
+   */
+  Statement _statement;
+
+  /**
+   * Initialize a newly created labeled statement.
+   */
+  LabeledStatementImpl(List<Label> labels, Statement statement) {
+    _labels = new NodeList<Label>(this, labels);
+    _statement = _becomeParentOf(statement);
+  }
+
+  @override
+  Token get beginToken {
+    if (!_labels.isEmpty) {
+      return _labels.beginToken;
+    }
+    return _statement.beginToken;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..addAll(_labels)
+    ..add(_statement);
+
+  @override
+  Token get endToken => _statement.endToken;
+
+  @override
+  NodeList<Label> get labels => _labels;
+
+  @override
+  Statement get statement => _statement;
+
+  @override
+  void set statement(Statement statement) {
+    _statement = _becomeParentOf(statement);
+  }
+
+  @override
+  Statement get unlabeled => _statement.unlabeled;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitLabeledStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _labels.accept(visitor);
+    _safelyVisitChild(_statement, visitor);
+  }
+}
+
+/**
+ * A label on either a [LabeledStatement] or a [NamedExpression].
+ *
+ * > label ::=
+ * >     [SimpleIdentifier] ':'
+ */
+class LabelImpl extends AstNodeImpl implements Label {
+  /**
+   * The label being associated with the statement.
+   */
+  SimpleIdentifier _label;
+
+  /**
+   * The colon that separates the label from the statement.
+   */
+  Token colon;
+
+  /**
+   * Initialize a newly created label.
+   */
+  LabelImpl(SimpleIdentifier label, this.colon) {
+    _label = _becomeParentOf(label);
+  }
+
+  @override
+  Token get beginToken => _label.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(_label)..add(colon);
+
+  @override
+  Token get endToken => colon;
+
+  @override
+  SimpleIdentifier get label => _label;
+
+  @override
+  void set label(SimpleIdentifier label) {
+    _label = _becomeParentOf(label);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitLabel(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_label, visitor);
+  }
+}
+
+/**
+ * A library directive.
+ *
+ * > libraryDirective ::=
+ * >     [Annotation] 'library' [Identifier] ';'
+ */
+class LibraryDirectiveImpl extends DirectiveImpl implements LibraryDirective {
+  /**
+   * The token representing the 'library' keyword.
+   */
+  Token libraryKeyword;
+
+  /**
+   * The name of the library being defined.
+   */
+  LibraryIdentifier _name;
+
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created library directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  LibraryDirectiveImpl(Comment comment, List<Annotation> metadata,
+      this.libraryKeyword, LibraryIdentifier name, this.semicolon)
+      : super(comment, metadata) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(libraryKeyword)..add(_name)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => libraryKeyword;
+
+  @override
+  Token get keyword => libraryKeyword;
+
+  @override
+  LibraryIdentifier get name => _name;
+
+  @override
+  void set name(LibraryIdentifier name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitLibraryDirective(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+  }
+}
+
+/**
+ * The identifier for a library.
+ *
+ * > libraryIdentifier ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ */
+class LibraryIdentifierImpl extends IdentifierImpl
+    implements LibraryIdentifier {
+  /**
+   * The components of the identifier.
+   */
+  NodeList<SimpleIdentifier> _components;
+
+  /**
+   * Initialize a newly created prefixed identifier.
+   */
+  LibraryIdentifierImpl(List<SimpleIdentifier> components) {
+    _components = new NodeList<SimpleIdentifier>(this, components);
+  }
+
+  @override
+  Token get beginToken => _components.beginToken;
+
+  @override
+  Element get bestElement => staticElement;
+
+  @override
+  // TODO(paulberry): add "." tokens.
+  Iterable get childEntities => new ChildEntities()..addAll(_components);
+
+  @override
+  NodeList<SimpleIdentifier> get components => _components;
+
+  @override
+  Token get endToken => _components.endToken;
+
+  @override
+  String get name {
+    StringBuffer buffer = new StringBuffer();
+    bool needsPeriod = false;
+    for (SimpleIdentifier identifier in _components) {
+      if (needsPeriod) {
+        buffer.write(".");
+      } else {
+        needsPeriod = true;
+      }
+      buffer.write(identifier.name);
+    }
+    return buffer.toString();
+  }
+
+  @override
+  int get precedence => 15;
+
+  @override
+  Element get propagatedElement => null;
+
+  @override
+  Element get staticElement => null;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitLibraryIdentifier(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _components.accept(visitor);
+  }
+}
+
+/**
+ * A list literal.
+ *
+ * > listLiteral ::=
+ * >     'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'
+ */
+class ListLiteralImpl extends TypedLiteralImpl implements ListLiteral {
+  /**
+   * The left square bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The expressions used to compute the elements of the list.
+   */
+  NodeList<Expression> _elements;
+
+  /**
+   * The right square bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created list literal. The [constKeyword] can be `null`
+   * if the literal is not a constant. The [typeArguments] can be `null` if no
+   * type arguments were declared. The list of [elements] can be `null` if the
+   * list is empty.
+   */
+  ListLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
+      this.leftBracket, List<Expression> elements, this.rightBracket)
+      : super(constKeyword, typeArguments) {
+    _elements = new NodeList<Expression>(this, elements);
+  }
+
+  @override
+  Token get beginToken {
+    if (constKeyword != null) {
+      return constKeyword;
+    }
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
+    }
+    return leftBracket;
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable get childEntities => super._childEntities
+    ..add(leftBracket)
+    ..addAll(_elements)
+    ..add(rightBracket);
+
+  @override
+  NodeList<Expression> get elements => _elements;
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitListLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _elements.accept(visitor);
+  }
+}
+
+/**
+ * A node that represents a literal expression.
+ *
+ * > literal ::=
+ * >     [BooleanLiteral]
+ * >   | [DoubleLiteral]
+ * >   | [IntegerLiteral]
+ * >   | [ListLiteral]
+ * >   | [MapLiteral]
+ * >   | [NullLiteral]
+ * >   | [StringLiteral]
+ */
+abstract class LiteralImpl extends ExpressionImpl implements Literal {
+  @override
+  int get precedence => 16;
+}
+
+/**
+ * A single key/value pair in a map literal.
+ *
+ * > mapLiteralEntry ::=
+ * >     [Expression] ':' [Expression]
+ */
+class MapLiteralEntryImpl extends AstNodeImpl implements MapLiteralEntry {
+  /**
+   * The expression computing the key with which the value will be associated.
+   */
+  Expression _key;
+
+  /**
+   * The colon that separates the key from the value.
+   */
+  Token separator;
+
+  /**
+   * The expression computing the value that will be associated with the key.
+   */
+  Expression _value;
+
+  /**
+   * Initialize a newly created map literal entry.
+   */
+  MapLiteralEntryImpl(Expression key, this.separator, Expression value) {
+    _key = _becomeParentOf(key);
+    _value = _becomeParentOf(value);
+  }
+
+  @override
+  Token get beginToken => _key.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_key)..add(separator)..add(_value);
+
+  @override
+  Token get endToken => _value.endToken;
+
+  @override
+  Expression get key => _key;
+
+  @override
+  void set key(Expression string) {
+    _key = _becomeParentOf(string);
+  }
+
+  @override
+  Expression get value => _value;
+
+  @override
+  void set value(Expression expression) {
+    _value = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitMapLiteralEntry(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_key, visitor);
+    _safelyVisitChild(_value, visitor);
+  }
+}
+
+/**
+ * A literal map.
+ *
+ * > mapLiteral ::=
+ * >     'const'? ('<' [TypeName] (',' [TypeName])* '>')?
+ * >     '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
+ */
+class MapLiteralImpl extends TypedLiteralImpl implements MapLiteral {
+  /**
+   * The left curly bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The entries in the map.
+   */
+  NodeList<MapLiteralEntry> _entries;
+
+  /**
+   * The right curly bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created map literal. The [constKeyword] can be `null` if
+   * the literal is not a constant. The [typeArguments] can be `null` if no type
+   * arguments were declared. The [entries] can be `null` if the map is empty.
+   */
+  MapLiteralImpl(Token constKeyword, TypeArgumentList typeArguments,
+      this.leftBracket, List<MapLiteralEntry> entries, this.rightBracket)
+      : super(constKeyword, typeArguments) {
+    _entries = new NodeList<MapLiteralEntry>(this, entries);
+  }
+
+  @override
+  Token get beginToken {
+    if (constKeyword != null) {
+      return constKeyword;
+    }
+    TypeArgumentList typeArguments = this.typeArguments;
+    if (typeArguments != null) {
+      return typeArguments.beginToken;
+    }
+    return leftBracket;
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable get childEntities => super._childEntities
+    ..add(leftBracket)
+    ..addAll(entries)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<MapLiteralEntry> get entries => _entries;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitMapLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _entries.accept(visitor);
+  }
+}
+
+/**
+ * A method declaration.
+ *
+ * > methodDeclaration ::=
+ * >     methodSignature [FunctionBody]
+ * >
+ * > methodSignature ::=
+ * >     'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
+ * >     methodName [TypeParameterList] [FormalParameterList]
+ * >
+ * > methodName ::=
+ * >     [SimpleIdentifier]
+ * >   | 'operator' [SimpleIdentifier]
+ */
+class MethodDeclarationImpl extends ClassMemberImpl
+    implements MethodDeclaration {
+  /**
+   * The token for the 'external' keyword, or `null` if the constructor is not
+   * external.
+   */
+  Token externalKeyword;
+
+  /**
+   * The token representing the 'abstract' or 'static' keyword, or `null` if
+   * neither modifier was specified.
+   */
+  Token modifierKeyword;
+
+  /**
+   * The return type of the method, or `null` if no return type was declared.
+   */
+  TypeName _returnType;
+
+  /**
+   * The token representing the 'get' or 'set' keyword, or `null` if this is a
+   * method declaration rather than a property declaration.
+   */
+  Token propertyKeyword;
+
+  /**
+   * The token representing the 'operator' keyword, or `null` if this method
+   * does not declare an operator.
+   */
+  Token operatorKeyword;
+
+  /**
+   * The name of the method.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
+   * The parameters associated with the method, or `null` if this method
+   * declares a getter.
+   */
+  FormalParameterList _parameters;
+
+  /**
+   * The body of the method.
+   */
+  FunctionBody _body;
+
+  /**
+   * Initialize a newly created method declaration. Either or both of the
+   * [comment] and [metadata] can be `null` if the declaration does not have the
+   * corresponding attribute. The [externalKeyword] can be `null` if the method
+   * is not external. The [modifierKeyword] can be `null` if the method is
+   * neither abstract nor static. The [returnType] can be `null` if no return
+   * type was specified. The [propertyKeyword] can be `null` if the method is
+   * neither a getter or a setter. The [operatorKeyword] can be `null` if the
+   * method does not implement an operator. The [parameters] must be `null` if
+   * this method declares a getter.
+   */
+  MethodDeclarationImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.externalKeyword,
+      this.modifierKeyword,
+      TypeName returnType,
+      this.propertyKeyword,
+      this.operatorKeyword,
+      SimpleIdentifier name,
+      TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      FunctionBody body)
+      : super(comment, metadata) {
+    _returnType = _becomeParentOf(returnType);
+    _name = _becomeParentOf(name);
+    _typeParameters = _becomeParentOf(typeParameters);
+    _parameters = _becomeParentOf(parameters);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  FunctionBody get body => _body;
+
+  @override
+  void set body(FunctionBody functionBody) {
+    _body = _becomeParentOf(functionBody);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(externalKeyword)
+    ..add(modifierKeyword)
+    ..add(_returnType)
+    ..add(propertyKeyword)
+    ..add(operatorKeyword)
+    ..add(_name)
+    ..add(_parameters)
+    ..add(_body);
+
+  /**
+   * Return the element associated with this method, or `null` if the AST
+   * structure has not been resolved. The element can either be a
+   * [MethodElement], if this represents the declaration of a normal method, or
+   * a [PropertyAccessorElement] if this represents the declaration of either a
+   * getter or a setter.
+   */
+  @override
+  ExecutableElement get element =>
+      _name != null ? (_name.staticElement as ExecutableElement) : null;
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (modifierKeyword != null) {
+      return modifierKeyword;
+    } else if (_returnType != null) {
+      return _returnType.beginToken;
+    } else if (propertyKeyword != null) {
+      return propertyKeyword;
+    } else if (operatorKeyword != null) {
+      return operatorKeyword;
+    }
+    return _name.beginToken;
+  }
+
+  @override
+  bool get isAbstract {
+    FunctionBody body = _body;
+    return externalKeyword == null &&
+        (body is EmptyFunctionBody && !body.semicolon.isSynthetic);
+  }
+
+  @override
+  bool get isGetter =>
+      propertyKeyword != null &&
+      (propertyKeyword as KeywordToken).keyword == Keyword.GET;
+
+  @override
+  bool get isOperator => operatorKeyword != null;
+
+  @override
+  bool get isSetter =>
+      propertyKeyword != null &&
+      (propertyKeyword as KeywordToken).keyword == Keyword.SET;
+
+  @override
+  bool get isStatic =>
+      modifierKeyword != null &&
+      (modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  FormalParameterList get parameters => _parameters;
+
+  @override
+  void set parameters(FormalParameterList parameters) {
+    _parameters = _becomeParentOf(parameters);
+  }
+
+  @override
+  TypeName get returnType => _returnType;
+
+  @override
+  void set returnType(TypeName typeName) {
+    _returnType = _becomeParentOf(typeName);
+  }
+
+  @override
+  TypeParameterList get typeParameters => _typeParameters;
+
+  @override
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitMethodDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_returnType, visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
+    _safelyVisitChild(_parameters, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * The invocation of either a function or a method. Invocations of functions
+ * resulting from evaluating an expression are represented by
+ * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
+ * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
+ *
+ * > methodInvocation ::=
+ * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
+ */
+class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
+  /**
+   * The expression producing the object on which the method is defined, or
+   * `null` if there is no target (that is, the target is implicitly `this`).
+   */
+  Expression _target;
+
+  /**
+   * The operator that separates the target from the method name, or `null`
+   * if there is no target. In an ordinary method invocation this will be a
+   * period ('.'). In a cascade section this will be the cascade operator
+   * ('..').
+   */
+  Token operator;
+
+  /**
+   * The name of the method being invoked.
+   */
+  SimpleIdentifier _methodName;
+
+  /**
+   * The type arguments to be applied to the method being invoked, or `null` if
+   * no type arguments were provided.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
+   * The list of arguments to the method.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The function type of the method invocation, or `null` if the AST
+   * structure has not been resolved, or if the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType staticInvokeType;
+
+  /**
+   * Like [staticInvokeType], but reflects propagated type information.
+   */
+  DartType propagatedInvokeType;
+
+  /**
+   * Initialize a newly created method invocation. The [target] and [operator]
+   * can be `null` if there is no target.
+   */
+  MethodInvocationImpl(
+      Expression target,
+      this.operator,
+      SimpleIdentifier methodName,
+      TypeArgumentList typeArguments,
+      ArgumentList argumentList) {
+    _target = _becomeParentOf(target);
+    _methodName = _becomeParentOf(methodName);
+    _typeArguments = _becomeParentOf(typeArguments);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    } else if (operator != null) {
+      return operator;
+    }
+    return _methodName.beginToken;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(_target)
+    ..add(operator)
+    ..add(_methodName)
+    ..add(_argumentList);
+
+  @override
+  Token get endToken => _argumentList.endToken;
+
+  @override
+  bool get isCascaded =>
+      operator != null && operator.type == TokenType.PERIOD_PERIOD;
+
+  @override
+  SimpleIdentifier get methodName => _methodName;
+
+  @override
+  void set methodName(SimpleIdentifier identifier) {
+    _methodName = _becomeParentOf(identifier);
+  }
+
+  @override
+  int get precedence => 15;
+
+  @override
+  Expression get realTarget {
+    if (isCascaded) {
+      AstNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+
+  @override
+  Expression get target => _target;
+
+  @override
+  void set target(Expression expression) {
+    _target = _becomeParentOf(expression);
+  }
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  @override
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_target, visitor);
+    _safelyVisitChild(_methodName, visitor);
+    _safelyVisitChild(_typeArguments, visitor);
+    _safelyVisitChild(_argumentList, visitor);
+  }
+}
+
+/**
+ * A node that declares a single name within the scope of a compilation unit.
+ */
+abstract class NamedCompilationUnitMemberImpl extends CompilationUnitMemberImpl
+    implements NamedCompilationUnitMember {
+  /**
+   * The name of the member being declared.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * Initialize a newly created compilation unit member with the given [name].
+   * Either or both of the [comment] and [metadata] can be `null` if the member
+   * does not have the corresponding attribute.
+   */
+  NamedCompilationUnitMemberImpl(
+      Comment comment, List<Annotation> metadata, SimpleIdentifier name)
+      : super(comment, metadata) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+}
+
+/**
+ * An expression that has a name associated with it. They are used in method
+ * invocations when there are named parameters.
+ *
+ * > namedExpression ::=
+ * >     [Label] [Expression]
+ */
+class NamedExpressionImpl extends ExpressionImpl implements NamedExpression {
+  /**
+   * The name associated with the expression.
+   */
+  Label _name;
+
+  /**
+   * The expression with which the name is associated.
+   */
+  Expression _expression;
+
+  /**
+   * Initialize a newly created named expression..
+   */
+  NamedExpressionImpl(Label name, Expression expression) {
+    _name = _becomeParentOf(name);
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => _name.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_name)..add(_expression);
+
+  @override
+  ParameterElement get element {
+    Element element = _name.label.staticElement;
+    if (element is ParameterElement) {
+      return element;
+    }
+    return null;
+  }
+
+  @override
+  Token get endToken => _expression.endToken;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Label get name => _name;
+
+  @override
+  void set name(Label identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  int get precedence => 0;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitNamedExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A node that represents a directive that impacts the namespace of a library.
+ *
+ * > directive ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ */
+abstract class NamespaceDirectiveImpl extends UriBasedDirectiveImpl
+    implements NamespaceDirective {
+  /**
+   * The token representing the 'import' or 'export' keyword.
+   */
+  Token keyword;
+
+  /**
+   * The configurations used to control which library will actually be loaded at
+   * run-time.
+   */
+  NodeList<Configuration> _configurations;
+
+  /**
+   * The combinators used to control which names are imported or exported.
+   */
+  NodeList<Combinator> _combinators;
+
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created namespace directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute. The list of [combinators] can be `null` if there
+   * are no combinators.
+   */
+  NamespaceDirectiveImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      this.semicolon)
+      : super(comment, metadata, libraryUri) {
+    _configurations = new NodeList<Configuration>(this, configurations);
+    _combinators = new NodeList<Combinator>(this, combinators);
+  }
+
+  @override
+  NodeList<Combinator> get combinators => _combinators;
+
+  @override
+  NodeList<Configuration> get configurations => _configurations;
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => keyword;
+
+  @override
+  LibraryElement get uriElement;
+}
+
+/**
+ * The "native" clause in an class declaration.
+ *
+ * > nativeClause ::=
+ * >     'native' [StringLiteral]
+ */
+class NativeClauseImpl extends AstNodeImpl implements NativeClause {
+  /**
+   * The token representing the 'native' keyword.
+   */
+  Token nativeKeyword;
+
+  /**
+   * The name of the native object that implements the class.
+   */
+  StringLiteral _name;
+
+  /**
+   * Initialize a newly created native clause.
+   */
+  NativeClauseImpl(this.nativeKeyword, StringLiteral name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  Token get beginToken => nativeKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(nativeKeyword)..add(_name);
+
+  @override
+  Token get endToken => _name.endToken;
+
+  @override
+  StringLiteral get name => _name;
+
+  @override
+  void set name(StringLiteral name) {
+    _name = _becomeParentOf(name);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitNativeClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+  }
+}
+
+/**
+ * A function body that consists of a native keyword followed by a string
+ * literal.
+ *
+ * > nativeFunctionBody ::=
+ * >     'native' [SimpleStringLiteral] ';'
+ */
+class NativeFunctionBodyImpl extends FunctionBodyImpl
+    implements NativeFunctionBody {
+  /**
+   * The token representing 'native' that marks the start of the function body.
+   */
+  Token nativeKeyword;
+
+  /**
+   * The string literal, after the 'native' token.
+   */
+  StringLiteral _stringLiteral;
+
+  /**
+   * The token representing the semicolon that marks the end of the function
+   * body.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created function body consisting of the 'native' token,
+   * a string literal, and a semicolon.
+   */
+  NativeFunctionBodyImpl(
+      this.nativeKeyword, StringLiteral stringLiteral, this.semicolon) {
+    _stringLiteral = _becomeParentOf(stringLiteral);
+  }
+
+  @override
+  Token get beginToken => nativeKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(nativeKeyword)
+    ..add(_stringLiteral)
+    ..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  StringLiteral get stringLiteral => _stringLiteral;
+
+  @override
+  void set stringLiteral(StringLiteral stringLiteral) {
+    _stringLiteral = _becomeParentOf(stringLiteral);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitNativeFunctionBody(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_stringLiteral, visitor);
+  }
+}
+
+/**
+ * A list of AST nodes that have a common parent.
+ */
+class NodeListImpl<E extends AstNode> extends Object
+    with ListMixin<E>
+    implements NodeList<E> {
+  /**
+   * The node that is the parent of each of the elements in the list.
+   */
+  AstNodeImpl owner;
+
+  /**
+   * The elements contained in the list.
+   */
+  List<E> _elements = <E>[];
+
+  /**
+   * Initialize a newly created list of nodes such that all of the nodes that
+   * are added to the list will have their parent set to the given [owner]. The
+   * list will initially be populated with the given [elements].
+   */
+  NodeListImpl(this.owner, [List<E> elements]) {
+    addAll(elements);
+  }
+
+  @override
+  Token get beginToken {
+    if (_elements.length == 0) {
+      return null;
+    }
+    return _elements[0].beginToken;
+  }
+
+  @override
+  Token get endToken {
+    int length = _elements.length;
+    if (length == 0) {
+      return null;
+    }
+    return _elements[length - 1].endToken;
+  }
+
+  int get length => _elements.length;
+
+  @deprecated // Never intended for public use.
+  @override
+  void set length(int newLength) {
+    throw new UnsupportedError("Cannot resize NodeList.");
+  }
+
+  E operator [](int index) {
+    if (index < 0 || index >= _elements.length) {
+      throw new RangeError("Index: $index, Size: ${_elements.length}");
+    }
+    return _elements[index];
+  }
+
+  void operator []=(int index, E node) {
+    if (index < 0 || index >= _elements.length) {
+      throw new RangeError("Index: $index, Size: ${_elements.length}");
+    }
+    owner._becomeParentOf(node);
+    _elements[index] = node;
+  }
+
+  @override
+  accept(AstVisitor visitor) {
+    int length = _elements.length;
+    for (var i = 0; i < length; i++) {
+      _elements[i].accept(visitor);
+    }
+  }
+
+  @override
+  void add(E node) {
+    insert(length, node);
+  }
+
+  @override
+  bool addAll(Iterable<E> nodes) {
+    if (nodes != null && !nodes.isEmpty) {
+      _elements.addAll(nodes);
+      for (E node in nodes) {
+        owner._becomeParentOf(node);
+      }
+      return true;
+    }
+    return false;
+  }
+
+  @override
+  void clear() {
+    _elements = <E>[];
+  }
+
+  @override
+  void insert(int index, E node) {
+    int length = _elements.length;
+    if (index < 0 || index > length) {
+      throw new RangeError("Index: $index, Size: ${_elements.length}");
+    }
+    owner._becomeParentOf(node);
+    if (length == 0) {
+      _elements.add(node);
+    } else {
+      _elements.insert(index, node);
+    }
+  }
+
+  @override
+  E removeAt(int index) {
+    if (index < 0 || index >= _elements.length) {
+      throw new RangeError("Index: $index, Size: ${_elements.length}");
+    }
+    E removedNode = _elements[index];
+    _elements.removeAt(index);
+    return removedNode;
+  }
+}
+
+/**
+ * A formal parameter that is required (is not optional).
+ *
+ * > normalFormalParameter ::=
+ * >     [FunctionTypedFormalParameter]
+ * >   | [FieldFormalParameter]
+ * >   | [SimpleFormalParameter]
+ */
+abstract class NormalFormalParameterImpl extends FormalParameterImpl
+    implements NormalFormalParameter {
+  /**
+   * The documentation comment associated with this parameter, or `null` if this
+   * parameter does not have a documentation comment associated with it.
+   */
+  Comment _comment;
+
+  /**
+   * The annotations associated with this parameter.
+   */
+  NodeList<Annotation> _metadata;
+
+  /**
+   * The name of the parameter being declared.
+   */
+  SimpleIdentifier _identifier;
+
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute.
+   */
+  NormalFormalParameterImpl(
+      Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
+    _comment = _becomeParentOf(comment);
+    _metadata = new NodeList<Annotation>(this, metadata);
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Comment get documentationComment => _comment;
+
+  @override
+  void set documentationComment(Comment comment) {
+    _comment = _becomeParentOf(comment);
+  }
+
+  @override
+  SimpleIdentifier get identifier => _identifier;
+
+  @override
+  void set identifier(SimpleIdentifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  ParameterKind get kind {
+    AstNode parent = this.parent;
+    if (parent is DefaultFormalParameter) {
+      return parent.kind;
+    }
+    return ParameterKind.REQUIRED;
+  }
+
+  @override
+  NodeList<Annotation> get metadata => _metadata;
+
+  @override
+  void set metadata(List<Annotation> metadata) {
+    _metadata.clear();
+    _metadata.addAll(metadata);
+  }
+
+  @override
+  List<AstNode> get sortedCommentAndAnnotations {
+    return <AstNode>[]
+      ..add(_comment)
+      ..addAll(_metadata)
+      ..sort(AstNode.LEXICAL_ORDER);
+  }
+
+  ChildEntities get _childEntities {
+    ChildEntities result = new ChildEntities();
+    if (_commentIsBeforeAnnotations()) {
+      result
+        ..add(_comment)
+        ..addAll(_metadata);
+    } else {
+      result.addAll(sortedCommentAndAnnotations);
+    }
+    return result;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    //
+    // Note that subclasses are responsible for visiting the identifier because
+    // they often need to visit other nodes before visiting the identifier.
+    //
+    if (_commentIsBeforeAnnotations()) {
+      _safelyVisitChild(_comment, visitor);
+      _metadata.accept(visitor);
+    } else {
+      for (AstNode child in sortedCommentAndAnnotations) {
+        child.accept(visitor);
+      }
+    }
+  }
+
+  /**
+   * Return `true` if the comment is lexically before any annotations.
+   */
+  bool _commentIsBeforeAnnotations() {
+    if (_comment == null || _metadata.isEmpty) {
+      return true;
+    }
+    Annotation firstAnnotation = _metadata[0];
+    return _comment.offset < firstAnnotation.offset;
+  }
+}
+
+/**
+ * A null literal expression.
+ *
+ * > nullLiteral ::=
+ * >     'null'
+ */
+class NullLiteralImpl extends LiteralImpl implements NullLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token literal;
+
+  /**
+   * Initialize a newly created null literal.
+   */
+  NullLiteralImpl(this.literal);
+
+  @override
+  Token get beginToken => literal;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(literal);
+
+  @override
+  Token get endToken => literal;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitNullLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A parenthesized expression.
+ *
+ * > parenthesizedExpression ::=
+ * >     '(' [Expression] ')'
+ */
+class ParenthesizedExpressionImpl extends ExpressionImpl
+    implements ParenthesizedExpression {
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The expression within the parentheses.
+   */
+  Expression _expression;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * Initialize a newly created parenthesized expression.
+   */
+  ParenthesizedExpressionImpl(
+      this.leftParenthesis, Expression expression, this.rightParenthesis) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => leftParenthesis;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftParenthesis)
+    ..add(_expression)
+    ..add(rightParenthesis);
+
+  @override
+  Token get endToken => rightParenthesis;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 15;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitParenthesizedExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A part directive.
+ *
+ * > partDirective ::=
+ * >     [Annotation] 'part' [StringLiteral] ';'
+ */
+class PartDirectiveImpl extends UriBasedDirectiveImpl implements PartDirective {
+  /**
+   * The token representing the 'part' keyword.
+   */
+  Token partKeyword;
+
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created part directive. Either or both of the [comment]
+   * and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  PartDirectiveImpl(Comment comment, List<Annotation> metadata,
+      this.partKeyword, StringLiteral partUri, this.semicolon)
+      : super(comment, metadata, partUri);
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(partKeyword)..add(_uri)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => partKeyword;
+
+  @override
+  Token get keyword => partKeyword;
+
+  @override
+  CompilationUnitElement get uriElement => element as CompilationUnitElement;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPartDirective(this);
+}
+
+/**
+ * A part-of directive.
+ *
+ * > partOfDirective ::=
+ * >     [Annotation] 'part' 'of' [Identifier] ';'
+ */
+class PartOfDirectiveImpl extends DirectiveImpl implements PartOfDirective {
+  /**
+   * The token representing the 'part' keyword.
+   */
+  Token partKeyword;
+
+  /**
+   * The token representing the 'of' keyword.
+   */
+  Token ofKeyword;
+
+  /**
+   * The name of the library that the containing compilation unit is part of.
+   */
+  LibraryIdentifier _libraryName;
+
+  /**
+   * The semicolon terminating the directive.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created part-of directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  PartOfDirectiveImpl(
+      Comment comment,
+      List<Annotation> metadata,
+      this.partKeyword,
+      this.ofKeyword,
+      LibraryIdentifier libraryName,
+      this.semicolon)
+      : super(comment, metadata) {
+    _libraryName = _becomeParentOf(libraryName);
+  }
+
+  @override
+  Iterable get childEntities => super._childEntities
+    ..add(partKeyword)
+    ..add(ofKeyword)
+    ..add(_libraryName)
+    ..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => partKeyword;
+
+  @override
+  Token get keyword => partKeyword;
+
+  @override
+  LibraryIdentifier get libraryName => _libraryName;
+
+  @override
+  void set libraryName(LibraryIdentifier libraryName) {
+    _libraryName = _becomeParentOf(libraryName);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_libraryName, visitor);
+  }
+}
+
+/**
+ * A postfix unary expression.
+ *
+ * > postfixExpression ::=
+ * >     [Expression] [Token]
+ */
+class PostfixExpressionImpl extends ExpressionImpl
+    implements PostfixExpression {
+  /**
+   * The expression computing the operand for the operator.
+   */
+  Expression _operand;
+
+  /**
+   * The postfix operator being applied to the operand.
+   */
+  Token operator;
+
+  /**
+   * The element associated with this the operator based on the propagated type
+   * of the operand, or `null` if the AST structure has not been resolved, if
+   * the operator is not user definable, or if the operator could not be
+   * resolved.
+   */
+  MethodElement propagatedElement;
+
+  /**
+   * The element associated with the operator based on the static type of the
+   * operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement staticElement;
+
+  /**
+   * Initialize a newly created postfix expression.
+   */
+  PostfixExpressionImpl(Expression operand, this.operator) {
+    _operand = _becomeParentOf(operand);
+  }
+
+  @override
+  Token get beginToken => _operand.beginToken;
+
+  @override
+  MethodElement get bestElement {
+    MethodElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_operand)..add(operator);
+
+  @override
+  Token get endToken => operator;
+
+  @override
+  Expression get operand => _operand;
+
+  @override
+  void set operand(Expression expression) {
+    _operand = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 15;
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on propagated type information, then return the parameter
+   * element representing the parameter to which the value of the operand will
+   * be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _propagatedParameterElementForOperand {
+    if (propagatedElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = propagatedElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on static type information, then return the parameter element
+   * representing the parameter to which the value of the operand will be bound.
+   * Otherwise, return `null`.
+   */
+  ParameterElement get _staticParameterElementForOperand {
+    if (staticElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = staticElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPostfixExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_operand, visitor);
+  }
+}
+
+/**
+ * An identifier that is prefixed or an access to an object property where the
+ * target of the property access is a simple identifier.
+ *
+ * > prefixedIdentifier ::=
+ * >     [SimpleIdentifier] '.' [SimpleIdentifier]
+ */
+class PrefixedIdentifierImpl extends IdentifierImpl
+    implements PrefixedIdentifier {
+  /**
+   * The prefix associated with the library in which the identifier is defined.
+   */
+  SimpleIdentifier _prefix;
+
+  /**
+   * The period used to separate the prefix from the identifier.
+   */
+  Token period;
+
+  /**
+   * The identifier being prefixed.
+   */
+  SimpleIdentifier _identifier;
+
+  /**
+   * Initialize a newly created prefixed identifier.
+   */
+  PrefixedIdentifierImpl(
+      SimpleIdentifier prefix, this.period, SimpleIdentifier identifier) {
+    _prefix = _becomeParentOf(prefix);
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  Token get beginToken => _prefix.beginToken;
+
+  @override
+  Element get bestElement {
+    if (_identifier == null) {
+      return null;
+    }
+    return _identifier.bestElement;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_prefix)..add(period)..add(_identifier);
+
+  @override
+  Token get endToken => _identifier.endToken;
+
+  @override
+  SimpleIdentifier get identifier => _identifier;
+
+  @override
+  void set identifier(SimpleIdentifier identifier) {
+    _identifier = _becomeParentOf(identifier);
+  }
+
+  @override
+  bool get isDeferred {
+    Element element = _prefix.staticElement;
+    if (element is! PrefixElement) {
+      return false;
+    }
+    PrefixElement prefixElement = element as PrefixElement;
+    List<ImportElement> imports =
+        prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
+    if (imports.length != 1) {
+      return false;
+    }
+    return imports[0].isDeferred;
+  }
+
+  @override
+  String get name => "${_prefix.name}.${_identifier.name}";
+
+  @override
+  int get precedence => 15;
+
+  @override
+  SimpleIdentifier get prefix => _prefix;
+
+  @override
+  void set prefix(SimpleIdentifier identifier) {
+    _prefix = _becomeParentOf(identifier);
+  }
+
+  @override
+  Element get propagatedElement {
+    if (_identifier == null) {
+      return null;
+    }
+    return _identifier.propagatedElement;
+  }
+
+  @override
+  Element get staticElement {
+    if (_identifier == null) {
+      return null;
+    }
+    return _identifier.staticElement;
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPrefixedIdentifier(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_prefix, visitor);
+    _safelyVisitChild(_identifier, visitor);
+  }
+}
+
+/**
+ * A prefix unary expression.
+ *
+ * > prefixExpression ::=
+ * >     [Token] [Expression]
+ */
+class PrefixExpressionImpl extends ExpressionImpl implements PrefixExpression {
+  /**
+   * The prefix operator being applied to the operand.
+   */
+  Token operator;
+
+  /**
+   * The expression computing the operand for the operator.
+   */
+  Expression _operand;
+
+  /**
+   * The element associated with the operator based on the static type of the
+   * operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement staticElement;
+
+  /**
+   * The element associated with the operator based on the propagated type of
+   * the operand, or `null` if the AST structure has not been resolved, if the
+   * operator is not user definable, or if the operator could not be resolved.
+   */
+  MethodElement propagatedElement;
+
+  /**
+   * Initialize a newly created prefix expression.
+   */
+  PrefixExpressionImpl(this.operator, Expression operand) {
+    _operand = _becomeParentOf(operand);
+  }
+
+  @override
+  Token get beginToken => operator;
+
+  @override
+  MethodElement get bestElement {
+    MethodElement element = propagatedElement;
+    if (element == null) {
+      element = staticElement;
+    }
+    return element;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(operator)..add(_operand);
+
+  @override
+  Token get endToken => _operand.endToken;
+
+  @override
+  Expression get operand => _operand;
+
+  @override
+  void set operand(Expression expression) {
+    _operand = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 14;
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on propagated type information, then return the parameter
+   * element representing the parameter to which the value of the operand will
+   * be bound. Otherwise, return `null`.
+   */
+  ParameterElement get _propagatedParameterElementForOperand {
+    if (propagatedElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = propagatedElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  /**
+   * If the AST structure has been resolved, and the function being invoked is
+   * known based on static type information, then return the parameter element
+   * representing the parameter to which the value of the operand will be bound.
+   * Otherwise, return `null`.
+   */
+  ParameterElement get _staticParameterElementForOperand {
+    if (staticElement == null) {
+      return null;
+    }
+    List<ParameterElement> parameters = staticElement.parameters;
+    if (parameters.length < 1) {
+      return null;
+    }
+    return parameters[0];
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPrefixExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_operand, visitor);
+  }
+}
+
+/**
+ * The access of a property of an object.
+ *
+ * Note, however, that accesses to properties of objects can also be represented
+ * as [PrefixedIdentifier] nodes in cases where the target is also a simple
+ * identifier.
+ *
+ * > propertyAccess ::=
+ * >     [Expression] '.' [SimpleIdentifier]
+ */
+class PropertyAccessImpl extends ExpressionImpl implements PropertyAccess {
+  /**
+   * The expression computing the object defining the property being accessed.
+   */
+  Expression _target;
+
+  /**
+   * The property access operator.
+   */
+  Token operator;
+
+  /**
+   * The name of the property being accessed.
+   */
+  SimpleIdentifier _propertyName;
+
+  /**
+   * Initialize a newly created property access expression.
+   */
+  PropertyAccessImpl(
+      Expression target, this.operator, SimpleIdentifier propertyName) {
+    _target = _becomeParentOf(target);
+    _propertyName = _becomeParentOf(propertyName);
+  }
+
+  @override
+  Token get beginToken {
+    if (_target != null) {
+      return _target.beginToken;
+    }
+    return operator;
+  }
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_target)..add(operator)..add(_propertyName);
+
+  @override
+  Token get endToken => _propertyName.endToken;
+
+  @override
+  bool get isAssignable => true;
+
+  @override
+  bool get isCascaded =>
+      operator != null && operator.type == TokenType.PERIOD_PERIOD;
+
+  @override
+  int get precedence => 15;
+
+  @override
+  SimpleIdentifier get propertyName => _propertyName;
+
+  @override
+  void set propertyName(SimpleIdentifier identifier) {
+    _propertyName = _becomeParentOf(identifier);
+  }
+
+  @override
+  Expression get realTarget {
+    if (isCascaded) {
+      AstNode ancestor = parent;
+      while (ancestor is! CascadeExpression) {
+        if (ancestor == null) {
+          return _target;
+        }
+        ancestor = ancestor.parent;
+      }
+      return (ancestor as CascadeExpression).target;
+    }
+    return _target;
+  }
+
+  @override
+  Expression get target => _target;
+
+  @override
+  void set target(Expression expression) {
+    _target = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitPropertyAccess(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_target, visitor);
+    _safelyVisitChild(_propertyName, visitor);
+  }
+}
+
+/**
+ * The invocation of a constructor in the same class from within a constructor's
+ * initialization list.
+ *
+ * > redirectingConstructorInvocation ::=
+ * >     'this' ('.' identifier)? arguments
+ */
+class RedirectingConstructorInvocationImpl extends ConstructorInitializerImpl
+    implements RedirectingConstructorInvocation {
+  /**
+   * The token for the 'this' keyword.
+   */
+  Token thisKeyword;
+
+  /**
+   * The token for the period before the name of the constructor that is being
+   * invoked, or `null` if the unnamed constructor is being invoked.
+   */
+  Token period;
+
+  /**
+   * The name of the constructor that is being invoked, or `null` if the unnamed
+   * constructor is being invoked.
+   */
+  SimpleIdentifier _constructorName;
+
+  /**
+   * The list of arguments to the constructor.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement staticElement;
+
+  /**
+   * Initialize a newly created redirecting invocation to invoke the constructor
+   * with the given name with the given arguments. The [constructorName] can be
+   * `null` if the constructor being invoked is the unnamed constructor.
+   */
+  RedirectingConstructorInvocationImpl(this.thisKeyword, this.period,
+      SimpleIdentifier constructorName, ArgumentList argumentList) {
+    _constructorName = _becomeParentOf(constructorName);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  Token get beginToken => thisKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(thisKeyword)
+    ..add(period)
+    ..add(_constructorName)
+    ..add(_argumentList);
+
+  @override
+  SimpleIdentifier get constructorName => _constructorName;
+
+  @override
+  void set constructorName(SimpleIdentifier identifier) {
+    _constructorName = _becomeParentOf(identifier);
+  }
+
+  @override
+  Token get endToken => _argumentList.endToken;
+
+  @override
+  accept(AstVisitor visitor) =>
+      visitor.visitRedirectingConstructorInvocation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_constructorName, visitor);
+    _safelyVisitChild(_argumentList, visitor);
+  }
+}
+
+/**
+ * A rethrow expression.
+ *
+ * > rethrowExpression ::=
+ * >     'rethrow'
+ */
+class RethrowExpressionImpl extends ExpressionImpl
+    implements RethrowExpression {
+  /**
+   * The token representing the 'rethrow' keyword.
+   */
+  Token rethrowKeyword;
+
+  /**
+   * Initialize a newly created rethrow expression.
+   */
+  RethrowExpressionImpl(this.rethrowKeyword);
+
+  @override
+  Token get beginToken => rethrowKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(rethrowKeyword);
+
+  @override
+  Token get endToken => rethrowKeyword;
+
+  @override
+  int get precedence => 0;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitRethrowExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A return statement.
+ *
+ * > returnStatement ::=
+ * >     'return' [Expression]? ';'
+ */
+class ReturnStatementImpl extends StatementImpl implements ReturnStatement {
+  /**
+   * The token representing the 'return' keyword.
+   */
+  Token returnKeyword;
+
+  /**
+   * The expression computing the value to be returned, or `null` if no explicit
+   * value was provided.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created return statement. The [expression] can be `null`
+   * if no explicit value was provided.
+   */
+  ReturnStatementImpl(
+      this.returnKeyword, Expression expression, this.semicolon) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => returnKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(returnKeyword)..add(_expression)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * A script tag that can optionally occur at the beginning of a compilation unit.
+ *
+ * > scriptTag ::=
+ * >     '#!' (~NEWLINE)* NEWLINE
+ */
+class ScriptTagImpl extends AstNodeImpl implements ScriptTag {
+  /**
+   * The token representing this script tag.
+   */
+  Token scriptTag;
+
+  /**
+   * Initialize a newly created script tag.
+   */
+  ScriptTagImpl(this.scriptTag);
+
+  @override
+  Token get beginToken => scriptTag;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(scriptTag);
+
+  @override
+  Token get endToken => scriptTag;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitScriptTag(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A combinator that restricts the names being imported to those in a given list.
+ *
+ * > showCombinator ::=
+ * >     'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
+ */
+class ShowCombinatorImpl extends CombinatorImpl implements ShowCombinator {
+  /**
+   * The list of names from the library that are made visible by this combinator.
+   */
+  NodeList<SimpleIdentifier> _shownNames;
+
+  /**
+   * Initialize a newly created import show combinator.
+   */
+  ShowCombinatorImpl(Token keyword, List<SimpleIdentifier> shownNames)
+      : super(keyword) {
+    _shownNames = new NodeList<SimpleIdentifier>(this, shownNames);
+  }
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable get childEntities => new ChildEntities()
+    ..add(keyword)
+    ..addAll(_shownNames);
+
+  @override
+  Token get endToken => _shownNames.endToken;
+
+  @override
+  NodeList<SimpleIdentifier> get shownNames => _shownNames;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitShowCombinator(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _shownNames.accept(visitor);
+  }
+}
+
+/**
+ * A simple formal parameter.
+ *
+ * > simpleFormalParameter ::=
+ * >     ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier]
+ */
+class SimpleFormalParameterImpl extends NormalFormalParameterImpl
+    implements SimpleFormalParameter {
+  /**
+   * The token representing either the 'final', 'const' or 'var' keyword, or
+   * `null` if no keyword was used.
+   */
+  Token keyword;
+
+  /**
+   * The name of the declared type of the parameter, or `null` if the parameter
+   * does not have a declared type.
+   */
+  TypeName _type;
+
+  /**
+   * Initialize a newly created formal parameter. Either or both of the
+   * [comment] and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  SimpleFormalParameterImpl(Comment comment, List<Annotation> metadata,
+      this.keyword, TypeName type, SimpleIdentifier identifier)
+      : super(comment, metadata, identifier) {
+    _type = _becomeParentOf(type);
+  }
+
+  @override
+  Token get beginToken {
+    NodeList<Annotation> metadata = this.metadata;
+    if (!metadata.isEmpty) {
+      return metadata.beginToken;
+    } else if (keyword != null) {
+      return keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return identifier.beginToken;
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(keyword)..add(_type)..add(identifier);
+
+  @override
+  Token get endToken => identifier.endToken;
+
+  @override
+  bool get isConst =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.CONST;
+
+  @override
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
+      (keyword as KeywordToken).keyword == Keyword.FINAL;
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName typeName) {
+    _type = _becomeParentOf(typeName);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSimpleFormalParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_type, visitor);
+    _safelyVisitChild(identifier, visitor);
+  }
+}
+
+/**
+ * A simple identifier.
+ *
+ * > simpleIdentifier ::=
+ * >     initialCharacter internalCharacter*
+ * >
+ * > initialCharacter ::= '_' | '$' | letter
+ * >
+ * > internalCharacter ::= '_' | '$' | letter | digit
+ */
+class SimpleIdentifierImpl extends IdentifierImpl implements SimpleIdentifier {
+  /**
+   * The token representing the identifier.
+   */
+  Token token;
+
+  /**
+   * The element associated with this identifier based on static type
+   * information, or `null` if the AST structure has not been resolved or if
+   * this identifier could not be resolved.
+   */
+  Element _staticElement;
+
+  /**
+   * The element associated with this identifier based on propagated type
+   * information, or `null` if the AST structure has not been resolved or if
+   * this identifier could not be resolved.
+   */
+  Element _propagatedElement;
+
+  /**
+   * If this expression is both in a getter and setter context, the
+   * [AuxiliaryElements] will be set to hold onto the static and propagated
+   * information. The auxiliary element will hold onto the elements from the
+   * getter context.
+   */
+  AuxiliaryElements auxiliaryElements = null;
+
+  /**
+   * Initialize a newly created identifier.
+   */
+  SimpleIdentifierImpl(this.token);
+
+  @override
+  Token get beginToken => token;
+
+  @override
+  Element get bestElement {
+    if (_propagatedElement == null) {
+      return _staticElement;
+    }
+    return _propagatedElement;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(token);
+
+  @override
+  Token get endToken => token;
+
+  @override
+  bool get isQualified {
+    AstNode parent = this.parent;
+    if (parent is PrefixedIdentifier) {
+      return identical(parent.identifier, this);
+    }
+    if (parent is PropertyAccess) {
+      return identical(parent.propertyName, this);
+    }
+    if (parent is MethodInvocation) {
+      MethodInvocation invocation = parent;
+      return identical(invocation.methodName, this) &&
+          invocation.realTarget != null;
+    }
+    return false;
+  }
+
+  @override
+  bool get isSynthetic => token.isSynthetic;
+
+  @override
+  String get name => token.lexeme;
+
+  @override
+  int get precedence => 16;
+
+  @override
+  Element get propagatedElement => _propagatedElement;
+
+  @override
+  void set propagatedElement(Element element) {
+    _propagatedElement = _validateElement(element);
+  }
+
+  @override
+  Element get staticElement => _staticElement;
+
+  @override
+  void set staticElement(Element element) {
+    _staticElement = _validateElement(element);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSimpleIdentifier(this);
+
+  @override
+  bool inDeclarationContext() {
+    // TODO(brianwilkerson) Convert this to a getter.
+    AstNode parent = this.parent;
+    if (parent is CatchClause) {
+      CatchClause clause = parent;
+      return identical(this, clause.exceptionParameter) ||
+          identical(this, clause.stackTraceParameter);
+    } else if (parent is ClassDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is ClassTypeAlias) {
+      return identical(this, parent.name);
+    } else if (parent is ConstructorDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is DeclaredIdentifier) {
+      return identical(this, parent.identifier);
+    } else if (parent is EnumDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is EnumConstantDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is FunctionDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is FunctionTypeAlias) {
+      return identical(this, parent.name);
+    } else if (parent is ImportDirective) {
+      return identical(this, parent.prefix);
+    } else if (parent is Label) {
+      return identical(this, parent.label) &&
+          (parent.parent is LabeledStatement);
+    } else if (parent is MethodDeclaration) {
+      return identical(this, parent.name);
+    } else if (parent is FunctionTypedFormalParameter ||
+        parent is SimpleFormalParameter) {
+      return identical(this, (parent as NormalFormalParameter).identifier);
+    } else if (parent is TypeParameter) {
+      return identical(this, parent.name);
+    } else if (parent is VariableDeclaration) {
+      return identical(this, parent.name);
+    }
+    return false;
+  }
+
+  @override
+  bool inGetterContext() {
+    // TODO(brianwilkerson) Convert this to a getter.
+    AstNode parent = this.parent;
+    AstNode target = this;
+    // skip prefix
+    if (parent is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
+      if (identical(prefixed.prefix, this)) {
+        return true;
+      }
+      parent = prefixed.parent;
+      target = prefixed;
+    } else if (parent is PropertyAccess) {
+      PropertyAccess access = parent as PropertyAccess;
+      if (identical(access.target, this)) {
+        return true;
+      }
+      parent = access.parent;
+      target = access;
+    }
+    // skip label
+    if (parent is Label) {
+      return false;
+    }
+    // analyze usage
+    if (parent is AssignmentExpression) {
+      if (identical(parent.leftHandSide, target) &&
+          parent.operator.type == TokenType.EQ) {
+        return false;
+      }
+    }
+    if (parent is ForEachStatement) {
+      if (identical(parent.identifier, target)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool inSetterContext() {
+    // TODO(brianwilkerson) Convert this to a getter.
+    AstNode parent = this.parent;
+    AstNode target = this;
+    // skip prefix
+    if (parent is PrefixedIdentifier) {
+      PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
+      // if this is the prefix, then return false
+      if (identical(prefixed.prefix, this)) {
+        return false;
+      }
+      parent = prefixed.parent;
+      target = prefixed;
+    } else if (parent is PropertyAccess) {
+      PropertyAccess access = parent as PropertyAccess;
+      if (identical(access.target, this)) {
+        return false;
+      }
+      parent = access.parent;
+      target = access;
+    }
+    // analyze usage
+    if (parent is PrefixExpression) {
+      return parent.operator.type.isIncrementOperator;
+    } else if (parent is PostfixExpression) {
+      return true;
+    } else if (parent is AssignmentExpression) {
+      return identical(parent.leftHandSide, target);
+    } else if (parent is ForEachStatement) {
+      return identical(parent.identifier, target);
+    }
+    return false;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+
+  /**
+   * Return the given element if it is valid, or report the problem and return
+   * `null` if it is not appropriate.
+   *
+   * The [parent] is the parent of the element, used for reporting when there is
+   * a problem.
+   * The [isValid] is `true` if the element is appropriate.
+   * The [element] is the element to be associated with this identifier.
+   */
+  Element _returnOrReportElement(
+      AstNode parent, bool isValid, Element element) {
+    if (!isValid) {
+      AnalysisEngine.instance.logger.logInformation(
+          "Internal error: attempting to set the name of a ${parent.runtimeType} to a ${element.runtimeType}",
+          new CaughtException(new AnalysisException(), null));
+      return null;
+    }
+    return element;
+  }
+
+  /**
+   * Return the given [element] if it is an appropriate element based on the
+   * parent of this identifier, or `null` if it is not appropriate.
+   */
+  Element _validateElement(Element element) {
+    if (element == null) {
+      return null;
+    }
+    AstNode parent = this.parent;
+    if (parent is ClassDeclaration && identical(parent.name, this)) {
+      return _returnOrReportElement(parent, element is ClassElement, element);
+    } else if (parent is ClassTypeAlias && identical(parent.name, this)) {
+      return _returnOrReportElement(parent, element is ClassElement, element);
+    } else if (parent is DeclaredIdentifier &&
+        identical(parent.identifier, this)) {
+      return _returnOrReportElement(
+          parent, element is LocalVariableElement, element);
+    } else if (parent is FormalParameter &&
+        identical(parent.identifier, this)) {
+      return _returnOrReportElement(
+          parent, element is ParameterElement, element);
+    } else if (parent is FunctionDeclaration && identical(parent.name, this)) {
+      return _returnOrReportElement(
+          parent, element is ExecutableElement, element);
+    } else if (parent is FunctionTypeAlias && identical(parent.name, this)) {
+      return _returnOrReportElement(
+          parent, element is FunctionTypeAliasElement, element);
+    } else if (parent is MethodDeclaration && identical(parent.name, this)) {
+      return _returnOrReportElement(
+          parent, element is ExecutableElement, element);
+    } else if (parent is TypeParameter && identical(parent.name, this)) {
+      return _returnOrReportElement(
+          parent, element is TypeParameterElement, element);
+    } else if (parent is VariableDeclaration && identical(parent.name, this)) {
+      return _returnOrReportElement(
+          parent, element is VariableElement, element);
+    }
+    return element;
+  }
+}
+
+/**
+ * A string literal expression that does not contain any interpolations.
+ *
+ * > simpleStringLiteral ::=
+ * >     rawStringLiteral
+ * >   | basicStringLiteral
+ * >
+ * > rawStringLiteral ::=
+ * >     'r' basicStringLiteral
+ * >
+ * > simpleStringLiteral ::=
+ * >     multiLineStringLiteral
+ * >   | singleLineStringLiteral
+ * >
+ * > multiLineStringLiteral ::=
+ * >     "'''" characters "'''"
+ * >   | '"""' characters '"""'
+ * >
+ * > singleLineStringLiteral ::=
+ * >     "'" characters "'"
+ * >   | '"' characters '"'
+ */
+class SimpleStringLiteralImpl extends SingleStringLiteralImpl
+    implements SimpleStringLiteral {
+  /**
+   * The token representing the literal.
+   */
+  Token literal;
+
+  /**
+   * The value of the literal.
+   */
+  String _value;
+
+  /**
+   * Initialize a newly created simple string literal.
+   */
+  SimpleStringLiteralImpl(this.literal, String value) {
+    _value = StringUtilities.intern(value);
+  }
+
+  @override
+  Token get beginToken => literal;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(literal);
+
+  @override
+  int get contentsEnd => offset + _helper.end;
+
+  @override
+  int get contentsOffset => offset + _helper.start;
+
+  @override
+  Token get endToken => literal;
+
+  @override
+  bool get isMultiline => _helper.isMultiline;
+
+  @override
+  bool get isRaw => _helper.isRaw;
+
+  @override
+  bool get isSingleQuoted => _helper.isSingleQuoted;
+
+  @override
+  bool get isSynthetic => literal.isSynthetic;
+
+  @override
+  String get value => _value;
+
+  @override
+  void set value(String string) {
+    _value = StringUtilities.intern(_value);
+  }
+
+  StringLexemeHelper get _helper {
+    return new StringLexemeHelper(literal.lexeme, true, true);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSimpleStringLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+
+  @override
+  void _appendStringValue(StringBuffer buffer) {
+    buffer.write(value);
+  }
+}
+
+/**
+ * A single string literal expression.
+ *
+ * > singleStringLiteral ::=
+ * >     [SimpleStringLiteral]
+ * >   | [StringInterpolation]
+ */
+abstract class SingleStringLiteralImpl extends StringLiteralImpl
+    implements SingleStringLiteral {}
+
+/**
+ * A node that represents a statement.
+ *
+ * > statement ::=
+ * >     [Block]
+ * >   | [VariableDeclarationStatement]
+ * >   | [ForStatement]
+ * >   | [ForEachStatement]
+ * >   | [WhileStatement]
+ * >   | [DoStatement]
+ * >   | [SwitchStatement]
+ * >   | [IfStatement]
+ * >   | [TryStatement]
+ * >   | [BreakStatement]
+ * >   | [ContinueStatement]
+ * >   | [ReturnStatement]
+ * >   | [ExpressionStatement]
+ * >   | [FunctionDeclarationStatement]
+ */
+abstract class StatementImpl extends AstNodeImpl implements Statement {
+  @override
+  Statement get unlabeled => this;
+}
+
+/**
+ * A string interpolation literal.
+ *
+ * > stringInterpolation ::=
+ * >     ''' [InterpolationElement]* '''
+ * >   | '"' [InterpolationElement]* '"'
+ */
+class StringInterpolationImpl extends SingleStringLiteralImpl
+    implements StringInterpolation {
+  /**
+   * The elements that will be composed to produce the resulting string.
+   */
+  NodeList<InterpolationElement> _elements;
+
+  /**
+   * Initialize a newly created string interpolation expression.
+   */
+  StringInterpolationImpl(List<InterpolationElement> elements) {
+    _elements = new NodeList<InterpolationElement>(this, elements);
+  }
+
+  @override
+  Token get beginToken => _elements.beginToken;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..addAll(_elements);
+
+  @override
+  int get contentsEnd {
+    InterpolationString element = _elements.last;
+    return element.contentsEnd;
+  }
+
+  @override
+  int get contentsOffset {
+    InterpolationString element = _elements.first;
+    return element.contentsOffset;
+  }
+
+  /**
+   * Return the elements that will be composed to produce the resulting string.
+   */
+  NodeList<InterpolationElement> get elements => _elements;
+
+  @override
+  Token get endToken => _elements.endToken;
+
+  @override
+  bool get isMultiline => _firstHelper.isMultiline;
+
+  @override
+  bool get isRaw => false;
+
+  @override
+  bool get isSingleQuoted => _firstHelper.isSingleQuoted;
+
+  StringLexemeHelper get _firstHelper {
+    InterpolationString lastString = _elements.first;
+    String lexeme = lastString.contents.lexeme;
+    return new StringLexemeHelper(lexeme, true, false);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitStringInterpolation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _elements.accept(visitor);
+  }
+
+  @override
+  void _appendStringValue(StringBuffer buffer) {
+    throw new IllegalArgumentException();
+  }
+}
+
+/**
+ * A helper for analyzing string lexemes.
+ */
+class StringLexemeHelper {
+  final String lexeme;
+  final bool isFirst;
+  final bool isLast;
+
+  bool isRaw = false;
+  bool isSingleQuoted = false;
+  bool isMultiline = false;
+  int start = 0;
+  int end;
+
+  StringLexemeHelper(this.lexeme, this.isFirst, this.isLast) {
+    if (isFirst) {
+      isRaw = StringUtilities.startsWithChar(lexeme, 0x72);
+      if (isRaw) {
+        start++;
+      }
+      if (StringUtilities.startsWith3(lexeme, start, 0x27, 0x27, 0x27)) {
+        isSingleQuoted = true;
+        isMultiline = true;
+        start += 3;
+        start = _trimInitialWhitespace(start);
+      } else if (StringUtilities.startsWith3(lexeme, start, 0x22, 0x22, 0x22)) {
+        isSingleQuoted = false;
+        isMultiline = true;
+        start += 3;
+        start = _trimInitialWhitespace(start);
+      } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x27) {
+        isSingleQuoted = true;
+        isMultiline = false;
+        start++;
+      } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x22) {
+        isSingleQuoted = false;
+        isMultiline = false;
+        start++;
+      }
+    }
+    end = lexeme.length;
+    if (isLast) {
+      if (start + 3 <= end &&
+          (StringUtilities.endsWith3(lexeme, 0x22, 0x22, 0x22) ||
+              StringUtilities.endsWith3(lexeme, 0x27, 0x27, 0x27))) {
+        end -= 3;
+      } else if (start + 1 <= end &&
+          (StringUtilities.endsWithChar(lexeme, 0x22) ||
+              StringUtilities.endsWithChar(lexeme, 0x27))) {
+        end -= 1;
+      }
+    }
+  }
+
+  /**
+   * Given the [lexeme] for a multi-line string whose content begins at the
+   * given [start] index, return the index of the first character that is
+   * included in the value of the string. According to the specification:
+   *
+   * If the first line of a multiline string consists solely of the whitespace
+   * characters defined by the production WHITESPACE 20.1), possibly prefixed
+   * by \, then that line is ignored, including the new line at its end.
+   */
+  int _trimInitialWhitespace(int start) {
+    int length = lexeme.length;
+    int index = start;
+    while (index < length) {
+      int currentChar = lexeme.codeUnitAt(index);
+      if (currentChar == 0x0D) {
+        if (index + 1 < length && lexeme.codeUnitAt(index + 1) == 0x0A) {
+          return index + 2;
+        }
+        return index + 1;
+      } else if (currentChar == 0x0A) {
+        return index + 1;
+      } else if (currentChar == 0x5C) {
+        if (index + 1 >= length) {
+          return start;
+        }
+        currentChar = lexeme.codeUnitAt(index + 1);
+        if (currentChar != 0x0D &&
+            currentChar != 0x0A &&
+            currentChar != 0x09 &&
+            currentChar != 0x20) {
+          return start;
+        }
+      } else if (currentChar != 0x09 && currentChar != 0x20) {
+        return start;
+      }
+      index++;
+    }
+    return start;
+  }
+}
+
+/**
+ * A string literal expression.
+ *
+ * > stringLiteral ::=
+ * >     [SimpleStringLiteral]
+ * >   | [AdjacentStrings]
+ * >   | [StringInterpolation]
+ */
+abstract class StringLiteralImpl extends LiteralImpl implements StringLiteral {
+  @override
+  String get stringValue {
+    StringBuffer buffer = new StringBuffer();
+    try {
+      _appendStringValue(buffer);
+    } on IllegalArgumentException {
+      return null;
+    }
+    return buffer.toString();
+  }
+
+  /**
+   * Append the value of this string literal to the given [buffer]. Throw an
+   * [IllegalArgumentException] if the string is not a constant string without
+   * any string interpolation.
+   */
+  void _appendStringValue(StringBuffer buffer);
+}
+
+/**
+ * The invocation of a superclass' constructor from within a constructor's
+ * initialization list.
+ *
+ * > superInvocation ::=
+ * >     'super' ('.' [SimpleIdentifier])? [ArgumentList]
+ */
+class SuperConstructorInvocationImpl extends ConstructorInitializerImpl
+    implements SuperConstructorInvocation {
+  /**
+   * The token for the 'super' keyword.
+   */
+  Token superKeyword;
+
+  /**
+   * The token for the period before the name of the constructor that is being
+   * invoked, or `null` if the unnamed constructor is being invoked.
+   */
+  Token period;
+
+  /**
+   * The name of the constructor that is being invoked, or `null` if the unnamed
+   * constructor is being invoked.
+   */
+  SimpleIdentifier _constructorName;
+
+  /**
+   * The list of arguments to the constructor.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The element associated with the constructor based on static type
+   * information, or `null` if the AST structure has not been resolved or if the
+   * constructor could not be resolved.
+   */
+  ConstructorElement staticElement;
+
+  /**
+   * Initialize a newly created super invocation to invoke the inherited
+   * constructor with the given name with the given arguments. The [period] and
+   * [constructorName] can be `null` if the constructor being invoked is the
+   * unnamed constructor.
+   */
+  SuperConstructorInvocationImpl(this.superKeyword, this.period,
+      SimpleIdentifier constructorName, ArgumentList argumentList) {
+    _constructorName = _becomeParentOf(constructorName);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  Token get beginToken => superKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(superKeyword)
+    ..add(period)
+    ..add(_constructorName)
+    ..add(_argumentList);
+
+  @override
+  SimpleIdentifier get constructorName => _constructorName;
+
+  @override
+  void set constructorName(SimpleIdentifier identifier) {
+    _constructorName = _becomeParentOf(identifier);
+  }
+
+  @override
+  Token get endToken => _argumentList.endToken;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_constructorName, visitor);
+    _safelyVisitChild(_argumentList, visitor);
+  }
+}
+
+/**
+ * A super expression.
+ *
+ * > superExpression ::=
+ * >     'super'
+ */
+class SuperExpressionImpl extends ExpressionImpl implements SuperExpression {
+  /**
+   * The token representing the 'super' keyword.
+   */
+  Token superKeyword;
+
+  /**
+   * Initialize a newly created super expression.
+   */
+  SuperExpressionImpl(this.superKeyword);
+
+  @override
+  Token get beginToken => superKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(superKeyword);
+
+  @override
+  Token get endToken => superKeyword;
+
+  @override
+  int get precedence => 16;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSuperExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A case in a switch statement.
+ *
+ * > switchCase ::=
+ * >     [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
+ */
+class SwitchCaseImpl extends SwitchMemberImpl implements SwitchCase {
+  /**
+   * The expression controlling whether the statements will be executed.
+   */
+  Expression _expression;
+
+  /**
+   * Initialize a newly created switch case. The list of [labels] can be `null`
+   * if there are no labels.
+   */
+  SwitchCaseImpl(List<Label> labels, Token keyword, Expression expression,
+      Token colon, List<Statement> statements)
+      : super(labels, keyword, colon, statements) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..addAll(labels)
+    ..add(keyword)
+    ..add(_expression)
+    ..add(colon)
+    ..addAll(statements);
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSwitchCase(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    labels.accept(visitor);
+    _safelyVisitChild(_expression, visitor);
+    statements.accept(visitor);
+  }
+}
+
+/**
+ * The default case in a switch statement.
+ *
+ * > switchDefault ::=
+ * >     [SimpleIdentifier]* 'default' ':' [Statement]*
+ */
+class SwitchDefaultImpl extends SwitchMemberImpl implements SwitchDefault {
+  /**
+   * Initialize a newly created switch default. The list of [labels] can be
+   * `null` if there are no labels.
+   */
+  SwitchDefaultImpl(List<Label> labels, Token keyword, Token colon,
+      List<Statement> statements)
+      : super(labels, keyword, colon, statements);
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..addAll(labels)
+    ..add(keyword)
+    ..add(colon)
+    ..addAll(statements);
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSwitchDefault(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    labels.accept(visitor);
+    statements.accept(visitor);
+  }
+}
+
+/**
+ * An element within a switch statement.
+ *
+ * > switchMember ::=
+ * >     switchCase
+ * >   | switchDefault
+ */
+abstract class SwitchMemberImpl extends AstNodeImpl implements SwitchMember {
+  /**
+   * The labels associated with the switch member.
+   */
+  NodeList<Label> _labels;
+
+  /**
+   * The token representing the 'case' or 'default' keyword.
+   */
+  Token keyword;
+
+  /**
+   * The colon separating the keyword or the expression from the statements.
+   */
+  Token colon;
+
+  /**
+   * The statements that will be executed if this switch member is selected.
+   */
+  NodeList<Statement> _statements;
+
+  /**
+   * Initialize a newly created switch member. The list of [labels] can be
+   * `null` if there are no labels.
+   */
+  SwitchMemberImpl(List<Label> labels, this.keyword, this.colon,
+      List<Statement> statements) {
+    _labels = new NodeList<Label>(this, labels);
+    _statements = new NodeList<Statement>(this, statements);
+  }
+
+  @override
+  Token get beginToken {
+    if (!_labels.isEmpty) {
+      return _labels.beginToken;
+    }
+    return keyword;
+  }
+
+  @override
+  Token get endToken {
+    if (!_statements.isEmpty) {
+      return _statements.endToken;
+    }
+    return colon;
+  }
+
+  @override
+  NodeList<Label> get labels => _labels;
+
+  @override
+  NodeList<Statement> get statements => _statements;
+}
+
+/**
+ * A switch statement.
+ *
+ * > switchStatement ::=
+ * >     'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
+ */
+class SwitchStatementImpl extends StatementImpl implements SwitchStatement {
+  /**
+   * The token representing the 'switch' keyword.
+   */
+  Token switchKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The expression used to determine which of the switch members will be
+   * selected.
+   */
+  Expression _expression;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The left curly bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The switch members that can be selected by the expression.
+   */
+  NodeList<SwitchMember> _members;
+
+  /**
+   * The right curly bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created switch statement. The list of [members] can be
+   * `null` if there are no switch members.
+   */
+  SwitchStatementImpl(
+      this.switchKeyword,
+      this.leftParenthesis,
+      Expression expression,
+      this.rightParenthesis,
+      this.leftBracket,
+      List<SwitchMember> members,
+      this.rightBracket) {
+    _expression = _becomeParentOf(expression);
+    _members = new NodeList<SwitchMember>(this, members);
+  }
+
+  @override
+  Token get beginToken => switchKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(switchKeyword)
+    ..add(leftParenthesis)
+    ..add(_expression)
+    ..add(rightParenthesis)
+    ..add(leftBracket)
+    ..addAll(_members)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  NodeList<SwitchMember> get members => _members;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSwitchStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+    _members.accept(visitor);
+  }
+}
+
+/**
+ * A symbol literal expression.
+ *
+ * > symbolLiteral ::=
+ * >     '#' (operator | (identifier ('.' identifier)*))
+ */
+class SymbolLiteralImpl extends LiteralImpl implements SymbolLiteral {
+  /**
+   * The token introducing the literal.
+   */
+  Token poundSign;
+
+  /**
+   * The components of the literal.
+   */
+  final List<Token> components;
+
+  /**
+   * Initialize a newly created symbol literal.
+   */
+  SymbolLiteralImpl(this.poundSign, this.components);
+
+  @override
+  Token get beginToken => poundSign;
+
+  @override
+  // TODO(paulberry): add "." tokens.
+  Iterable get childEntities => new ChildEntities()
+    ..add(poundSign)
+    ..addAll(components);
+
+  @override
+  Token get endToken => components[components.length - 1];
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitSymbolLiteral(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A this expression.
+ *
+ * > thisExpression ::=
+ * >     'this'
+ */
+class ThisExpressionImpl extends ExpressionImpl implements ThisExpression {
+  /**
+   * The token representing the 'this' keyword.
+   */
+  Token thisKeyword;
+
+  /**
+   * Initialize a newly created this expression.
+   */
+  ThisExpressionImpl(this.thisKeyword);
+
+  @override
+  Token get beginToken => thisKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()..add(thisKeyword);
+
+  @override
+  Token get endToken => thisKeyword;
+
+  @override
+  int get precedence => 16;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitThisExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    // There are no children to visit.
+  }
+}
+
+/**
+ * A throw expression.
+ *
+ * > throwExpression ::=
+ * >     'throw' [Expression]
+ */
+class ThrowExpressionImpl extends ExpressionImpl implements ThrowExpression {
+  /**
+   * The token representing the 'throw' keyword.
+   */
+  Token throwKeyword;
+
+  /**
+   * The expression computing the exception to be thrown.
+   */
+  Expression _expression;
+
+  /**
+   * Initialize a newly created throw expression.
+   */
+  ThrowExpressionImpl(this.throwKeyword, Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken => throwKeyword;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(throwKeyword)..add(_expression);
+
+  @override
+  Token get endToken {
+    if (_expression != null) {
+      return _expression.endToken;
+    }
+    return throwKeyword;
+  }
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  int get precedence => 0;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitThrowExpression(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
+
+/**
+ * The declaration of one or more top-level variables of the same type.
+ *
+ * > topLevelVariableDeclaration ::=
+ * >     ('final' | 'const') type? staticFinalDeclarationList ';'
+ * >   | variableDeclaration ';'
+ */
+class TopLevelVariableDeclarationImpl extends CompilationUnitMemberImpl
+    implements TopLevelVariableDeclaration {
+  /**
+   * The top-level variables being declared.
+   */
+  VariableDeclarationList _variableList;
+
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created top-level variable declaration. Either or both
+   * of the [comment] and [metadata] can be `null` if the variable does not have
+   * the corresponding attribute.
+   */
+  TopLevelVariableDeclarationImpl(Comment comment, List<Annotation> metadata,
+      VariableDeclarationList variableList, this.semicolon)
+      : super(comment, metadata) {
+    _variableList = _becomeParentOf(variableList);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(_variableList)..add(semicolon);
+
+  @override
+  Element get element => null;
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => _variableList.beginToken;
+
+  @override
+  VariableDeclarationList get variables => _variableList;
+
+  @override
+  void set variables(VariableDeclarationList variables) {
+    _variableList = _becomeParentOf(variables);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_variableList, visitor);
+  }
+}
+
+/**
+ * A try statement.
+ *
+ * > tryStatement ::=
+ * >     'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
+ * >
+ * > finallyClause ::=
+ * >     'finally' [Block]
+ */
+class TryStatementImpl extends StatementImpl implements TryStatement {
+  /**
+   * The token representing the 'try' keyword.
+   */
+  Token tryKeyword;
+
+  /**
+   * The body of the statement.
+   */
+  Block _body;
+
+  /**
+   * The catch clauses contained in the try statement.
+   */
+  NodeList<CatchClause> _catchClauses;
+
+  /**
+   * The token representing the 'finally' keyword, or `null` if the statement
+   * does not contain a finally clause.
+   */
+  Token finallyKeyword;
+
+  /**
+   * The finally block contained in the try statement, or `null` if the
+   * statement does not contain a finally clause.
+   */
+  Block _finallyBlock;
+
+  /**
+   * Initialize a newly created try statement. The list of [catchClauses] can be
+   * `null` if there are no catch clauses. The [finallyKeyword] and
+   * [finallyBlock] can be `null` if there is no finally clause.
+   */
+  TryStatementImpl(this.tryKeyword, Block body, List<CatchClause> catchClauses,
+      this.finallyKeyword, Block finallyBlock) {
+    _body = _becomeParentOf(body);
+    _catchClauses = new NodeList<CatchClause>(this, catchClauses);
+    _finallyBlock = _becomeParentOf(finallyBlock);
+  }
+
+  @override
+  Token get beginToken => tryKeyword;
+
+  @override
+  Block get body => _body;
+
+  @override
+  void set body(Block block) {
+    _body = _becomeParentOf(block);
+  }
+
+  @override
+  NodeList<CatchClause> get catchClauses => _catchClauses;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(tryKeyword)
+    ..add(_body)
+    ..addAll(_catchClauses)
+    ..add(finallyKeyword)
+    ..add(_finallyBlock);
+
+  @override
+  Token get endToken {
+    if (_finallyBlock != null) {
+      return _finallyBlock.endToken;
+    } else if (finallyKeyword != null) {
+      return finallyKeyword;
+    } else if (!_catchClauses.isEmpty) {
+      return _catchClauses.endToken;
+    }
+    return _body.endToken;
+  }
+
+  @override
+  Block get finallyBlock => _finallyBlock;
+
+  @override
+  void set finallyBlock(Block block) {
+    _finallyBlock = _becomeParentOf(block);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTryStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_body, visitor);
+    _catchClauses.accept(visitor);
+    _safelyVisitChild(_finallyBlock, visitor);
+  }
+}
+
+/**
+ * The declaration of a type alias.
+ *
+ * > typeAlias ::=
+ * >     'typedef' typeAliasBody
+ * >
+ * > typeAliasBody ::=
+ * >     classTypeAlias
+ * >   | functionTypeAlias
+ */
+abstract class TypeAliasImpl extends NamedCompilationUnitMemberImpl
+    implements TypeAlias {
+  /**
+   * The token representing the 'typedef' keyword.
+   */
+  Token typedefKeyword;
+
+  /**
+   * The semicolon terminating the declaration.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created type alias. Either or both of the [comment] and
+   * [metadata] can be `null` if the declaration does not have the corresponding
+   * attribute.
+   */
+  TypeAliasImpl(Comment comment, List<Annotation> metadata, this.typedefKeyword,
+      SimpleIdentifier name, this.semicolon)
+      : super(comment, metadata, name);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
+}
+
+/**
+ * A list of type arguments.
+ *
+ * > typeArguments ::=
+ * >     '<' typeName (',' typeName)* '>'
+ */
+class TypeArgumentListImpl extends AstNodeImpl implements TypeArgumentList {
+  /**
+   * The left bracket.
+   */
+  Token leftBracket;
+
+  /**
+   * The type arguments associated with the type.
+   */
+  NodeList<TypeName> _arguments;
+
+  /**
+   * The right bracket.
+   */
+  Token rightBracket;
+
+  /**
+   * Initialize a newly created list of type arguments.
+   */
+  TypeArgumentListImpl(
+      this.leftBracket, List<TypeName> arguments, this.rightBracket) {
+    _arguments = new NodeList<TypeName>(this, arguments);
+  }
+
+  @override
+  NodeList<TypeName> get arguments => _arguments;
+
+  @override
+  Token get beginToken => leftBracket;
+
+  @override
+  // TODO(paulberry): Add commas.
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftBracket)
+    ..addAll(_arguments)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTypeArgumentList(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _arguments.accept(visitor);
+  }
+}
+
+/**
+ * A literal that has a type associated with it.
+ *
+ * > typedLiteral ::=
+ * >     [ListLiteral]
+ * >   | [MapLiteral]
+ */
+abstract class TypedLiteralImpl extends LiteralImpl implements TypedLiteral {
+  /**
+   * The token representing the 'const' keyword, or `null` if the literal is not
+   * a constant.
+   */
+  Token constKeyword;
+
+  /**
+   * The type argument associated with this literal, or `null` if no type
+   * arguments were declared.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
+   * Initialize a newly created typed literal. The [constKeyword] can be `null`\
+   * if the literal is not a constant. The [typeArguments] can be `null` if no
+   * type arguments were declared.
+   */
+  TypedLiteralImpl(this.constKeyword, TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  @override
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  ChildEntities get _childEntities =>
+      new ChildEntities()..add(constKeyword)..add(_typeArguments);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_typeArguments, visitor);
+  }
+}
+
+/**
+ * The name of a type, which can optionally include type arguments.
+ *
+ * > typeName ::=
+ * >     [Identifier] typeArguments?
+ */
+class TypeNameImpl extends AstNodeImpl implements TypeName {
+  /**
+   * The name of the type.
+   */
+  Identifier _name;
+
+  /**
+   * The type arguments associated with the type, or `null` if there are no type
+   * arguments.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
+   * The type being named, or `null` if the AST structure has not been resolved.
+   */
+  DartType type;
+
+  /**
+   * Initialize a newly created type name. The [typeArguments] can be `null` if
+   * there are no type arguments.
+   */
+  TypeNameImpl(Identifier name, TypeArgumentList typeArguments) {
+    _name = _becomeParentOf(name);
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  @override
+  Token get beginToken => _name.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_name)..add(_typeArguments);
+
+  @override
+  Token get endToken {
+    if (_typeArguments != null) {
+      return _typeArguments.endToken;
+    }
+    return _name.endToken;
+  }
+
+  @override
+  bool get isDeferred {
+    Identifier identifier = name;
+    if (identifier is! PrefixedIdentifier) {
+      return false;
+    }
+    return (identifier as PrefixedIdentifier).isDeferred;
+  }
+
+  @override
+  bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
+
+  @override
+  Identifier get name => _name;
+
+  @override
+  void set name(Identifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  @override
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTypeName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeArguments, visitor);
+  }
+}
+
+/**
+ * A type parameter.
+ *
+ * > typeParameter ::=
+ * >     [SimpleIdentifier] ('extends' [TypeName])?
+ */
+class TypeParameterImpl extends DeclarationImpl implements TypeParameter {
+  /**
+   * The name of the type parameter.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * The token representing the 'extends' keyword, or `null` if there is no
+   * explicit upper bound.
+   */
+  Token extendsKeyword;
+
+  /**
+   * The name of the upper bound for legal arguments, or `null` if there is no
+   * explicit upper bound.
+   */
+  TypeName _bound;
+
+  /**
+   * Initialize a newly created type parameter. Either or both of the [comment]
+   * and [metadata] can be `null` if the parameter does not have the
+   * corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
+   * the parameter does not have an upper bound.
+   */
+  TypeParameterImpl(Comment comment, List<Annotation> metadata,
+      SimpleIdentifier name, this.extendsKeyword, TypeName bound)
+      : super(comment, metadata) {
+    _name = _becomeParentOf(name);
+    _bound = _becomeParentOf(bound);
+  }
+
+  @override
+  TypeName get bound => _bound;
+
+  @override
+  void set bound(TypeName typeName) {
+    _bound = _becomeParentOf(typeName);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(_name)..add(extendsKeyword)..add(_bound);
+
+  @override
+  TypeParameterElement get element =>
+      _name != null ? (_name.staticElement as TypeParameterElement) : null;
+
+  @override
+  Token get endToken {
+    if (_bound == null) {
+      return _name.endToken;
+    }
+    return _bound.endToken;
+  }
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTypeParameter(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_bound, visitor);
+  }
+}
+
+/**
+ * Type parameters within a declaration.
+ *
+ * > typeParameterList ::=
+ * >     '<' [TypeParameter] (',' [TypeParameter])* '>'
+ */
+class TypeParameterListImpl extends AstNodeImpl implements TypeParameterList {
+  /**
+   * The left angle bracket.
+   */
+  final Token leftBracket;
+
+  /**
+   * The type parameters in the list.
+   */
+  NodeList<TypeParameter> _typeParameters;
+
+  /**
+   * The right angle bracket.
+   */
+  final Token rightBracket;
+
+  /**
+   * Initialize a newly created list of type parameters.
+   */
+  TypeParameterListImpl(
+      this.leftBracket, List<TypeParameter> typeParameters, this.rightBracket) {
+    _typeParameters = new NodeList<TypeParameter>(this, typeParameters);
+  }
+
+  @override
+  Token get beginToken => leftBracket;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(leftBracket)
+    ..addAll(_typeParameters)
+    ..add(rightBracket);
+
+  @override
+  Token get endToken => rightBracket;
+
+  @override
+  NodeList<TypeParameter> get typeParameters => _typeParameters;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitTypeParameterList(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _typeParameters.accept(visitor);
+  }
+}
+
+/**
+ * A directive that references a URI.
+ *
+ * > uriBasedDirective ::=
+ * >     [ExportDirective]
+ * >   | [ImportDirective]
+ * >   | [PartDirective]
+ */
+abstract class UriBasedDirectiveImpl extends DirectiveImpl
+    implements UriBasedDirective {
+  /**
+   * The prefix of a URI using the `dart-ext` scheme to reference a native code
+   * library.
+   */
+  static String _DART_EXT_SCHEME = "dart-ext:";
+
+  /**
+   * The URI referenced by this directive.
+   */
+  StringLiteral _uri;
+
+  /**
+   * The content of the URI.
+   */
+  String uriContent;
+
+  /**
+   * The source to which the URI was resolved.
+   */
+  Source source;
+
+  /**
+   * Initialize a newly create URI-based directive. Either or both of the
+   * [comment] and [metadata] can be `null` if the directive does not have the
+   * corresponding attribute.
+   */
+  UriBasedDirectiveImpl(
+      Comment comment, List<Annotation> metadata, StringLiteral uri)
+      : super(comment, metadata) {
+    _uri = _becomeParentOf(uri);
+  }
+
+  @override
+  StringLiteral get uri => _uri;
+
+  @override
+  void set uri(StringLiteral uri) {
+    _uri = _becomeParentOf(uri);
+  }
+
+  @override
+  UriValidationCode validate() {
+    StringLiteral uriLiteral = uri;
+    if (uriLiteral is StringInterpolation) {
+      return UriValidationCode.URI_WITH_INTERPOLATION;
+    }
+    String uriContent = this.uriContent;
+    if (uriContent == null) {
+      return UriValidationCode.INVALID_URI;
+    }
+    if (this is ImportDirective && uriContent.startsWith(_DART_EXT_SCHEME)) {
+      return UriValidationCode.URI_WITH_DART_EXT_SCHEME;
+    }
+    try {
+      parseUriWithException(Uri.encodeFull(uriContent));
+    } on URISyntaxException {
+      return UriValidationCode.INVALID_URI;
+    }
+    return null;
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_uri, visitor);
+  }
+}
+
+/**
+ * Validation codes returned by [UriBasedDirective.validate].
+ */
+class UriValidationCodeImpl implements UriValidationCode {
+  static const UriValidationCode INVALID_URI =
+      const UriValidationCodeImpl('INVALID_URI');
+
+  static const UriValidationCode URI_WITH_INTERPOLATION =
+      const UriValidationCodeImpl('URI_WITH_INTERPOLATION');
+
+  static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
+      const UriValidationCodeImpl('URI_WITH_DART_EXT_SCHEME');
+
+  /**
+   * The name of the validation code.
+   */
+  final String name;
+
+  /**
+   * Initialize a newly created validation code to have the given [name].
+   */
+  const UriValidationCodeImpl(this.name);
+
+  @override
+  String toString() => name;
+}
+
+/**
+ * An identifier that has an initial value associated with it. Instances of this
+ * class are always children of the class [VariableDeclarationList].
+ *
+ * > variableDeclaration ::=
+ * >     [SimpleIdentifier] ('=' [Expression])?
+ *
+ * TODO(paulberry): the grammar does not allow metadata to be associated with
+ * a VariableDeclaration, and currently we don't record comments for it either.
+ * Consider changing the class hierarchy so that [VariableDeclaration] does not
+ * extend [Declaration].
+ */
+class VariableDeclarationImpl extends DeclarationImpl
+    implements VariableDeclaration {
+  /**
+   * The name of the variable being declared.
+   */
+  SimpleIdentifier _name;
+
+  /**
+   * The equal sign separating the variable name from the initial value, or
+   * `null` if the initial value was not specified.
+   */
+  Token equals;
+
+  /**
+   * The expression used to compute the initial value for the variable, or
+   * `null` if the initial value was not specified.
+   */
+  Expression _initializer;
+
+  /**
+   * Initialize a newly created variable declaration. The [equals] and
+   * [initializer] can be `null` if there is no initializer.
+   */
+  VariableDeclarationImpl(
+      SimpleIdentifier name, this.equals, Expression initializer)
+      : super(null, null) {
+    _name = _becomeParentOf(name);
+    _initializer = _becomeParentOf(initializer);
+  }
+
+  @override
+  Iterable get childEntities =>
+      super._childEntities..add(_name)..add(equals)..add(_initializer);
+
+  /**
+   * This overridden implementation of getDocumentationComment() looks in the
+   * grandparent node for Dartdoc comments if no documentation is specifically
+   * available on the node.
+   */
+  @override
+  Comment get documentationComment {
+    Comment comment = super.documentationComment;
+    if (comment == null) {
+      if (parent != null && parent.parent != null) {
+        AstNode node = parent.parent;
+        if (node is AnnotatedNode) {
+          return node.documentationComment;
+        }
+      }
+    }
+    return comment;
+  }
+
+  @override
+  VariableElement get element =>
+      _name != null ? (_name.staticElement as VariableElement) : null;
+
+  @override
+  Token get endToken {
+    if (_initializer != null) {
+      return _initializer.endToken;
+    }
+    return _name.endToken;
+  }
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
+
+  @override
+  Expression get initializer => _initializer;
+
+  @override
+  void set initializer(Expression expression) {
+    _initializer = _becomeParentOf(expression);
+  }
+
+  @override
+  bool get isConst {
+    AstNode parent = this.parent;
+    return parent is VariableDeclarationList && parent.isConst;
+  }
+
+  @override
+  bool get isFinal {
+    AstNode parent = this.parent;
+    return parent is VariableDeclarationList && parent.isFinal;
+  }
+
+  @override
+  SimpleIdentifier get name => _name;
+
+  @override
+  void set name(SimpleIdentifier identifier) {
+    _name = _becomeParentOf(identifier);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitVariableDeclaration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_initializer, visitor);
+  }
+}
+
+/**
+ * The declaration of one or more variables of the same type.
+ *
+ * > variableDeclarationList ::=
+ * >     finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
+ * >
+ * > finalConstVarOrType ::=
+ * >   | 'final' [TypeName]?
+ * >   | 'const' [TypeName]?
+ * >   | 'var'
+ * >   | [TypeName]
+ */
+class VariableDeclarationListImpl extends AnnotatedNodeImpl
+    implements VariableDeclarationList {
+  /**
+   * The token representing the 'final', 'const' or 'var' keyword, or `null` if
+   * no keyword was included.
+   */
+  Token keyword;
+
+  /**
+   * The type of the variables being declared, or `null` if no type was provided.
+   */
+  TypeName _type;
+
+  /**
+   * A list containing the individual variables being declared.
+   */
+  NodeList<VariableDeclaration> _variables;
+
+  /**
+   * Initialize a newly created variable declaration list. Either or both of the
+   * [comment] and [metadata] can be `null` if the variable list does not have
+   * the corresponding attribute. The [keyword] can be `null` if a type was
+   * specified. The [type] must be `null` if the keyword is 'var'.
+   */
+  VariableDeclarationListImpl(Comment comment, List<Annotation> metadata,
+      this.keyword, TypeName type, List<VariableDeclaration> variables)
+      : super(comment, metadata) {
+    _type = _becomeParentOf(type);
+    _variables = new NodeList<VariableDeclaration>(this, variables);
+  }
+
+  @override
+  // TODO(paulberry): include commas.
+  Iterable get childEntities => super._childEntities
+    ..add(keyword)
+    ..add(_type)
+    ..addAll(_variables);
+
+  @override
+  Token get endToken => _variables.endToken;
+
+  @override
+  Token get firstTokenAfterCommentAndMetadata {
+    if (keyword != null) {
+      return keyword;
+    } else if (_type != null) {
+      return _type.beginToken;
+    }
+    return _variables.beginToken;
+  }
+
+  @override
+  bool get isConst =>
+      keyword is KeywordToken &&
+      (keyword as KeywordToken).keyword == Keyword.CONST;
+
+  @override
+  bool get isFinal =>
+      keyword is KeywordToken &&
+      (keyword as KeywordToken).keyword == Keyword.FINAL;
+
+  @override
+  TypeName get type => _type;
+
+  @override
+  void set type(TypeName typeName) {
+    _type = _becomeParentOf(typeName);
+  }
+
+  @override
+  NodeList<VariableDeclaration> get variables => _variables;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitVariableDeclarationList(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    super.visitChildren(visitor);
+    _safelyVisitChild(_type, visitor);
+    _variables.accept(visitor);
+  }
+}
+
+/**
+ * A list of variables that are being declared in a context where a statement is
+ * required.
+ *
+ * > variableDeclarationStatement ::=
+ * >     [VariableDeclarationList] ';'
+ */
+class VariableDeclarationStatementImpl extends StatementImpl
+    implements VariableDeclarationStatement {
+  /**
+   * The variables being declared.
+   */
+  VariableDeclarationList _variableList;
+
+  /**
+   * The semicolon terminating the statement.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created variable declaration statement.
+   */
+  VariableDeclarationStatementImpl(
+      VariableDeclarationList variableList, this.semicolon) {
+    _variableList = _becomeParentOf(variableList);
+  }
+
+  @override
+  Token get beginToken => _variableList.beginToken;
+
+  @override
+  Iterable get childEntities =>
+      new ChildEntities()..add(_variableList)..add(semicolon);
+
+  @override
+  Token get endToken => semicolon;
+
+  @override
+  VariableDeclarationList get variables => _variableList;
+
+  @override
+  void set variables(VariableDeclarationList variables) {
+    _variableList = _becomeParentOf(variables);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitVariableDeclarationStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_variableList, visitor);
+  }
+}
+
+/**
+ * A while statement.
+ *
+ * > whileStatement ::=
+ * >     'while' '(' [Expression] ')' [Statement]
+ */
+class WhileStatementImpl extends StatementImpl implements WhileStatement {
+  /**
+   * The token representing the 'while' keyword.
+   */
+  Token whileKeyword;
+
+  /**
+   * The left parenthesis.
+   */
+  Token leftParenthesis;
+
+  /**
+   * The expression used to determine whether to execute the body of the loop.
+   */
+  Expression _condition;
+
+  /**
+   * The right parenthesis.
+   */
+  Token rightParenthesis;
+
+  /**
+   * The body of the loop.
+   */
+  Statement _body;
+
+  /**
+   * Initialize a newly created while statement.
+   */
+  WhileStatementImpl(this.whileKeyword, this.leftParenthesis,
+      Expression condition, this.rightParenthesis, Statement body) {
+    _condition = _becomeParentOf(condition);
+    _body = _becomeParentOf(body);
+  }
+
+  @override
+  Token get beginToken => whileKeyword;
+
+  @override
+  Statement get body => _body;
+
+  @override
+  void set body(Statement statement) {
+    _body = _becomeParentOf(statement);
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(whileKeyword)
+    ..add(leftParenthesis)
+    ..add(_condition)
+    ..add(rightParenthesis)
+    ..add(_body);
+
+  @override
+  Expression get condition => _condition;
+
+  @override
+  void set condition(Expression expression) {
+    _condition = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get endToken => _body.endToken;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(_body, visitor);
+  }
+}
+
+/**
+ * The with clause in a class declaration.
+ *
+ * > withClause ::=
+ * >     'with' [TypeName] (',' [TypeName])*
+ */
+class WithClauseImpl extends AstNodeImpl implements WithClause {
+  /**
+   * The token representing the 'with' keyword.
+   */
+  Token withKeyword;
+
+  /**
+   * The names of the mixins that were specified.
+   */
+  NodeList<TypeName> _mixinTypes;
+
+  /**
+   * Initialize a newly created with clause.
+   */
+  WithClauseImpl(this.withKeyword, List<TypeName> mixinTypes) {
+    _mixinTypes = new NodeList<TypeName>(this, mixinTypes);
+  }
+
+  @override
+  Token get beginToken => withKeyword;
+
+  @override
+  // TODO(paulberry): add commas.
+  Iterable get childEntities => new ChildEntities()
+    ..add(withKeyword)
+    ..addAll(_mixinTypes);
+
+  @override
+  Token get endToken => _mixinTypes.endToken;
+
+  @override
+  NodeList<TypeName> get mixinTypes => _mixinTypes;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitWithClause(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _mixinTypes.accept(visitor);
+  }
+}
+
+/**
+ * A yield statement.
+ *
+ * > yieldStatement ::=
+ * >     'yield' '*'? [Expression] ‘;’
+ */
+class YieldStatementImpl extends StatementImpl implements YieldStatement {
+  /**
+   * The 'yield' keyword.
+   */
+  Token yieldKeyword;
+
+  /**
+   * The star optionally following the 'yield' keyword.
+   */
+  Token star;
+
+  /**
+   * The expression whose value will be yielded.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon following the expression.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created yield expression. The [star] can be `null` if no
+   * star was provided.
+   */
+  YieldStatementImpl(
+      this.yieldKeyword, this.star, Expression expression, this.semicolon) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  Token get beginToken {
+    if (yieldKeyword != null) {
+      return yieldKeyword;
+    }
+    return _expression.beginToken;
+  }
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(yieldKeyword)
+    ..add(star)
+    ..add(_expression)
+    ..add(semicolon);
+
+  @override
+  Token get endToken {
+    if (semicolon != null) {
+      return semicolon;
+    }
+    return _expression.endToken;
+  }
+
+  @override
+  Expression get expression => _expression;
+
+  @override
+  void set expression(Expression expression) {
+    _expression = _becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitYieldStatement(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_expression, visitor);
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f0435eb..1a21746 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -2,13 +2,13 @@
 // 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.generated.ast;
+library analyzer.src.dart.ast.utilities;
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.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/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 71030e7..e319acf 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7,11 +7,12 @@
 import 'dart:collection';
 import 'dart:math' show min;
 
+import 'package:analyzer/dart/ast/ast.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/dart/ast/utilities.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'
@@ -335,7 +336,22 @@
   }
 
   @override
-  bool get isValidMixin => hasModifier(Modifier.MIXIN);
+  bool get isValidMixin {
+    if (!context.analysisOptions.enableSuperMixins) {
+      if (hasReferenceToSuper) {
+        return false;
+      }
+      if (!supertype.isObject) {
+        return false;
+      }
+    }
+    for (ConstructorElement constructor in constructors) {
+      if (!constructor.isSynthetic && !constructor.isFactory) {
+        return false;
+      }
+    }
+    return true;
+  }
 
   @override
   ElementKind get kind => ElementKind.CLASS;
@@ -385,13 +401,6 @@
     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);
 
@@ -2511,6 +2520,13 @@
    */
   FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
 
+  /**
+   * Initialize a newly created parameter element to have the given [name] and
+   * [offset].
+   */
+  FieldFormalParameterElementImpl.forNameAndOffset(String name, int nameOffset)
+      : super(name, nameOffset);
+
   @override
   bool get isInitializingFormal => true;
 
@@ -3095,6 +3111,9 @@
       entryPoint != null && isOrImportsBrowserLibrary;
 
   @override
+  bool get isDartAsync => name == "dart.async";
+
+  @override
   bool get isDartCore => name == "dart.core";
 
   @override
@@ -3641,6 +3660,148 @@
 }
 
 /**
+ * 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 is a mixin application.
+   */
+  static const Modifier MIXIN_APPLICATION =
+      const Modifier('MIXIN_APPLICATION', 12);
+
+  /**
+   * 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', 13);
+
+  /**
+   * 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', 14);
+
+  /**
+   * Indicates that a class contains an explicit reference to 'super'.
+   */
+  static const Modifier REFERENCES_SUPER =
+      const Modifier('REFERENCES_SUPER', 15);
+
+  /**
+   * Indicates that the pseudo-modifier 'set' was applied to the element.
+   */
+  static const Modifier SETTER = const Modifier('SETTER', 16);
+
+  /**
+   * Indicates that the modifier 'static' was applied to the element.
+   */
+  static const Modifier STATIC = const Modifier('STATIC', 17);
+
+  /**
+   * 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', 18);
+
+  static const List<Modifier> values = const [
+    ABSTRACT,
+    ASYNCHRONOUS,
+    CONST,
+    DEFERRED,
+    ENUM,
+    EXTERNAL,
+    FACTORY,
+    FINAL,
+    GENERATOR,
+    GETTER,
+    HAS_EXT_URI,
+    IMPLICIT_TYPE,
+    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 concrete implementation of a [MultiplyDefinedElement].
  */
 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 75dcee6..bc073d8 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -4,11 +4,11 @@
 
 library analyzer.src.dart.element.member;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 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'
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index b804339..0f8ec27 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -14,6 +14,7 @@
     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/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -234,15 +235,6 @@
   List<TypeParameterElement> get boundTypeParameters => typeFormals;
 
   @override
-  List<TypeParameterElement> get typeFormals {
-    if (_isInstantiated) {
-      return TypeParameterElement.EMPTY_LIST;
-    } else {
-      return element?.typeParameters ?? TypeParameterElement.EMPTY_LIST;
-    }
-  }
-
-  @override
   String get displayName {
     String name = this.name;
     if (name == null || name.length == 0) {
@@ -496,6 +488,15 @@
   }
 
   @override
+  List<TypeParameterElement> get typeFormals {
+    if (_isInstantiated) {
+      return TypeParameterElement.EMPTY_LIST;
+    } else {
+      return element?.typeParameters ?? TypeParameterElement.EMPTY_LIST;
+    }
+  }
+
+  @override
   List<TypeParameterElement> get typeParameters {
     if (_typeParameters == null) {
       // Combine the generic type variables from all enclosing contexts, except
@@ -1194,6 +1195,15 @@
   }
 
   @override
+  bool get isDartAsyncFuture {
+    ClassElement element = this.element;
+    if (element == null) {
+      return false;
+    }
+    return element.name == "Future" && element.library.isDartAsync;
+  }
+
+  @override
   bool get isDartCoreFunction {
     ClassElement element = this.element;
     if (element == null) {
@@ -1280,6 +1290,35 @@
   }
 
   @override
+  DartType flattenFutures(TypeSystem typeSystem) {
+    // Implement the case: "If T = Future<S> then flatten(T) = flatten(S)."
+    if (isDartAsyncFuture && typeArguments.isNotEmpty) {
+      return typeArguments[0].flattenFutures(typeSystem);
+    }
+
+    // Implement the case: "Otherwise if T <: Future then let S be a type
+    // such that T << Future<S> and for all R, if T << Future<R> then S << R.
+    // Then flatten(T) = S."
+    //
+    // In other words, given the set of all types R such that T << Future<R>,
+    // let S be the most specific of those types, if any such S exists.
+    //
+    // Since we only care about the most specific type, it is sufficent to
+    // look at the types appearing as a parameter to Future in the type
+    // hierarchy of T.  We don't need to consider the supertypes of those
+    // types, since they are by definition less specific.
+    List<DartType> candidateTypes =
+        _searchTypeHierarchyForFutureTypeParameters();
+    DartType flattenResult = _findMostSpecificType(candidateTypes, typeSystem);
+    if (flattenResult != null) {
+      return flattenResult;
+    }
+
+    // Implement the case: "In any other circumstance, flatten(T) = T."
+    return this;
+  }
+
+  @override
   PropertyAccessorElement getGetter(String getterName) =>
       PropertyAccessorMember.from(element.getGetter(getterName), this);
 
@@ -1678,6 +1717,34 @@
     if (JavaArrays.equals(newTypeArguments, typeArguments)) {
       return this;
     }
+
+    if (isDartAsyncFuture && newTypeArguments.isNotEmpty) {
+      //
+      // In strong mode interpret Future< T > as Future< flatten(T) >
+      //
+      // For example, Future<Future<T>> will flatten to Future<T>.
+      //
+      // In the Dart 3rd edition spec, this flatten operation is used for
+      // `async` and `await`. In strong mode, we extend it to all Future<T>
+      // instantiations. This allows typing of Future-related operations
+      // in dart:async in a way that matches their runtime behavior and provides
+      // precise return types for users of these APIs.
+      //
+      // For example:
+      //
+      //     abstract class Future<T> {
+      //       Future<S> then<S>(S onValue(T value), ...);
+      //     }
+      //
+      // Given a call where S <: Future<R> for some R, we will need to flatten
+      // the return type so it is Future< flatten(S) >, yielding Future<R>.
+      //
+      if (element.library.context.analysisOptions.strongMode) {
+        TypeImpl t = newTypeArguments[0];
+        newTypeArguments[0] = t.flattenFutures(new StrongTypeSystemImpl());
+      }
+    }
+
     InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
     newType.typeArguments = newTypeArguments;
     return newType;
@@ -1688,6 +1755,31 @@
       substitute2(argumentTypes, typeArguments);
 
   /**
+   * Starting from this type, search its class hierarchy for types of the form
+   * Future<R>, and return a list of the resulting R's.
+   */
+  List<DartType> _searchTypeHierarchyForFutureTypeParameters() {
+    List<DartType> result = <DartType>[];
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    void recurse(InterfaceTypeImpl type) {
+      if (type.isDartAsyncFuture && type.typeArguments.isNotEmpty) {
+        result.add(type.typeArguments[0]);
+      }
+      if (visitedClasses.add(type.element)) {
+        if (type.superclass != null) {
+          recurse(type.superclass);
+        }
+        for (InterfaceType interface in type.interfaces) {
+          recurse(interface);
+        }
+        visitedClasses.remove(type.element);
+      }
+    }
+    recurse(this);
+    return result;
+  }
+
+  /**
    * Compute the least upper bound of types [i] and [j], both of which are
    * known to be interface types.
    *
@@ -1846,6 +1938,61 @@
   }
 
   /**
+   * If there is a single type which is at least as specific as all of the
+   * types in [types], return it.  Otherwise return `null`.
+   */
+  static DartType _findMostSpecificType(List<DartType> types, TypeSystem typeSystem) {
+    // The << relation ("more specific than") is a partial ordering on types,
+    // so to find the most specific type of a set, we keep a bucket of the most
+    // specific types seen so far such that no type in the bucket is more
+    // specific than any other type in the bucket.
+    List<DartType> bucket = <DartType>[];
+
+    // Then we consider each type in turn.
+    for (DartType type in types) {
+      // If any existing type in the bucket is more specific than this type,
+      // then we can ignore this type.
+      if (bucket.any((DartType t) => typeSystem.isMoreSpecificThan(t, type))) {
+        continue;
+      }
+      // Otherwise, we need to add this type to the bucket and remove any types
+      // that are less specific than it.
+      bool added = false;
+      int i = 0;
+      while (i < bucket.length) {
+        if (typeSystem.isMoreSpecificThan(type, bucket[i])) {
+          if (added) {
+            if (i < bucket.length - 1) {
+              bucket[i] = bucket.removeLast();
+            } else {
+              bucket.removeLast();
+            }
+          } else {
+            bucket[i] = type;
+            i++;
+            added = true;
+          }
+        } else {
+          i++;
+        }
+      }
+      if (!added) {
+        bucket.add(type);
+      }
+    }
+
+    // Now that we are finished, if there is exactly one type left in the
+    // bucket, it is the most specific type.
+    if (bucket.length == 1) {
+      return bucket[0];
+    }
+
+    // Otherwise, there is no single type that is more specific than the
+    // others.
+    return null;
+  }
+
+  /**
    * Return the intersection of the [first] and [second] sets of types, where
    * intersection is based on the equality of the types themselves.
    */
@@ -1986,6 +2133,9 @@
   bool get isBottom => false;
 
   @override
+  bool get isDartAsyncFuture => false;
+
+  @override
   bool get isDartCoreFunction => false;
 
   @override
@@ -2012,6 +2162,9 @@
     }
   }
 
+  @override
+  DartType flattenFutures(TypeSystem typeSystem) => this;
+
   /**
    * Return `true` if this type is assignable to the given [type] (written in
    * the spec as "T <=> S", where T=[this] and S=[type]).
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 3daca75..18c14d8 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -2,12331 +2,18 @@
 // 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/ast/ast.dart
+ * * package:analyzer/dart/ast/visitor.dart
+ *
+ * If your code is using APIs 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.ast;
 
-import 'dart:collection';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/ast/utilities.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';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
-import 'package:analyzer/src/generated/utilities_dart.dart';
-
+export 'package:analyzer/dart/ast/ast.dart';
 export 'package:analyzer/dart/ast/visitor.dart';
 export 'package:analyzer/src/dart/ast/utilities.dart';
-
-/**
- * Two or more string literals that are implicitly concatenated because of being
- * adjacent (separated only by whitespace).
- *
- * While the grammar only allows adjacent strings when all of the strings are of
- * the same kind (single line or multi-line), this class doesn't enforce that
- * restriction.
- *
- * > adjacentStrings ::=
- * >     [StringLiteral] [StringLiteral]+
- */
-class AdjacentStrings extends StringLiteral {
-  /**
-   * The strings that are implicitly concatenated.
-   */
-  NodeList<StringLiteral> _strings;
-
-  /**
-   * Initialize a newly created list of adjacent strings. To be syntactically
-   * valid, the list of [strings] must contain at least two elements.
-   */
-  AdjacentStrings(List<StringLiteral> strings) {
-    _strings = new NodeList<StringLiteral>(this, strings);
-  }
-
-  @override
-  Token get beginToken => _strings.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..addAll(_strings);
-
-  @override
-  Token get endToken => _strings.endToken;
-
-  /**
-   * Return the strings that are implicitly concatenated.
-   */
-  NodeList<StringLiteral> get strings => _strings;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAdjacentStrings(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _strings.accept(visitor);
-  }
-
-  @override
-  void _appendStringValue(StringBuffer buffer) {
-    for (StringLiteral stringLiteral in strings) {
-      stringLiteral._appendStringValue(buffer);
-    }
-  }
-}
-
-/**
- * An AST node that can be annotated with both a documentation comment and a
- * list of annotations.
- */
-abstract class AnnotatedNode extends AstNode {
-  /**
-   * The documentation comment associated with this node, or `null` if this node
-   * does not have a documentation comment associated with it.
-   */
-  Comment _comment;
-
-  /**
-   * The annotations associated with this node.
-   */
-  NodeList<Annotation> _metadata;
-
-  /**
-   * Initialize a newly created annotated node. Either or both of the [comment]
-   * and [metadata] can be `null` if the node does not have the corresponding
-   * attribute.
-   */
-  AnnotatedNode(Comment comment, List<Annotation> metadata) {
-    _comment = _becomeParentOf(comment);
-    _metadata = new NodeList<Annotation>(this, metadata);
-  }
-
-  @override
-  Token get beginToken {
-    if (_comment == null) {
-      if (_metadata.isEmpty) {
-        return firstTokenAfterCommentAndMetadata;
-      }
-      return _metadata.beginToken;
-    } else if (_metadata.isEmpty) {
-      return _comment.beginToken;
-    }
-    Token commentToken = _comment.beginToken;
-    Token metadataToken = _metadata.beginToken;
-    if (commentToken.offset < metadataToken.offset) {
-      return commentToken;
-    }
-    return metadataToken;
-  }
-
-  /**
-   * Return the documentation comment associated with this node, or `null` if
-   * this node does not have a documentation comment associated with it.
-   */
-  Comment get documentationComment => _comment;
-
-  /**
-   * Set the documentation comment associated with this node to the given
-   * [comment].
-   */
-  void set documentationComment(Comment comment) {
-    _comment = _becomeParentOf(comment);
-  }
-
-  /**
-   * Return the first token following the comment and metadata.
-   */
-  Token get firstTokenAfterCommentAndMetadata;
-
-  /**
-   * Return the annotations associated with this node.
-   */
-  NodeList<Annotation> get metadata => _metadata;
-
-  /**
-   * Return a list containing the comment and annotations associated with this
-   * node, sorted in lexical order.
-   */
-  List<AstNode> get sortedCommentAndAnnotations {
-    return <AstNode>[]
-      ..add(_comment)
-      ..addAll(_metadata)
-      ..sort(AstNode.LEXICAL_ORDER);
-  }
-
-  /**
-   * Return a holder of child entities that subclasses can add to.
-   */
-  ChildEntities get _childEntities {
-    ChildEntities result = new ChildEntities();
-    if (_commentIsBeforeAnnotations()) {
-      result
-        ..add(_comment)
-        ..addAll(_metadata);
-    } else {
-      result.addAll(sortedCommentAndAnnotations);
-    }
-    return result;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    if (_commentIsBeforeAnnotations()) {
-      _safelyVisitChild(_comment, visitor);
-      _metadata.accept(visitor);
-    } else {
-      for (AstNode child in sortedCommentAndAnnotations) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Return `true` if there are no annotations before the comment. Note that a
-   * result of `true` does not imply that there is a comment, nor that there are
-   * annotations associated with this node.
-   */
-  bool _commentIsBeforeAnnotations() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    if (_comment == null || _metadata.isEmpty) {
-      return true;
-    }
-    Annotation firstAnnotation = _metadata[0];
-    return _comment.offset < firstAnnotation.offset;
-  }
-}
-
-/**
- * An annotation that can be associated with an AST node.
- *
- * > metadata ::=
- * >     annotation*
- * >
- * > annotation ::=
- * >     '@' [Identifier] ('.' [SimpleIdentifier])? [ArgumentList]?
- */
-class Annotation extends AstNode {
-  /**
-   * The at sign that introduced the annotation.
-   */
-  Token atSign;
-
-  /**
-   * The name of the class defining the constructor that is being invoked or the
-   * name of the field that is being referenced.
-   */
-  Identifier _name;
-
-  /**
-   * The period before the constructor name, or `null` if this annotation is not
-   * the invocation of a named constructor.
-   */
-  Token period;
-
-  /**
-   * The name of the constructor being invoked, or `null` if this annotation is
-   * not the invocation of a named constructor.
-   */
-  SimpleIdentifier _constructorName;
-
-  /**
-   * The arguments to the constructor being invoked, or `null` if this
-   * annotation is not the invocation of a constructor.
-   */
-  ArgumentList _arguments;
-
-  /**
-   * The element associated with this annotation, or `null` if the AST structure
-   * has not been resolved or if this annotation could not be resolved.
-   */
-  Element _element;
-
-  /**
-   * The element annotation representing this annotation in the element model.
-   */
-  ElementAnnotation elementAnnotation;
-
-  /**
-   * Initialize a newly created annotation. Both the [period] and the
-   * [constructorName] can be `null` if the annotation is not referencing a
-   * named constructor. The [arguments] can be `null` if the annotation is not
-   * referencing a constructor.
-   */
-  Annotation(this.atSign, Identifier name, this.period,
-      SimpleIdentifier constructorName, ArgumentList arguments) {
-    _name = _becomeParentOf(name);
-    _constructorName = _becomeParentOf(constructorName);
-    _arguments = _becomeParentOf(arguments);
-  }
-
-  /**
-   * Return the arguments to the constructor being invoked, or `null` if this
-   * annotation is not the invocation of a constructor.
-   */
-  ArgumentList get arguments => _arguments;
-
-  /**
-   * Set the arguments to the constructor being invoked to the given arguments.
-   */
-  void set arguments(ArgumentList arguments) {
-    _arguments = _becomeParentOf(arguments);
-  }
-
-  @override
-  Token get beginToken => atSign;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(atSign)
-    ..add(_name)
-    ..add(period)
-    ..add(_constructorName)
-    ..add(_arguments);
-
-  /**
-   * Return the name of the constructor being invoked, or `null` if this
-   * annotation is not the invocation of a named constructor.
-   */
-  SimpleIdentifier get constructorName => _constructorName;
-
-  /**
-   * Set the name of the constructor being invoked to the given [name].
-   */
-  void set constructorName(SimpleIdentifier name) {
-    _constructorName = _becomeParentOf(name);
-  }
-
-  /**
-   * Return the element associated with this annotation, or `null` if the AST
-   * structure has not been resolved or if this annotation could not be
-   * resolved.
-   */
-  Element get element {
-    if (_element != null) {
-      return _element;
-    } else if (_name != null) {
-      return _name.staticElement;
-    }
-    return null;
-  }
-
-  /**
-   * Set the element associated with this annotation to the given [element].
-   */
-  void set element(Element element) {
-    _element = element;
-  }
-
-  @override
-  Token get endToken {
-    if (_arguments != null) {
-      return _arguments.endToken;
-    } else if (_constructorName != null) {
-      return _constructorName.endToken;
-    }
-    return _name.endToken;
-  }
-
-  /**
-   * Return the name of the class defining the constructor that is being invoked
-   * or the name of the field that is being referenced.
-   */
-  Identifier get name => _name;
-
-  /**
-   * Set the name of the class defining the constructor that is being invoked or
-   * the name of the field that is being referenced to the given [name].
-   */
-  void set name(Identifier name) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAnnotation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_constructorName, visitor);
-    _safelyVisitChild(_arguments, visitor);
-  }
-}
-
-/**
- * A list of arguments in the invocation of an executable element (that is, a
- * function, method, or constructor).
- *
- * > argumentList ::=
- * >     '(' arguments? ')'
- * >
- * > arguments ::=
- * >     [NamedExpression] (',' [NamedExpression])*
- * >   | [Expression] (',' [Expression])* (',' [NamedExpression])*
- */
-class ArgumentList extends AstNode {
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The expressions producing the values of the arguments.
-   */
-  NodeList<Expression> _arguments;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * A list containing the elements representing the parameters corresponding to
-   * each of the arguments in this list, or `null` if the AST has not been
-   * resolved or if the function or method being invoked could not be determined
-   * based on static type information. The list must be the same length as the
-   * number of arguments, but can contain `null` entries if a given argument
-   * does not correspond to a formal parameter.
-   */
-  List<ParameterElement> _correspondingStaticParameters;
-
-  /**
-   * A list containing the elements representing the parameters corresponding to
-   * each of the arguments in this list, or `null` if the AST has not been
-   * resolved or if the function or method being invoked could not be determined
-   * based on propagated type information. The list must be the same length as
-   * the number of arguments, but can contain `null` entries if a given argument
-   * does not correspond to a formal parameter.
-   */
-  List<ParameterElement> _correspondingPropagatedParameters;
-
-  /**
-   * Initialize a newly created list of arguments. The list of [arguments] can
-   * be `null` if there are no arguments.
-   */
-  ArgumentList(
-      this.leftParenthesis, List<Expression> arguments, this.rightParenthesis) {
-    _arguments = new NodeList<Expression>(this, arguments);
-  }
-
-  /**
-   * Return the expressions producing the values of the arguments. Although the
-   * language requires that positional arguments appear before named arguments,
-   * this class allows them to be intermixed.
-   */
-  NodeList<Expression> get arguments => _arguments;
-
-  @override
-  Token get beginToken => leftParenthesis;
-
-  @override
-  // TODO(paulberry): Add commas.
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftParenthesis)
-    ..addAll(_arguments)
-    ..add(rightParenthesis);
-
-  /**
-   * Set the parameter elements corresponding to each of the arguments in this
-   * list to the given list of [parameters]. The list of parameters must be the
-   * same length as the number of arguments, but can contain `null` entries if a
-   * given argument does not correspond to a formal parameter.
-   */
-  void set correspondingPropagatedParameters(
-      List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
-      throw new IllegalArgumentException(
-          "Expected ${_arguments.length} parameters, not ${parameters.length}");
-    }
-    _correspondingPropagatedParameters = parameters;
-  }
-
-  /**
-   * Set the parameter elements corresponding to each of the arguments in this
-   * list to the given list of parameters. The list of parameters must be the
-   * same length as the number of arguments, but can contain `null` entries if a
-   * given argument does not correspond to a formal parameter.
-   */
-  void set correspondingStaticParameters(List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
-      throw new IllegalArgumentException(
-          "Expected ${_arguments.length} parameters, not ${parameters.length}");
-    }
-    _correspondingStaticParameters = parameters;
-  }
-
-  @override
-  Token get endToken => rightParenthesis;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitArgumentList(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _arguments.accept(visitor);
-  }
-
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on propagated type information,
-   *   and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  ParameterElement _getPropagatedParameterElementFor(Expression expression) {
-    if (_correspondingPropagatedParameters == null ||
-        _correspondingPropagatedParameters.length != _arguments.length) {
-      // Either the AST structure has not been resolved, the invocation of which
-      // this list is a part could not be resolved, or the argument list was
-      // modified after the parameters were set.
-      return null;
-    }
-    int index = _arguments.indexOf(expression);
-    if (index < 0) {
-      // The expression isn't a child of this node.
-      return null;
-    }
-    return _correspondingPropagatedParameters[index];
-  }
-
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on static type information, and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  ParameterElement _getStaticParameterElementFor(Expression expression) {
-    if (_correspondingStaticParameters == null ||
-        _correspondingStaticParameters.length != _arguments.length) {
-      // Either the AST structure has not been resolved, the invocation of which
-      // this list is a part could not be resolved, or the argument list was
-      // modified after the parameters were set.
-      return null;
-    }
-    int index = _arguments.indexOf(expression);
-    if (index < 0) {
-      // The expression isn't a child of this node.
-      return null;
-    }
-    return _correspondingStaticParameters[index];
-  }
-}
-
-/**
- * An as expression.
- *
- * > asExpression ::=
- * >     [Expression] 'as' [TypeName]
- */
-class AsExpression extends Expression {
-  /**
-   * The expression used to compute the value being cast.
-   */
-  Expression _expression;
-
-  /**
-   * The 'as' operator.
-   */
-  Token asOperator;
-
-  /**
-   * The name of the type being cast to.
-   */
-  TypeName _type;
-
-  /**
-   * Initialize a newly created as expression.
-   */
-  AsExpression(Expression expression, this.asOperator, TypeName type) {
-    _expression = _becomeParentOf(expression);
-    _type = _becomeParentOf(type);
-  }
-
-  @override
-  Token get beginToken => _expression.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_expression)..add(asOperator)..add(_type);
-
-  @override
-  Token get endToken => _type.endToken;
-
-  /**
-   * Return the expression used to compute the value being cast.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression used to compute the value being cast to the given
-   * [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 7;
-
-  /**
-   * Return the name of the type being cast to.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the type being cast to to the given [name].
-   */
-  void set type(TypeName name) {
-    _type = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAsExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-    _safelyVisitChild(_type, visitor);
-  }
-}
-
-/**
- * An assert statement.
- *
- * > assertStatement ::=
- * >     'assert' '(' [Expression] ')' ';'
- */
-class AssertStatement extends Statement {
-  /**
-   * The token representing the 'assert' keyword.
-   */
-  Token assertKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The condition that is being asserted to be `true`.
-   */
-  Expression _condition;
-
-  /**
-   * The comma, if a message expression was supplied.  Otherwise `null`.
-   */
-  Token comma;
-
-  /**
-   * The message to report if the assertion fails.  `null` if no message was
-   * supplied.
-   */
-  Expression _message;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created assert statement.
-   */
-  AssertStatement(
-      this.assertKeyword,
-      this.leftParenthesis,
-      Expression condition,
-      this.comma,
-      Expression message,
-      this.rightParenthesis,
-      this.semicolon) {
-    _condition = _becomeParentOf(condition);
-    _message = _becomeParentOf(message);
-  }
-
-  @override
-  Token get beginToken => assertKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(assertKeyword)
-    ..add(leftParenthesis)
-    ..add(_condition)
-    ..add(comma)
-    ..add(_message)
-    ..add(rightParenthesis)
-    ..add(semicolon);
-
-  /**
-   * Return the condition that is being asserted to be `true`.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the condition that is being asserted to be `true` to the given
-   * [expression].
-   */
-  void set condition(Expression condition) {
-    _condition = _becomeParentOf(condition);
-  }
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the message to report if the assertion fails.
-   */
-  Expression get message => _message;
-
-  /**
-   * Set the message to report if the assertion fails to the given
-   * [expression].
-   */
-  void set message(Expression expression) {
-    _message = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAssertStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_condition, visitor);
-    _safelyVisitChild(message, visitor);
-  }
-}
-
-/**
- * An assignment expression.
- *
- * > assignmentExpression ::=
- * >     [Expression] operator [Expression]
- */
-class AssignmentExpression extends Expression {
-  /**
-   * The expression used to compute the left hand side.
-   */
-  Expression _leftHandSide;
-
-  /**
-   * The assignment operator being applied.
-   */
-  Token operator;
-
-  /**
-   * The expression used to compute the right hand side.
-   */
-  Expression _rightHandSide;
-
-  /**
-   * The element associated with the operator based on the static type of the
-   * left-hand-side, or `null` if the AST structure has not been resolved, if
-   * the operator is not a compound operator, or if the operator could not be
-   * resolved.
-   */
-  MethodElement staticElement;
-
-  /**
-   * The element associated with the operator based on the propagated type of
-   * the left-hand-side, or `null` if the AST structure has not been resolved,
-   * if the operator is not a compound operator, or if the operator could not be
-   * resolved.
-   */
-  MethodElement propagatedElement;
-
-  /**
-   * Initialize a newly created assignment expression.
-   */
-  AssignmentExpression(
-      Expression leftHandSide, this.operator, Expression rightHandSide) {
-    if (leftHandSide == null || rightHandSide == null) {
-      String message;
-      if (leftHandSide == null) {
-        if (rightHandSide == null) {
-          message = "Both the left-hand and right-hand sides are null";
-        } else {
-          message = "The left-hand size is null";
-        }
-      } else {
-        message = "The right-hand size is null";
-      }
-      AnalysisEngine.instance.logger.logError(
-          message, new CaughtException(new AnalysisException(message), null));
-    }
-    _leftHandSide = _becomeParentOf(leftHandSide);
-    _rightHandSide = _becomeParentOf(rightHandSide);
-  }
-
-  @override
-  Token get beginToken => _leftHandSide.beginToken;
-
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  MethodElement get bestElement {
-    MethodElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_leftHandSide)
-    ..add(operator)
-    ..add(_rightHandSide);
-
-  @override
-  Token get endToken => _rightHandSide.endToken;
-
-  /**
-   * Set the expression used to compute the left hand side to the given
-   * [expression].
-   */
-  Expression get leftHandSide => _leftHandSide;
-
-  /**
-   * Return the expression used to compute the left hand side.
-   */
-  void set leftHandSide(Expression expression) {
-    _leftHandSide = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 1;
-
-  /**
-   * Return the expression used to compute the right hand side.
-   */
-  Expression get rightHandSide => _rightHandSide;
-
-  /**
-   * Set the expression used to compute the left hand side to the given
-   * [expression].
-   */
-  void set rightHandSide(Expression expression) {
-    _rightHandSide = _becomeParentOf(expression);
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _propagatedParameterElementForRightHandSide {
-    ExecutableElement executableElement = null;
-    if (propagatedElement != null) {
-      executableElement = propagatedElement;
-    } else {
-      if (_leftHandSide is Identifier) {
-        Identifier identifier = _leftHandSide as Identifier;
-        Element leftElement = identifier.propagatedElement;
-        if (leftElement is ExecutableElement) {
-          executableElement = leftElement;
-        }
-      }
-      if (_leftHandSide is PropertyAccess) {
-        SimpleIdentifier identifier =
-            (_leftHandSide as PropertyAccess).propertyName;
-        Element leftElement = identifier.propagatedElement;
-        if (leftElement is ExecutableElement) {
-          executableElement = leftElement;
-        }
-      }
-    }
-    if (executableElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = executableElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  ParameterElement get _staticParameterElementForRightHandSide {
-    ExecutableElement executableElement = null;
-    if (staticElement != null) {
-      executableElement = staticElement;
-    } else {
-      if (_leftHandSide is Identifier) {
-        Element leftElement = (_leftHandSide as Identifier).staticElement;
-        if (leftElement is ExecutableElement) {
-          executableElement = leftElement;
-        }
-      }
-      if (_leftHandSide is PropertyAccess) {
-        Element leftElement =
-            (_leftHandSide as PropertyAccess).propertyName.staticElement;
-        if (leftElement is ExecutableElement) {
-          executableElement = leftElement;
-        }
-      }
-    }
-    if (executableElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = executableElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAssignmentExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_leftHandSide, visitor);
-    _safelyVisitChild(_rightHandSide, visitor);
-  }
-}
-
-/**
- * A node in the AST structure for a Dart program.
- */
-abstract class AstNode {
-  /**
-   * An empty list of AST nodes.
-   */
-  static const List<AstNode> EMPTY_LIST = const <AstNode>[];
-
-  /**
-   * A comparator that can be used to sort AST nodes in lexical order. In other
-   * words, `compare` will return a negative value if the offset of the first
-   * node is less than the offset of the second node, zero (0) if the nodes have
-   * the same offset, and a positive value if the offset of the first node is
-   * greater than the offset of the second node.
-   */
-  static Comparator<AstNode> LEXICAL_ORDER =
-      (AstNode first, AstNode second) => first.offset - second.offset;
-
-  /**
-   * The parent of the node, or `null` if the node is the root of an AST
-   * structure.
-   */
-  AstNode _parent;
-
-  /**
-   * A table mapping the names of properties to their values, or `null` if this
-   * node does not have any properties associated with it.
-   */
-  Map<String, Object> _propertyMap;
-
-  /**
-   * Return the first token included in this node's source range.
-   */
-  Token get beginToken;
-
-  /**
-   * Iterate through all the entities (either AST nodes or tokens) which make
-   * up the contents of this node, including doc comments but excluding other
-   * comments.
-   */
-  Iterable /*<AstNode | Token>*/ get childEntities;
-
-  /**
-   * Return the offset of the character immediately following the last character
-   * of this node's source range. This is equivalent to
-   * `node.getOffset() + node.getLength()`. For a compilation unit this will be
-   * equal to the length of the unit's source. For synthetic nodes this will be
-   * equivalent to the node's offset (because the length is zero (0) by
-   * definition).
-   */
-  int get end => offset + length;
-
-  /**
-   * Return the last token included in this node's source range.
-   */
-  Token get endToken;
-
-  /**
-   * Return `true` if this node is a synthetic node. A synthetic node is a node
-   * that was introduced by the parser in order to recover from an error in the
-   * code. Synthetic nodes always have a length of zero (`0`).
-   */
-  bool get isSynthetic => false;
-
-  /**
-   * Return the number of characters in the node's source range.
-   */
-  int get length {
-    Token beginToken = this.beginToken;
-    Token endToken = this.endToken;
-    if (beginToken == null || endToken == null) {
-      return -1;
-    }
-    return endToken.offset + endToken.length - beginToken.offset;
-  }
-
-  /**
-   * Return the offset from the beginning of the file to the first character in
-   * the node's source range.
-   */
-  int get offset {
-    Token beginToken = this.beginToken;
-    if (beginToken == null) {
-      return -1;
-    }
-    return beginToken.offset;
-  }
-
-  /**
-   * Return this node's parent node, or `null` if this node is the root of an
-   * AST structure.
-   *
-   * Note that the relationship between an AST node and its parent node may
-   * change over the lifetime of a node.
-   */
-  AstNode get parent => _parent;
-
-  /**
-   * Return the node at the root of this node's AST structure. Note that this
-   * method's performance is linear with respect to the depth of the node in the
-   * AST structure (O(depth)).
-   */
-  AstNode get root {
-    AstNode root = this;
-    AstNode parent = this.parent;
-    while (parent != null) {
-      root = parent;
-      parent = root.parent;
-    }
-    return root;
-  }
-
-  /**
-   * Use the given [visitor] to visit this node. Return the value returned by
-   * the visitor as a result of visiting this node.
-   */
-  dynamic /*=E*/ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
-
-  /**
-   * Return the most immediate ancestor of this node for which the [predicate]
-   * returns `true`, or `null` if there is no such ancestor. Note that this node
-   * will never be returned.
-   */
-  AstNode getAncestor(Predicate<AstNode> predicate) {
-    // TODO(brianwilkerson) It is a bug that this method can return `this`.
-    AstNode node = this;
-    while (node != null && !predicate(node)) {
-      node = node.parent;
-    }
-    return node;
-  }
-
-  /**
-   * Return the value of the property with the given [name], or `null` if this
-   * node does not have a property with the given name.
-   */
-  Object getProperty(String name) {
-    if (_propertyMap == null) {
-      return null;
-    }
-    return _propertyMap[name];
-  }
-
-  /**
-   * Set the value of the property with the given [name] to the given [value].
-   * If the value is `null`, the property will effectively be removed.
-   */
-  void setProperty(String name, Object value) {
-    if (value == null) {
-      if (_propertyMap != null) {
-        _propertyMap.remove(name);
-        if (_propertyMap.isEmpty) {
-          _propertyMap = null;
-        }
-      }
-    } else {
-      if (_propertyMap == null) {
-        _propertyMap = new HashMap<String, Object>();
-      }
-      _propertyMap[name] = value;
-    }
-  }
-
-  /**
-   * Return a textual description of this node in a form approximating valid
-   * source. The returned string will not be valid source primarily in the case
-   * where the node itself is not well-formed.
-   */
-  String toSource() {
-    PrintStringWriter writer = new PrintStringWriter();
-    accept(new ToSourceVisitor(writer));
-    return writer.toString();
-  }
-
-  @override
-  String toString() => toSource();
-
-  /**
-   * Use the given [visitor] to visit all of the children of this node. The
-   * children will be visited in lexical order.
-   */
-  void visitChildren(AstVisitor visitor);
-
-  /**
-   * Make this node the parent of the given [child] node. Return the child node.
-   */
-  AstNode _becomeParentOf(AstNode child) {
-    if (child != null) {
-      child._parent = this;
-    }
-    return child;
-  }
-
-  /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  void _safelyVisitChild(AstNode child, AstVisitor visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-}
-
-/**
- * An object that can be used to visit an AST structure.
- */
-abstract class AstVisitor<R> {
-  R visitAdjacentStrings(AdjacentStrings node);
-
-  R visitAnnotation(Annotation node);
-
-  R visitArgumentList(ArgumentList node);
-
-  R visitAsExpression(AsExpression node);
-
-  R visitAssertStatement(AssertStatement assertStatement);
-
-  R visitAssignmentExpression(AssignmentExpression node);
-
-  R visitAwaitExpression(AwaitExpression node);
-
-  R visitBinaryExpression(BinaryExpression node);
-
-  R visitBlock(Block node);
-
-  R visitBlockFunctionBody(BlockFunctionBody node);
-
-  R visitBooleanLiteral(BooleanLiteral node);
-
-  R visitBreakStatement(BreakStatement node);
-
-  R visitCascadeExpression(CascadeExpression node);
-
-  R visitCatchClause(CatchClause node);
-
-  R visitClassDeclaration(ClassDeclaration node);
-
-  R visitClassTypeAlias(ClassTypeAlias node);
-
-  R visitComment(Comment node);
-
-  R visitCommentReference(CommentReference node);
-
-  R visitCompilationUnit(CompilationUnit node);
-
-  R visitConditionalExpression(ConditionalExpression node);
-
-  R visitConfiguration(Configuration node);
-
-  R visitConstructorDeclaration(ConstructorDeclaration node);
-
-  R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
-
-  R visitConstructorName(ConstructorName node);
-
-  R visitContinueStatement(ContinueStatement node);
-
-  R visitDeclaredIdentifier(DeclaredIdentifier node);
-
-  R visitDefaultFormalParameter(DefaultFormalParameter node);
-
-  R visitDoStatement(DoStatement node);
-
-  R visitDottedName(DottedName node);
-
-  R visitDoubleLiteral(DoubleLiteral node);
-
-  R visitEmptyFunctionBody(EmptyFunctionBody node);
-
-  R visitEmptyStatement(EmptyStatement node);
-
-  R visitEnumConstantDeclaration(EnumConstantDeclaration node);
-
-  R visitEnumDeclaration(EnumDeclaration node);
-
-  R visitExportDirective(ExportDirective node);
-
-  R visitExpressionFunctionBody(ExpressionFunctionBody node);
-
-  R visitExpressionStatement(ExpressionStatement node);
-
-  R visitExtendsClause(ExtendsClause node);
-
-  R visitFieldDeclaration(FieldDeclaration node);
-
-  R visitFieldFormalParameter(FieldFormalParameter node);
-
-  R visitForEachStatement(ForEachStatement node);
-
-  R visitFormalParameterList(FormalParameterList node);
-
-  R visitForStatement(ForStatement node);
-
-  R visitFunctionDeclaration(FunctionDeclaration node);
-
-  R visitFunctionDeclarationStatement(FunctionDeclarationStatement node);
-
-  R visitFunctionExpression(FunctionExpression node);
-
-  R visitFunctionExpressionInvocation(FunctionExpressionInvocation node);
-
-  R visitFunctionTypeAlias(FunctionTypeAlias functionTypeAlias);
-
-  R visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node);
-
-  R visitHideCombinator(HideCombinator node);
-
-  R visitIfStatement(IfStatement node);
-
-  R visitImplementsClause(ImplementsClause node);
-
-  R visitImportDirective(ImportDirective node);
-
-  R visitIndexExpression(IndexExpression node);
-
-  R visitInstanceCreationExpression(InstanceCreationExpression node);
-
-  R visitIntegerLiteral(IntegerLiteral node);
-
-  R visitInterpolationExpression(InterpolationExpression node);
-
-  R visitInterpolationString(InterpolationString node);
-
-  R visitIsExpression(IsExpression node);
-
-  R visitLabel(Label node);
-
-  R visitLabeledStatement(LabeledStatement node);
-
-  R visitLibraryDirective(LibraryDirective node);
-
-  R visitLibraryIdentifier(LibraryIdentifier node);
-
-  R visitListLiteral(ListLiteral node);
-
-  R visitMapLiteral(MapLiteral node);
-
-  R visitMapLiteralEntry(MapLiteralEntry node);
-
-  R visitMethodDeclaration(MethodDeclaration node);
-
-  R visitMethodInvocation(MethodInvocation node);
-
-  R visitNamedExpression(NamedExpression node);
-
-  R visitNativeClause(NativeClause node);
-
-  R visitNativeFunctionBody(NativeFunctionBody node);
-
-  R visitNullLiteral(NullLiteral node);
-
-  R visitParenthesizedExpression(ParenthesizedExpression node);
-
-  R visitPartDirective(PartDirective node);
-
-  R visitPartOfDirective(PartOfDirective node);
-
-  R visitPostfixExpression(PostfixExpression node);
-
-  R visitPrefixedIdentifier(PrefixedIdentifier node);
-
-  R visitPrefixExpression(PrefixExpression node);
-
-  R visitPropertyAccess(PropertyAccess node);
-
-  R visitRedirectingConstructorInvocation(
-      RedirectingConstructorInvocation node);
-
-  R visitRethrowExpression(RethrowExpression node);
-
-  R visitReturnStatement(ReturnStatement node);
-
-  R visitScriptTag(ScriptTag node);
-
-  R visitShowCombinator(ShowCombinator node);
-
-  R visitSimpleFormalParameter(SimpleFormalParameter node);
-
-  R visitSimpleIdentifier(SimpleIdentifier node);
-
-  R visitSimpleStringLiteral(SimpleStringLiteral node);
-
-  R visitStringInterpolation(StringInterpolation node);
-
-  R visitSuperConstructorInvocation(SuperConstructorInvocation node);
-
-  R visitSuperExpression(SuperExpression node);
-
-  R visitSwitchCase(SwitchCase node);
-
-  R visitSwitchDefault(SwitchDefault node);
-
-  R visitSwitchStatement(SwitchStatement node);
-
-  R visitSymbolLiteral(SymbolLiteral node);
-
-  R visitThisExpression(ThisExpression node);
-
-  R visitThrowExpression(ThrowExpression node);
-
-  R visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node);
-
-  R visitTryStatement(TryStatement node);
-
-  R visitTypeArgumentList(TypeArgumentList node);
-
-  R visitTypeName(TypeName node);
-
-  R visitTypeParameter(TypeParameter node);
-
-  R visitTypeParameterList(TypeParameterList node);
-
-  R visitVariableDeclaration(VariableDeclaration node);
-
-  R visitVariableDeclarationList(VariableDeclarationList node);
-
-  R visitVariableDeclarationStatement(VariableDeclarationStatement node);
-
-  R visitWhileStatement(WhileStatement node);
-
-  R visitWithClause(WithClause node);
-
-  R visitYieldStatement(YieldStatement node);
-}
-
-/**
- * An await expression.
- *
- * > awaitExpression ::=
- * >     'await' [Expression]
- */
-class AwaitExpression extends Expression {
-  /**
-   * The 'await' keyword.
-   */
-  Token awaitKeyword;
-
-  /**
-   * The expression whose value is being waited on.
-   */
-  Expression _expression;
-
-  /**
-   * Initialize a newly created await expression.
-   */
-  AwaitExpression(this.awaitKeyword, Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken {
-    if (awaitKeyword != null) {
-      return awaitKeyword;
-    }
-    return _expression.beginToken;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(awaitKeyword)..add(_expression);
-
-  @override
-  Token get endToken => _expression.endToken;
-
-  /**
-   * Return the expression whose value is being waited on.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression whose value is being waited on to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 0;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitAwaitExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A binary (infix) expression.
- *
- * > binaryExpression ::=
- * >     [Expression] [Token] [Expression]
- */
-class BinaryExpression extends Expression {
-  /**
-   * The expression used to compute the left operand.
-   */
-  Expression _leftOperand;
-
-  /**
-   * The binary operator being applied.
-   */
-  Token operator;
-
-  /**
-   * The expression used to compute the right operand.
-   */
-  Expression _rightOperand;
-
-  /**
-   * The element associated with the operator based on the static type of the
-   * left operand, or `null` if the AST structure has not been resolved, if the
-   * operator is not user definable, or if the operator could not be resolved.
-   */
-  MethodElement staticElement;
-
-  /**
-   * The element associated with the operator based on the propagated type of
-   * the left operand, or `null` if the AST structure has not been resolved, if
-   * the operator is not user definable, or if the operator could not be
-   * resolved.
-   */
-  MethodElement propagatedElement;
-
-  /**
-   * Initialize a newly created binary expression.
-   */
-  BinaryExpression(
-      Expression leftOperand, this.operator, Expression rightOperand) {
-    _leftOperand = _becomeParentOf(leftOperand);
-    _rightOperand = _becomeParentOf(rightOperand);
-  }
-
-  @override
-  Token get beginToken => _leftOperand.beginToken;
-
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  MethodElement get bestElement {
-    MethodElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_leftOperand)..add(operator)..add(_rightOperand);
-
-  @override
-  Token get endToken => _rightOperand.endToken;
-
-  /**
-   * Return the expression used to compute the left operand.
-   */
-  Expression get leftOperand => _leftOperand;
-
-  /**
-   * Set the expression used to compute the left operand to the given
-   * [expression].
-   */
-  void set leftOperand(Expression expression) {
-    _leftOperand = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => operator.type.precedence;
-
-  /**
-   * Return the expression used to compute the right operand.
-   */
-  Expression get rightOperand => _rightOperand;
-
-  /**
-   * Set the expression used to compute the right operand to the given
-   * [expression].
-   */
-  void set rightOperand(Expression expression) {
-    _rightOperand = _becomeParentOf(expression);
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _propagatedParameterElementForRightOperand {
-    if (propagatedElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = propagatedElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  ParameterElement get _staticParameterElementForRightOperand {
-    if (staticElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = staticElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitBinaryExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_leftOperand, visitor);
-    _safelyVisitChild(_rightOperand, visitor);
-  }
-}
-
-/**
- * A sequence of statements.
- *
- * > block ::=
- * >     '{' statement* '}'
- */
-class Block extends Statement {
-  /**
-   * The left curly bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The statements contained in the block.
-   */
-  NodeList<Statement> _statements;
-
-  /**
-   * The right curly bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created block of code.
-   */
-  Block(this.leftBracket, List<Statement> statements, this.rightBracket) {
-    _statements = new NodeList<Statement>(this, statements);
-  }
-
-  @override
-  Token get beginToken => leftBracket;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftBracket)
-    ..addAll(_statements)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the statements contained in the block.
-   */
-  NodeList<Statement> get statements => _statements;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitBlock(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _statements.accept(visitor);
-  }
-}
-
-/**
- * A function body that consists of a block of statements.
- *
- * > blockFunctionBody ::=
- * >     ('async' | 'async' '*' | 'sync' '*')? [Block]
- */
-class BlockFunctionBody extends FunctionBody {
-  /**
-   * The token representing the 'async' or 'sync' keyword, or `null` if there is
-   * no such keyword.
-   */
-  Token keyword;
-
-  /**
-   * The star optionally following the 'async' or 'sync' keyword, or `null` if
-   * there is wither no such keyword or no star.
-   */
-  Token star;
-
-  /**
-   * The block representing the body of the function.
-   */
-  Block _block;
-
-  /**
-   * Initialize a newly created function body consisting of a block of
-   * statements. The [keyword] can be `null` if there is no keyword specified
-   * for the block. The [star] can be `null` if there is no star following the
-   * keyword (and must be `null` if there is no keyword).
-   */
-  BlockFunctionBody(this.keyword, this.star, Block block) {
-    _block = _becomeParentOf(block);
-  }
-
-  @override
-  Token get beginToken {
-    if (keyword != null) {
-      return keyword;
-    }
-    return _block.beginToken;
-  }
-
-  /**
-   * Return the block representing the body of the function.
-   */
-  Block get block => _block;
-
-  /**
-   * Set the block representing the body of the function to the given [block].
-   */
-  void set block(Block block) {
-    _block = _becomeParentOf(block);
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(keyword)..add(star)..add(_block);
-
-  @override
-  Token get endToken => _block.endToken;
-
-  @override
-  bool get isAsynchronous => keyword != null && keyword.lexeme == Parser.ASYNC;
-
-  @override
-  bool get isGenerator => star != null;
-
-  @override
-  bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitBlockFunctionBody(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_block, visitor);
-  }
-}
-
-/**
- * A boolean literal expression.
- *
- * > booleanLiteral ::=
- * >     'false' | 'true'
- */
-class BooleanLiteral extends Literal {
-  /**
-   * The token representing the literal.
-   */
-  Token literal;
-
-  /**
-   * The value of the literal.
-   */
-  bool value = false;
-
-  /**
-   * Initialize a newly created boolean literal.
-   */
-  BooleanLiteral(this.literal, this.value);
-
-  @override
-  Token get beginToken => literal;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(literal);
-
-  @override
-  Token get endToken => literal;
-
-  @override
-  bool get isSynthetic => literal.isSynthetic;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitBooleanLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A break statement.
- *
- * > breakStatement ::=
- * >     'break' [SimpleIdentifier]? ';'
- */
-class BreakStatement extends Statement {
-  /**
-   * The token representing the 'break' keyword.
-   */
-  Token breakKeyword;
-
-  /**
-   * The label associated with the statement, or `null` if there is no label.
-   */
-  SimpleIdentifier _label;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * The AstNode which this break statement is breaking from.  This will be
-   * either a [Statement] (in the case of breaking out of a loop), a
-   * [SwitchMember] (in the case of a labeled break statement whose label
-   * matches a label on a switch case in an enclosing switch statement), or
-   * `null` if the AST has not yet been resolved or if the target could not be
-   * resolved. Note that if the source code has errors, the target might be
-   * invalid (e.g. trying to break to a switch case).
-   */
-  AstNode target;
-
-  /**
-   * Initialize a newly created break statement. The [label] can be `null` if
-   * there is no label associated with the statement.
-   */
-  BreakStatement(this.breakKeyword, SimpleIdentifier label, this.semicolon) {
-    _label = _becomeParentOf(label);
-  }
-
-  @override
-  Token get beginToken => breakKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(breakKeyword)..add(_label)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the label associated with the statement, or `null` if there is no
-   * label.
-   */
-  SimpleIdentifier get label => _label;
-
-  /**
-   * Set the label associated with the statement to the given [identifier].
-   */
-  void set label(SimpleIdentifier identifier) {
-    _label = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitBreakStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_label, visitor);
-  }
-}
-
-/**
- * A sequence of cascaded expressions: expressions that share a common target.
- * There are three kinds of expressions that can be used in a cascade
- * expression: [IndexExpression], [MethodInvocation] and [PropertyAccess].
- *
- * > cascadeExpression ::=
- * >     [Expression] cascadeSection*
- * >
- * > cascadeSection ::=
- * >     '..'  (cascadeSelector arguments*) (assignableSelector arguments*)*
- * >     (assignmentOperator expressionWithoutCascade)?
- * >
- * > cascadeSelector ::=
- * >     '[ ' expression '] '
- * >   | identifier
- */
-class CascadeExpression extends Expression {
-  /**
-   * The target of the cascade sections.
-   */
-  Expression _target;
-
-  /**
-   * The cascade sections sharing the common target.
-   */
-  NodeList<Expression> _cascadeSections;
-
-  /**
-   * Initialize a newly created cascade expression. The list of
-   * [cascadeSections] must contain at least one element.
-   */
-  CascadeExpression(Expression target, List<Expression> cascadeSections) {
-    _target = _becomeParentOf(target);
-    _cascadeSections = new NodeList<Expression>(this, cascadeSections);
-  }
-
-  @override
-  Token get beginToken => _target.beginToken;
-
-  /**
-   * Return the cascade sections sharing the common target.
-   */
-  NodeList<Expression> get cascadeSections => _cascadeSections;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_target)
-    ..addAll(_cascadeSections);
-
-  @override
-  Token get endToken => _cascadeSections.endToken;
-
-  @override
-  int get precedence => 2;
-
-  /**
-   * Return the target of the cascade sections.
-   */
-  Expression get target => _target;
-
-  /**
-   * Set the target of the cascade sections to the given [expression].
-   */
-  void set target(Expression target) {
-    _target = _becomeParentOf(target);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitCascadeExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_target, visitor);
-    _cascadeSections.accept(visitor);
-  }
-}
-
-/**
- * A catch clause within a try statement.
- *
- * > onPart ::=
- * >     catchPart [Block]
- * >   | 'on' type catchPart? [Block]
- * >
- * > catchPart ::=
- * >     'catch' '(' [SimpleIdentifier] (',' [SimpleIdentifier])? ')'
- */
-class CatchClause extends AstNode {
-  /**
-   * The token representing the 'on' keyword, or `null` if there is no 'on'
-   * keyword.
-   */
-  Token onKeyword;
-
-  /**
-   * The type of exceptions caught by this catch clause, or `null` if this catch
-   * clause catches every type of exception.
-   */
-  TypeName _exceptionType;
-
-  /**
-   * The token representing the 'catch' keyword, or `null` if there is no
-   * 'catch' keyword.
-   */
-  Token catchKeyword;
-
-  /**
-   * The left parenthesis, or `null` if there is no 'catch' keyword.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The parameter whose value will be the exception that was thrown, or `null`
-   * if there is no 'catch' keyword.
-   */
-  SimpleIdentifier _exceptionParameter;
-
-  /**
-   * The comma separating the exception parameter from the stack trace
-   * parameter, or `null` if there is no stack trace parameter.
-   */
-  Token comma;
-
-  /**
-   * The parameter whose value will be the stack trace associated with the
-   * exception, or `null` if there is no stack trace parameter.
-   */
-  SimpleIdentifier _stackTraceParameter;
-
-  /**
-   * The right parenthesis, or `null` if there is no 'catch' keyword.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The body of the catch block.
-   */
-  Block _body;
-
-  /**
-   * Initialize a newly created catch clause. The [onKeyword] and
-   * [exceptionType] can be `null` if the clause will catch all exceptions. The
-   * [comma] and [stackTraceParameter] can be `null` if the stack trace is not
-   * referencable within the body.
-   */
-  CatchClause(
-      this.onKeyword,
-      TypeName exceptionType,
-      this.catchKeyword,
-      this.leftParenthesis,
-      SimpleIdentifier exceptionParameter,
-      this.comma,
-      SimpleIdentifier stackTraceParameter,
-      this.rightParenthesis,
-      Block body) {
-    _exceptionType = _becomeParentOf(exceptionType);
-    _exceptionParameter = _becomeParentOf(exceptionParameter);
-    _stackTraceParameter = _becomeParentOf(stackTraceParameter);
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  Token get beginToken {
-    if (onKeyword != null) {
-      return onKeyword;
-    }
-    return catchKeyword;
-  }
-
-  /**
-   * Return the body of the catch block.
-   */
-  Block get body => _body;
-
-  /**
-   * Set the body of the catch block to the given [block].
-   */
-  void set body(Block block) {
-    _body = _becomeParentOf(block);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(onKeyword)
-    ..add(_exceptionType)
-    ..add(catchKeyword)
-    ..add(leftParenthesis)
-    ..add(_exceptionParameter)
-    ..add(comma)
-    ..add(_stackTraceParameter)
-    ..add(rightParenthesis)
-    ..add(_body);
-
-  @override
-  Token get endToken => _body.endToken;
-
-  /**
-   * Return the parameter whose value will be the exception that was thrown, or
-   * `null` if there is no 'catch' keyword.
-   */
-  SimpleIdentifier get exceptionParameter => _exceptionParameter;
-
-  /**
-   * Set the parameter whose value will be the exception that was thrown to the
-   * given [parameter].
-   */
-  void set exceptionParameter(SimpleIdentifier parameter) {
-    _exceptionParameter = _becomeParentOf(parameter);
-  }
-
-  /**
-   * Return the type of exceptions caught by this catch clause, or `null` if
-   * this catch clause catches every type of exception.
-   */
-  TypeName get exceptionType => _exceptionType;
-
-  /**
-   * Set the type of exceptions caught by this catch clause to the given
-   * [exceptionType].
-   */
-  void set exceptionType(TypeName exceptionType) {
-    _exceptionType = _becomeParentOf(exceptionType);
-  }
-
-  /**
-   * Return the parameter whose value will be the stack trace associated with
-   * the exception, or `null` if there is no stack trace parameter.
-   */
-  SimpleIdentifier get stackTraceParameter => _stackTraceParameter;
-
-  /**
-   * Set the parameter whose value will be the stack trace associated with the
-   * exception to the given [parameter].
-   */
-  void set stackTraceParameter(SimpleIdentifier parameter) {
-    _stackTraceParameter = _becomeParentOf(parameter);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitCatchClause(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_exceptionType, visitor);
-    _safelyVisitChild(_exceptionParameter, visitor);
-    _safelyVisitChild(_stackTraceParameter, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * Helper class to allow iteration of child entities of an AST node.
- */
-class ChildEntities extends Object with IterableMixin implements Iterable {
-  /**
-   * The list of child entities to be iterated over.
-   */
-  List _entities = [];
-
-  @override
-  Iterator get iterator => _entities.iterator;
-
-  /**
-   * Add an AST node or token as the next child entity, if it is not null.
-   */
-  void add(entity) {
-    if (entity != null) {
-      assert(entity is Token || entity is AstNode);
-      _entities.add(entity);
-    }
-  }
-
-  /**
-   * Add the given items as the next child entities, if [items] is not null.
-   */
-  void addAll(Iterable items) {
-    if (items != null) {
-      _entities.addAll(items);
-    }
-  }
-}
-
-/**
- * The declaration of a class.
- *
- * > classDeclaration ::=
- * >     'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]?
- * >     ([ExtendsClause] [WithClause]?)?
- * >     [ImplementsClause]?
- * >     '{' [ClassMember]* '}'
- */
-class ClassDeclaration extends NamedCompilationUnitMember {
-  /**
-   * The 'abstract' keyword, or `null` if the keyword was absent.
-   */
-  Token abstractKeyword;
-
-  /**
-   * The token representing the 'class' keyword.
-   */
-  Token classKeyword;
-
-  /**
-   * The type parameters for the class, or `null` if the class does not have any
-   * type parameters.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The extends clause for the class, or `null` if the class does not extend
-   * any other class.
-   */
-  ExtendsClause _extendsClause;
-
-  /**
-   * The with clause for the class, or `null` if the class does not have a with
-   * clause.
-   */
-  WithClause _withClause;
-
-  /**
-   * The implements clause for the class, or `null` if the class does not
-   * implement any interfaces.
-   */
-  ImplementsClause _implementsClause;
-
-  /**
-   * The native clause for the class, or `null` if the class does not have a
-   * native clause.
-   */
-  NativeClause _nativeClause;
-
-  /**
-   * The left curly bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The members defined by the class.
-   */
-  NodeList<ClassMember> _members;
-
-  /**
-   * The right curly bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created class declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the class does not have the
-   * corresponding attribute. The [abstractKeyword] can be `null` if the class
-   * is not abstract. The [typeParameters] can be `null` if the class does not
-   * have any type parameters. Any or all of the [extendsClause], [withClause],
-   * and [implementsClause] can be `null` if the class does not have the
-   * corresponding clause. The list of [members] can be `null` if the class does
-   * not have any members.
-   */
-  ClassDeclaration(
-      Comment comment,
-      List<Annotation> metadata,
-      this.abstractKeyword,
-      this.classKeyword,
-      SimpleIdentifier name,
-      TypeParameterList typeParameters,
-      ExtendsClause extendsClause,
-      WithClause withClause,
-      ImplementsClause implementsClause,
-      this.leftBracket,
-      List<ClassMember> members,
-      this.rightBracket)
-      : super(comment, metadata, name) {
-    _typeParameters = _becomeParentOf(typeParameters);
-    _extendsClause = _becomeParentOf(extendsClause);
-    _withClause = _becomeParentOf(withClause);
-    _implementsClause = _becomeParentOf(implementsClause);
-    _members = new NodeList<ClassMember>(this, members);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(abstractKeyword)
-    ..add(classKeyword)
-    ..add(_name)
-    ..add(_typeParameters)
-    ..add(_extendsClause)
-    ..add(_withClause)
-    ..add(_implementsClause)
-    ..add(_nativeClause)
-    ..add(leftBracket)
-    ..addAll(members)
-    ..add(rightBracket);
-
-  @override
-  ClassElement get element =>
-      _name != null ? (_name.staticElement as ClassElement) : null;
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the extends clause for this class, or `null` if the class does not
-   * extend any other class.
-   */
-  ExtendsClause get extendsClause => _extendsClause;
-
-  /**
-   * Set the extends clause for this class to the given [extendsClause].
-   */
-  void set extendsClause(ExtendsClause extendsClause) {
-    _extendsClause = _becomeParentOf(extendsClause);
-  }
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (abstractKeyword != null) {
-      return abstractKeyword;
-    }
-    return classKeyword;
-  }
-
-  /**
-   * Return the implements clause for the class, or `null` if the class does not
-   * implement any interfaces.
-   */
-  ImplementsClause get implementsClause => _implementsClause;
-
-  /**
-   * Set the implements clause for the class to the given [implementsClause].
-   */
-  void set implementsClause(ImplementsClause implementsClause) {
-    _implementsClause = _becomeParentOf(implementsClause);
-  }
-
-  /**
-   * Return `true` if this class is declared to be an abstract class.
-   */
-  bool get isAbstract => abstractKeyword != null;
-
-  /**
-   * Return the members defined by the class.
-   */
-  NodeList<ClassMember> get members => _members;
-
-  /**
-   * Return the native clause for this class, or `null` if the class does not
-   * have a native clause.
-   */
-  NativeClause get nativeClause => _nativeClause;
-
-  /**
-   * Set the native clause for this class to the given [nativeClause].
-   */
-  void set nativeClause(NativeClause nativeClause) {
-    _nativeClause = _becomeParentOf(nativeClause);
-  }
-
-  /**
-   * Return the type parameters for the class, or `null` if the class does not
-   * have any type parameters.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters for the class to the given list of [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  /**
-   * Return the with clause for the class, or `null` if the class does not have
-   * a with clause.
-   */
-  WithClause get withClause => _withClause;
-
-  /**
-   * Set the with clause for the class to the given [withClause].
-   */
-  void set withClause(WithClause withClause) {
-    _withClause = _becomeParentOf(withClause);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitClassDeclaration(this);
-
-  /**
-   * Return the constructor declared in the class with the given [name], or
-   * `null` if there is no such constructor. If the [name] is `null` then the
-   * default constructor will be searched for.
-   */
-  ConstructorDeclaration getConstructor(String name) {
-    for (ClassMember classMember in _members) {
-      if (classMember is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = classMember;
-        SimpleIdentifier constructorName = constructor.name;
-        if (name == null && constructorName == null) {
-          return constructor;
-        }
-        if (constructorName != null && constructorName.name == name) {
-          return constructor;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the field declared in the class with the given [name], or `null` if
-   * there is no such field.
-   */
-  VariableDeclaration getField(String name) {
-    for (ClassMember classMember in _members) {
-      if (classMember is FieldDeclaration) {
-        FieldDeclaration fieldDeclaration = classMember;
-        NodeList<VariableDeclaration> fields =
-            fieldDeclaration.fields.variables;
-        for (VariableDeclaration field in fields) {
-          SimpleIdentifier fieldName = field.name;
-          if (fieldName != null && name == fieldName.name) {
-            return field;
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the method declared in the class with the given [name], or `null` if
-   * there is no such method.
-   */
-  MethodDeclaration getMethod(String name) {
-    for (ClassMember classMember in _members) {
-      if (classMember is MethodDeclaration) {
-        MethodDeclaration method = classMember;
-        SimpleIdentifier methodName = method.name;
-        if (methodName != null && name == methodName.name) {
-          return method;
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_extendsClause, visitor);
-    _safelyVisitChild(_withClause, visitor);
-    _safelyVisitChild(_implementsClause, visitor);
-    _safelyVisitChild(_nativeClause, visitor);
-    members.accept(visitor);
-  }
-}
-
-/**
- * A node that declares a name within the scope of a class.
- */
-abstract class ClassMember extends Declaration {
-  /**
-   * Initialize a newly created member of a class. Either or both of the
-   * [comment] and [metadata] can be `null` if the member does not have the
-   * corresponding attribute.
-   */
-  ClassMember(Comment comment, List<Annotation> metadata)
-      : super(comment, metadata);
-}
-
-/**
- * A class type alias.
- *
- * > classTypeAlias ::=
- * >     [SimpleIdentifier] [TypeParameterList]? '=' 'abstract'? mixinApplication
- * >
- * > mixinApplication ::=
- * >     [TypeName] [WithClause] [ImplementsClause]? ';'
- */
-class ClassTypeAlias extends TypeAlias {
-  /**
-   * The type parameters for the class, or `null` if the class does not have any
-   * type parameters.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The token for the '=' separating the name from the definition.
-   */
-  Token equals;
-
-  /**
-   * The token for the 'abstract' keyword, or `null` if this is not defining an
-   * abstract class.
-   */
-  Token abstractKeyword;
-
-  /**
-   * The name of the superclass of the class being declared.
-   */
-  TypeName _superclass;
-
-  /**
-   * The with clause for this class.
-   */
-  WithClause _withClause;
-
-  /**
-   * The implements clause for this class, or `null` if there is no implements
-   * clause.
-   */
-  ImplementsClause _implementsClause;
-
-  /**
-   * Initialize a newly created class type alias. Either or both of the
-   * [comment] and [metadata] can be `null` if the class type alias does not
-   * have the corresponding attribute. The [typeParameters] can be `null` if the
-   * class does not have any type parameters. The [abstractKeyword] can be
-   * `null` if the class is not abstract. The [implementsClause] can be `null`
-   * if the class does not implement any interfaces.
-   */
-  ClassTypeAlias(
-      Comment comment,
-      List<Annotation> metadata,
-      Token keyword,
-      SimpleIdentifier name,
-      TypeParameterList typeParameters,
-      this.equals,
-      this.abstractKeyword,
-      TypeName superclass,
-      WithClause withClause,
-      ImplementsClause implementsClause,
-      Token semicolon)
-      : super(comment, metadata, keyword, name, semicolon) {
-    _typeParameters = _becomeParentOf(typeParameters);
-    _superclass = _becomeParentOf(superclass);
-    _withClause = _becomeParentOf(withClause);
-    _implementsClause = _becomeParentOf(implementsClause);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(typedefKeyword)
-    ..add(_name)
-    ..add(_typeParameters)
-    ..add(equals)
-    ..add(abstractKeyword)
-    ..add(_superclass)
-    ..add(_withClause)
-    ..add(_implementsClause)
-    ..add(semicolon);
-
-  @override
-  ClassElement get element =>
-      _name != null ? (_name.staticElement as ClassElement) : null;
-
-  /**
-   * Return the implements clause for this class, or `null` if there is no
-   * implements clause.
-   */
-  ImplementsClause get implementsClause => _implementsClause;
-
-  /**
-   * Set the implements clause for this class to the given [implementsClause].
-   */
-  void set implementsClause(ImplementsClause implementsClause) {
-    _implementsClause = _becomeParentOf(implementsClause);
-  }
-
-  /**
-   * Return `true` if this class is declared to be an abstract class.
-   */
-  bool get isAbstract => abstractKeyword != null;
-
-  /**
-   * Return the name of the superclass of the class being declared.
-   */
-  TypeName get superclass => _superclass;
-
-  /**
-   * Set the name of the superclass of the class being declared to the given
-   * [superclass] name.
-   */
-  void set superclass(TypeName superclass) {
-    _superclass = _becomeParentOf(superclass);
-  }
-
-  /**
-   * Return the type parameters for the class, or `null` if the class does not
-   * have any type parameters.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters for the class to the given list of [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  /**
-   * Return the with clause for this class.
-   */
-  WithClause get withClause => _withClause;
-
-  /**
-   * Set the with clause for this class to the given with [withClause].
-   */
-  void set withClause(WithClause withClause) {
-    _withClause = _becomeParentOf(withClause);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitClassTypeAlias(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_superclass, visitor);
-    _safelyVisitChild(_withClause, visitor);
-    _safelyVisitChild(_implementsClause, visitor);
-  }
-}
-
-/**
- * A combinator associated with an import or export directive.
- *
- * > combinator ::=
- * >     [HideCombinator]
- * >   | [ShowCombinator]
- */
-abstract class Combinator extends AstNode {
-  /**
-   * The 'hide' or 'show' keyword specifying what kind of processing is to be
-   * done on the names.
-   */
-  Token keyword;
-
-  /**
-   * Initialize a newly created combinator.
-   */
-  Combinator(this.keyword);
-
-  @override
-  Token get beginToken => keyword;
-}
-
-/**
- * A comment within the source code.
- *
- * > comment ::=
- * >     endOfLineComment
- * >   | blockComment
- * >   | documentationComment
- * >
- * > endOfLineComment ::=
- * >     '//' (CHARACTER - EOL)* EOL
- * >
- * > blockComment ::=
- * >     '/ *' CHARACTER* '&#42;/'
- * >
- * > documentationComment ::=
- * >     '/ **' (CHARACTER | [CommentReference])* '&#42;/'
- * >   | ('///' (CHARACTER - EOL)* EOL)+
- */
-class Comment extends AstNode {
-  /**
-   * The tokens representing the comment.
-   */
-  final List<Token> tokens;
-
-  /**
-   * The type of the comment.
-   */
-  final CommentType _type;
-
-  /**
-   * The references embedded within the documentation comment. This list will be
-   * empty unless this is a documentation comment that has references embedded
-   * within it.
-   */
-  NodeList<CommentReference> _references;
-
-  /**
-   * Initialize a newly created comment. The list of [tokens] must contain at
-   * least one token. The [type] is the type of the comment. The list of
-   * [references] can be empty if the comment does not contain any embedded
-   * references.
-   */
-  Comment(this.tokens, this._type, List<CommentReference> references) {
-    _references = new NodeList<CommentReference>(this, references);
-  }
-
-  @override
-  Token get beginToken => tokens[0];
-
-  @override
-  Iterable get childEntities => new ChildEntities()..addAll(tokens);
-
-  @override
-  Token get endToken => tokens[tokens.length - 1];
-
-  /**
-   * Return `true` if this is a block comment.
-   */
-  bool get isBlock => _type == CommentType.BLOCK;
-
-  /**
-   * Return `true` if this is a documentation comment.
-   */
-  bool get isDocumentation => _type == CommentType.DOCUMENTATION;
-
-  /**
-   * Return `true` if this is an end-of-line comment.
-   */
-  bool get isEndOfLine => _type == CommentType.END_OF_LINE;
-
-  /**
-   * Return the references embedded within the documentation comment.
-   */
-  NodeList<CommentReference> get references => _references;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitComment(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _references.accept(visitor);
-  }
-
-  /**
-   * Create a block comment consisting of the given [tokens].
-   */
-  static Comment createBlockComment(List<Token> tokens) =>
-      new Comment(tokens, CommentType.BLOCK, null);
-
-  /**
-   * Create a documentation comment consisting of the given [tokens].
-   */
-  static Comment createDocumentationComment(List<Token> tokens) => new Comment(
-      tokens, CommentType.DOCUMENTATION, new List<CommentReference>());
-
-  /**
-   * Create a documentation comment consisting of the given [tokens] and having
-   * the given [references] embedded within it.
-   */
-  static Comment createDocumentationCommentWithReferences(
-          List<Token> tokens, List<CommentReference> references) =>
-      new Comment(tokens, CommentType.DOCUMENTATION, references);
-
-  /**
-   * Create an end-of-line comment consisting of the given [tokens].
-   */
-  static Comment createEndOfLineComment(List<Token> tokens) =>
-      new Comment(tokens, CommentType.END_OF_LINE, null);
-}
-
-/**
- * A reference to a Dart element that is found within a documentation comment.
- *
- * > commentReference ::=
- * >     '[' 'new'? [Identifier] ']'
- */
-class CommentReference extends AstNode {
-  /**
-   * The token representing the 'new' keyword, or `null` if there was no 'new'
-   * keyword.
-   */
-  Token newKeyword;
-
-  /**
-   * The identifier being referenced.
-   */
-  Identifier _identifier;
-
-  /**
-   * Initialize a newly created reference to a Dart element. The [newKeyword]
-   * can be `null` if the reference is not to a constructor.
-   */
-  CommentReference(this.newKeyword, Identifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  @override
-  Token get beginToken => _identifier.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(newKeyword)..add(_identifier);
-
-  @override
-  Token get endToken => _identifier.endToken;
-
-  /**
-   * Return the identifier being referenced.
-   */
-  Identifier get identifier => _identifier;
-
-  /**
-   * Set the identifier being referenced to the given [identifier].
-   */
-  void set identifier(Identifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitCommentReference(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_identifier, visitor);
-  }
-}
-
-/**
- * The possible types of comments that are recognized by the parser.
- */
-class CommentType {
-  /**
-   * A block comment.
-   */
-  static const CommentType BLOCK = const CommentType('BLOCK');
-
-  /**
-   * A documentation comment.
-   */
-  static const CommentType DOCUMENTATION = const CommentType('DOCUMENTATION');
-
-  /**
-   * An end-of-line comment.
-   */
-  static const CommentType END_OF_LINE = const CommentType('END_OF_LINE');
-
-  /**
-   * The name of the comment type.
-   */
-  final String name;
-
-  /**
-   * Initialize a newly created comment type to have the given [name].
-   */
-  const CommentType(this.name);
-
-  @override
-  String toString() => name;
-}
-
-/**
- * A compilation unit.
- *
- * While the grammar restricts the order of the directives and declarations
- * within a compilation unit, this class does not enforce those restrictions.
- * In particular, the children of a compilation unit will be visited in lexical
- * order even if lexical order does not conform to the restrictions of the
- * grammar.
- *
- * > compilationUnit ::=
- * >     directives declarations
- * >
- * > directives ::=
- * >     [ScriptTag]? [LibraryDirective]? namespaceDirective* [PartDirective]*
- * >   | [PartOfDirective]
- * >
- * > namespaceDirective ::=
- * >     [ImportDirective]
- * >   | [ExportDirective]
- * >
- * > declarations ::=
- * >     [CompilationUnitMember]*
- */
-class CompilationUnit extends AstNode {
-  /**
-   * The first token in the token stream that was parsed to form this
-   * compilation unit.
-   */
-  Token beginToken;
-
-  /**
-   * The script tag at the beginning of the compilation unit, or `null` if there
-   * is no script tag in this compilation unit.
-   */
-  ScriptTag _scriptTag;
-
-  /**
-   * The directives contained in this compilation unit.
-   */
-  NodeList<Directive> _directives;
-
-  /**
-   * The declarations contained in this compilation unit.
-   */
-  NodeList<CompilationUnitMember> _declarations;
-
-  /**
-   * The last token in the token stream that was parsed to form this compilation
-   * unit. This token should always have a type of [TokenType.EOF].
-   */
-  Token endToken;
-
-  /**
-   * The element associated with this compilation unit, or `null` if the AST
-   * structure has not been resolved.
-   */
-  CompilationUnitElement element;
-
-  /**
-   * The line information for this compilation unit.
-   */
-  LineInfo lineInfo;
-
-  /**
-   * Initialize a newly created compilation unit to have the given directives
-   * and declarations. The [scriptTag] can be `null` if there is no script tag
-   * in the compilation unit. The list of [directives] can be `null` if there
-   * are no directives in the compilation unit. The list of [declarations] can
-   * be `null` if there are no declarations in the compilation unit.
-   */
-  CompilationUnit(
-      this.beginToken,
-      ScriptTag scriptTag,
-      List<Directive> directives,
-      List<CompilationUnitMember> declarations,
-      this.endToken) {
-    _scriptTag = _becomeParentOf(scriptTag);
-    _directives = new NodeList<Directive>(this, directives);
-    _declarations = new NodeList<CompilationUnitMember>(this, declarations);
-  }
-
-  @override
-  Iterable get childEntities {
-    ChildEntities result = new ChildEntities()..add(_scriptTag);
-    if (_directivesAreBeforeDeclarations) {
-      result..addAll(_directives)..addAll(_declarations);
-    } else {
-      result.addAll(sortedDirectivesAndDeclarations);
-    }
-    return result;
-  }
-
-  /**
-   * Return the declarations contained in this compilation unit.
-   */
-  NodeList<CompilationUnitMember> get declarations => _declarations;
-
-  /**
-   * Return the directives contained in this compilation unit.
-   */
-  NodeList<Directive> get directives => _directives;
-
-  @override
-  int get length {
-    Token endToken = this.endToken;
-    if (endToken == null) {
-      return 0;
-    }
-    return endToken.offset + endToken.length;
-  }
-
-  @override
-  int get offset => 0;
-
-  /**
-   * Return the script tag at the beginning of the compilation unit, or `null`
-   * if there is no script tag in this compilation unit.
-   */
-  ScriptTag get scriptTag => _scriptTag;
-
-  /**
-   * Set the script tag at the beginning of the compilation unit to the given
-   * [scriptTag].
-   */
-  void set scriptTag(ScriptTag scriptTag) {
-    _scriptTag = _becomeParentOf(scriptTag);
-  }
-
-  /**
-   * Return a list containing all of the directives and declarations in this
-   * compilation unit, sorted in lexical order.
-   */
-  List<AstNode> get sortedDirectivesAndDeclarations {
-    return <AstNode>[]
-      ..addAll(_directives)
-      ..addAll(_declarations)
-      ..sort(AstNode.LEXICAL_ORDER);
-  }
-
-  /**
-   * Return `true` if all of the directives are lexically before any
-   * declarations.
-   */
-  bool get _directivesAreBeforeDeclarations {
-    if (_directives.isEmpty || _declarations.isEmpty) {
-      return true;
-    }
-    Directive lastDirective = _directives[_directives.length - 1];
-    CompilationUnitMember firstDeclaration = _declarations[0];
-    return lastDirective.offset < firstDeclaration.offset;
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitCompilationUnit(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_scriptTag, visitor);
-    if (_directivesAreBeforeDeclarations) {
-      _directives.accept(visitor);
-      _declarations.accept(visitor);
-    } else {
-      for (AstNode child in sortedDirectivesAndDeclarations) {
-        child.accept(visitor);
-      }
-    }
-  }
-}
-
-/**
- * A node that declares one or more names within the scope of a compilation
- * unit.
- *
- * > compilationUnitMember ::=
- * >     [ClassDeclaration]
- * >   | [TypeAlias]
- * >   | [FunctionDeclaration]
- * >   | [MethodDeclaration]
- * >   | [VariableDeclaration]
- * >   | [VariableDeclaration]
- */
-abstract class CompilationUnitMember extends Declaration {
-  /**
-   * Initialize a newly created generic compilation unit member. Either or both
-   * of the [comment] and [metadata] can be `null` if the member does not have
-   * the corresponding attribute.
-   */
-  CompilationUnitMember(Comment comment, List<Annotation> metadata)
-      : super(comment, metadata);
-}
-
-/**
- * A conditional expression.
- *
- * > conditionalExpression ::=
- * >     [Expression] '?' [Expression] ':' [Expression]
- */
-class ConditionalExpression extends Expression {
-  /**
-   * The condition used to determine which of the expressions is executed next.
-   */
-  Expression _condition;
-
-  /**
-   * The token used to separate the condition from the then expression.
-   */
-  Token question;
-
-  /**
-   * The expression that is executed if the condition evaluates to `true`.
-   */
-  Expression _thenExpression;
-
-  /**
-   * The token used to separate the then expression from the else expression.
-   */
-  Token colon;
-
-  /**
-   * The expression that is executed if the condition evaluates to `false`.
-   */
-  Expression _elseExpression;
-
-  /**
-   * Initialize a newly created conditional expression.
-   */
-  ConditionalExpression(Expression condition, this.question,
-      Expression thenExpression, this.colon, Expression elseExpression) {
-    _condition = _becomeParentOf(condition);
-    _thenExpression = _becomeParentOf(thenExpression);
-    _elseExpression = _becomeParentOf(elseExpression);
-  }
-
-  @override
-  Token get beginToken => _condition.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_condition)
-    ..add(question)
-    ..add(_thenExpression)
-    ..add(colon)
-    ..add(_elseExpression);
-
-  /**
-   * Return the condition used to determine which of the expressions is executed
-   * next.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the condition used to determine which of the expressions is executed
-   * next to the given [expression].
-   */
-  void set condition(Expression expression) {
-    _condition = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the expression that is executed if the condition evaluates to
-   * `false`.
-   */
-  Expression get elseExpression => _elseExpression;
-
-  /**
-   * Set the expression that is executed if the condition evaluates to `false`
-   * to the given [expression].
-   */
-  void set elseExpression(Expression expression) {
-    _elseExpression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get endToken => _elseExpression.endToken;
-
-  @override
-  int get precedence => 3;
-
-  /**
-   * Return the expression that is executed if the condition evaluates to
-   * `true`.
-   */
-  Expression get thenExpression => _thenExpression;
-
-  /**
-   * Set the expression that is executed if the condition evaluates to `true` to
-   * the given [expression].
-   */
-  void set thenExpression(Expression expression) {
-    _thenExpression = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitConditionalExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_condition, visitor);
-    _safelyVisitChild(_thenExpression, visitor);
-    _safelyVisitChild(_elseExpression, visitor);
-  }
-}
-
-/**
- * A configuration in either an import or export directive.
- *
- *     configuration ::=
- *         'if' '(' test ')' uri
- *
- *     test ::=
- *         dottedName ('==' stringLiteral)?
- *
- *     dottedName ::=
- *         identifier ('.' identifier)*
- */
-class Configuration extends AstNode {
-  Token ifKeyword;
-  Token leftParenthesis;
-  DottedName _name;
-  Token equalToken;
-  StringLiteral _value;
-  Token rightParenthesis;
-  StringLiteral _libraryUri;
-
-  Configuration(
-      this.ifKeyword,
-      this.leftParenthesis,
-      DottedName name,
-      this.equalToken,
-      StringLiteral value,
-      this.rightParenthesis,
-      StringLiteral libraryUri) {
-    _name = _becomeParentOf(name);
-    _value = _becomeParentOf(value);
-    _libraryUri = _becomeParentOf(libraryUri);
-  }
-
-  @override
-  Token get beginToken => ifKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(ifKeyword)
-    ..add(leftParenthesis)
-    ..add(_name)
-    ..add(equalToken)
-    ..add(_value)
-    ..add(rightParenthesis)
-    ..add(_libraryUri);
-
-  @override
-  Token get endToken => _libraryUri.endToken;
-
-  StringLiteral get libraryUri => _libraryUri;
-
-  void set libraryUri(StringLiteral libraryUri) {
-    _libraryUri = _becomeParentOf(libraryUri);
-  }
-
-  DottedName get name => _name;
-
-  void set name(DottedName name) {
-    _name = _becomeParentOf(name);
-  }
-
-  StringLiteral get value => _value;
-
-  void set value(StringLiteral value) {
-    _value = _becomeParentOf(value);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitConfiguration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_value, visitor);
-    _safelyVisitChild(_libraryUri, visitor);
-  }
-}
-
-/**
- * A constructor declaration.
- *
- * > constructorDeclaration ::=
- * >     constructorSignature [FunctionBody]?
- * >   | constructorName formalParameterList ':' 'this' ('.' [SimpleIdentifier])? arguments
- * >
- * > constructorSignature ::=
- * >     'external'? constructorName formalParameterList initializerList?
- * >   | 'external'? 'factory' factoryName formalParameterList initializerList?
- * >   | 'external'? 'const'  constructorName formalParameterList initializerList?
- * >
- * > constructorName ::=
- * >     [SimpleIdentifier] ('.' [SimpleIdentifier])?
- * >
- * > factoryName ::=
- * >     [Identifier] ('.' [SimpleIdentifier])?
- * >
- * > initializerList ::=
- * >     ':' [ConstructorInitializer] (',' [ConstructorInitializer])*
- */
-class ConstructorDeclaration extends ClassMember {
-  /**
-   * The token for the 'external' keyword, or `null` if the constructor is not
-   * external.
-   */
-  Token externalKeyword;
-
-  /**
-   * The token for the 'const' keyword, or `null` if the constructor is not a
-   * const constructor.
-   */
-  Token constKeyword;
-
-  /**
-   * The token for the 'factory' keyword, or `null` if the constructor is not a
-   * factory constructor.
-   */
-  Token factoryKeyword;
-
-  /**
-   * The type of object being created. This can be different than the type in
-   * which the constructor is being declared if the constructor is the
-   * implementation of a factory constructor.
-   */
-  Identifier _returnType;
-
-  /**
-   * The token for the period before the constructor name, or `null` if the
-   * constructor being declared is unnamed.
-   */
-  Token period;
-
-  /**
-   * The name of the constructor, or `null` if the constructor being declared is
-   * unnamed.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * The parameters associated with the constructor.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * The token for the separator (colon or equals) before the initializer list
-   * or redirection, or `null` if there are no initializers.
-   */
-  Token separator;
-
-  /**
-   * The initializers associated with the constructor.
-   */
-  NodeList<ConstructorInitializer> _initializers;
-
-  /**
-   * The name of the constructor to which this constructor will be redirected,
-   * or `null` if this is not a redirecting factory constructor.
-   */
-  ConstructorName _redirectedConstructor;
-
-  /**
-   * The body of the constructor, or `null` if the constructor does not have a
-   * body.
-   */
-  FunctionBody _body;
-
-  /**
-   * The element associated with this constructor, or `null` if the AST
-   * structure has not been resolved or if this constructor could not be
-   * resolved.
-   */
-  ConstructorElement element;
-
-  /**
-   * Initialize a newly created constructor declaration. The [externalKeyword]
-   * can be `null` if the constructor is not external. Either or both of the
-   * [comment] and [metadata] can be `null` if the constructor does not have the
-   * corresponding attribute. The [constKeyword] can be `null` if the
-   * constructor cannot be used to create a constant. The [factoryKeyword] can
-   * be `null` if the constructor is not a factory. The [period] and [name] can
-   * both be `null` if the constructor is not a named constructor. The
-   * [separator] can be `null` if the constructor does not have any initializers
-   * and does not redirect to a different constructor. The list of
-   * [initializers] can be `null` if the constructor does not have any
-   * initializers. The [redirectedConstructor] can be `null` if the constructor
-   * does not redirect to a different constructor. The [body] can be `null` if
-   * the constructor does not have a body.
-   */
-  ConstructorDeclaration(
-      Comment comment,
-      List<Annotation> metadata,
-      this.externalKeyword,
-      this.constKeyword,
-      this.factoryKeyword,
-      Identifier returnType,
-      this.period,
-      SimpleIdentifier name,
-      FormalParameterList parameters,
-      this.separator,
-      List<ConstructorInitializer> initializers,
-      ConstructorName redirectedConstructor,
-      FunctionBody body)
-      : super(comment, metadata) {
-    _returnType = _becomeParentOf(returnType);
-    _name = _becomeParentOf(name);
-    _parameters = _becomeParentOf(parameters);
-    _initializers = new NodeList<ConstructorInitializer>(this, initializers);
-    _redirectedConstructor = _becomeParentOf(redirectedConstructor);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
-   * Return the body of the constructor, or `null` if the constructor does not
-   * have a body.
-   */
-  FunctionBody get body => _body;
-
-  /**
-   * Set the body of the constructor to the given [functionBody].
-   */
-  void set body(FunctionBody functionBody) {
-    _body = _becomeParentOf(functionBody);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(externalKeyword)
-    ..add(constKeyword)
-    ..add(factoryKeyword)
-    ..add(_returnType)
-    ..add(period)
-    ..add(_name)
-    ..add(_parameters)
-    ..add(separator)
-    ..addAll(initializers)
-    ..add(_redirectedConstructor)
-    ..add(_body);
-
-  @override
-  Token get endToken {
-    if (_body != null) {
-      return _body.endToken;
-    } else if (!_initializers.isEmpty) {
-      return _initializers.endToken;
-    }
-    return _parameters.endToken;
-  }
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    Token leftMost =
-        Token.lexicallyFirst([externalKeyword, constKeyword, factoryKeyword]);
-    if (leftMost != null) {
-      return leftMost;
-    }
-    return _returnType.beginToken;
-  }
-
-  /**
-   * Return the initializers associated with the constructor.
-   */
-  NodeList<ConstructorInitializer> get initializers => _initializers;
-
-  /**
-   * Return the name of the constructor, or `null` if the constructor being
-   * declared is unnamed.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the constructor to the given [identifier].
-   */
-  void set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the parameters associated with the constructor.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters associated with the constructor to the given list of
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  /**
-   * Return the name of the constructor to which this constructor will be
-   * redirected, or `null` if this is not a redirecting factory constructor.
-   */
-  ConstructorName get redirectedConstructor => _redirectedConstructor;
-
-  /**
-   * Set the name of the constructor to which this constructor will be
-   * redirected to the given [redirectedConstructor] name.
-   */
-  void set redirectedConstructor(ConstructorName redirectedConstructor) {
-    _redirectedConstructor = _becomeParentOf(redirectedConstructor);
-  }
-
-  /**
-   * Return the type of object being created. This can be different than the
-   * type in which the constructor is being declared if the constructor is the
-   * implementation of a factory constructor.
-   */
-  Identifier get returnType => _returnType;
-
-  /**
-   * Set the type of object being created to the given [typeName].
-   */
-  void set returnType(Identifier typeName) {
-    _returnType = _becomeParentOf(typeName);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitConstructorDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_returnType, visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_parameters, visitor);
-    _initializers.accept(visitor);
-    _safelyVisitChild(_redirectedConstructor, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * The initialization of a field within a constructor's initialization list.
- *
- * > fieldInitializer ::=
- * >     ('this' '.')? [SimpleIdentifier] '=' [Expression]
- */
-class ConstructorFieldInitializer extends ConstructorInitializer {
-  /**
-   * The token for the 'this' keyword, or `null` if there is no 'this' keyword.
-   */
-  Token thisKeyword;
-
-  /**
-   * The token for the period after the 'this' keyword, or `null` if there is no
-   * 'this' keyword.
-   */
-  Token period;
-
-  /**
-   * The name of the field being initialized.
-   */
-  SimpleIdentifier _fieldName;
-
-  /**
-   * The token for the equal sign between the field name and the expression.
-   */
-  Token equals;
-
-  /**
-   * The expression computing the value to which the field will be initialized.
-   */
-  Expression _expression;
-
-  /**
-   * Initialize a newly created field initializer to initialize the field with
-   * the given name to the value of the given expression. The [thisKeyword] and
-   * [period] can be `null` if the 'this' keyword was not specified.
-   */
-  ConstructorFieldInitializer(this.thisKeyword, this.period,
-      SimpleIdentifier fieldName, this.equals, Expression expression) {
-    _fieldName = _becomeParentOf(fieldName);
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken {
-    if (thisKeyword != null) {
-      return thisKeyword;
-    }
-    return _fieldName.beginToken;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(thisKeyword)
-    ..add(period)
-    ..add(_fieldName)
-    ..add(equals)
-    ..add(_expression);
-
-  @override
-  Token get endToken => _expression.endToken;
-
-  /**
-   * Return the expression computing the value to which the field will be
-   * initialized.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression computing the value to which the field will be
-   * initialized to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the name of the field being initialized.
-   */
-  SimpleIdentifier get fieldName => _fieldName;
-
-  /**
-   * Set the name of the field being initialized to the given [identifier].
-   */
-  void set fieldName(SimpleIdentifier identifier) {
-    _fieldName = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_fieldName, visitor);
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A node that can occur in the initializer list of a constructor declaration.
- *
- * > constructorInitializer ::=
- * >     [SuperConstructorInvocation]
- * >   | [ConstructorFieldInitializer]
- * >   | [RedirectingConstructorInvocation]
- */
-abstract class ConstructorInitializer extends AstNode {}
-
-/**
- * The name of the constructor.
- *
- * > constructorName ::=
- * >     type ('.' identifier)?
- */
-class ConstructorName extends AstNode {
-  /**
-   * The name of the type defining the constructor.
-   */
-  TypeName _type;
-
-  /**
-   * The token for the period before the constructor name, or `null` if the
-   * specified constructor is the unnamed constructor.
-   */
-  Token period;
-
-  /**
-   * The name of the constructor, or `null` if the specified constructor is the
-   * unnamed constructor.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * The element associated with this constructor name based on static type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this constructor name could not be resolved.
-   */
-  ConstructorElement staticElement;
-
-  /**
-   * Initialize a newly created constructor name. The [period] and [name] can be
-   * `null` if the constructor being named is the unnamed constructor.
-   */
-  ConstructorName(TypeName type, this.period, SimpleIdentifier name) {
-    _type = _becomeParentOf(type);
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  Token get beginToken => _type.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_type)..add(period)..add(_name);
-
-  @override
-  Token get endToken {
-    if (_name != null) {
-      return _name.endToken;
-    }
-    return _type.endToken;
-  }
-
-  /**
-   * Return the name of the constructor, or `null` if the specified constructor
-   * is the unnamed constructor.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the constructor to the given [name].
-   */
-  void set name(SimpleIdentifier name) {
-    _name = _becomeParentOf(name);
-  }
-
-  /**
-   * Return the name of the type defining the constructor.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the type defining the constructor to the given [type] name.
-   */
-  void set type(TypeName type) {
-    _type = _becomeParentOf(type);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitConstructorName(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_type, visitor);
-    _safelyVisitChild(_name, visitor);
-  }
-}
-
-/**
- * A continue statement.
- *
- * > continueStatement ::=
- * >     'continue' [SimpleIdentifier]? ';'
- */
-class ContinueStatement extends Statement {
-  /**
-   * The token representing the 'continue' keyword.
-   */
-  Token continueKeyword;
-
-  /**
-   * The label associated with the statement, or `null` if there is no label.
-   */
-  SimpleIdentifier _label;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * The AstNode which this continue statement is continuing to.  This will be
-   * either a Statement (in the case of continuing a loop) or a SwitchMember
-   * (in the case of continuing from one switch case to another).  Null if the
-   * AST has not yet been resolved or if the target could not be resolved.
-   * Note that if the source code has errors, the target may be invalid (e.g.
-   * the target may be in an enclosing function).
-   */
-  AstNode target;
-
-  /**
-   * Initialize a newly created continue statement. The [label] can be `null` if
-   * there is no label associated with the statement.
-   */
-  ContinueStatement(
-      this.continueKeyword, SimpleIdentifier label, this.semicolon) {
-    _label = _becomeParentOf(label);
-  }
-
-  @override
-  Token get beginToken => continueKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(continueKeyword)..add(_label)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the label associated with the statement, or `null` if there is no
-   * label.
-   */
-  SimpleIdentifier get label => _label;
-
-  /**
-   * Set the label associated with the statement to the given [identifier].
-   */
-  void set label(SimpleIdentifier identifier) {
-    _label = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitContinueStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_label, visitor);
-  }
-}
-
-/**
- * A node that represents the declaration of one or more names. Each declared
- * name is visible within a name scope.
- */
-abstract class Declaration extends AnnotatedNode {
-  /**
-   * Initialize a newly created declaration. Either or both of the [comment] and
-   * [metadata] can be `null` if the declaration does not have the corresponding
-   * attribute.
-   */
-  Declaration(Comment comment, List<Annotation> metadata)
-      : super(comment, metadata);
-
-  /**
-   * Return the element associated with this declaration, or `null` if either
-   * this node corresponds to a list of declarations or if the AST structure has
-   * not been resolved.
-   */
-  Element get element;
-}
-
-/**
- * The declaration of a single identifier.
- *
- * > declaredIdentifier ::=
- * >     [Annotation] finalConstVarOrType [SimpleIdentifier]
- */
-class DeclaredIdentifier extends Declaration {
-  /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or
-   * `null` if no keyword was used.
-   */
-  Token keyword;
-
-  /**
-   * The name of the declared type of the parameter, or `null` if the parameter
-   * does not have a declared type.
-   */
-  TypeName _type;
-
-  /**
-   * The name of the variable being declared.
-   */
-  SimpleIdentifier _identifier;
-
-  /**
-   * Initialize a newly created formal parameter. Either or both of the
-   * [comment] and [metadata] can be `null` if the declaration does not have the
-   * corresponding attribute. The [keyword] can be `null` if a type name is
-   * given. The [type] must be `null` if the keyword is 'var'.
-   */
-  DeclaredIdentifier(Comment comment, List<Annotation> metadata, this.keyword,
-      TypeName type, SimpleIdentifier identifier)
-      : super(comment, metadata) {
-    _type = _becomeParentOf(type);
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(keyword)..add(_type)..add(_identifier);
-
-  @override
-  LocalVariableElement get element {
-    if (_identifier == null) {
-      return null;
-    }
-    return _identifier.staticElement as LocalVariableElement;
-  }
-
-  @override
-  Token get endToken => _identifier.endToken;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (keyword != null) {
-      return keyword;
-    } else if (_type != null) {
-      return _type.beginToken;
-    }
-    return _identifier.beginToken;
-  }
-
-  /**
-   * Return the name of the variable being declared.
-   */
-  SimpleIdentifier get identifier => _identifier;
-
-  /**
-   * Set the name of the variable being declared to the given [identifier].
-   */
-  void set identifier(SimpleIdentifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
-  bool get isConst =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.CONST;
-
-  /**
-   * 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 =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.FINAL;
-
-  /**
-   * Return the name of the declared type of the parameter, or `null` if the
-   * parameter does not have a declared type.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the declared type of the parameter to the given [typeName].
-   */
-  void set type(TypeName typeName) {
-    _type = _becomeParentOf(typeName);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitDeclaredIdentifier(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_type, visitor);
-    _safelyVisitChild(_identifier, visitor);
-  }
-}
-
-/**
- * A formal parameter with a default value. There are two kinds of parameters
- * that are both represented by this class: named formal parameters and
- * positional formal parameters.
- *
- * > defaultFormalParameter ::=
- * >     [NormalFormalParameter] ('=' [Expression])?
- * >
- * > defaultNamedParameter ::=
- * >     [NormalFormalParameter] (':' [Expression])?
- */
-class DefaultFormalParameter extends FormalParameter {
-  /**
-   * The formal parameter with which the default value is associated.
-   */
-  NormalFormalParameter _parameter;
-
-  /**
-   * The kind of this parameter.
-   */
-  ParameterKind kind;
-
-  /**
-   * The token separating the parameter from the default value, or `null` if
-   * there is no default value.
-   */
-  Token separator;
-
-  /**
-   * The expression computing the default value for the parameter, or `null` if
-   * there is no default value.
-   */
-  Expression _defaultValue;
-
-  /**
-   * Initialize a newly created default formal parameter. The [separator] and
-   * [defaultValue] can be `null` if there is no default value.
-   */
-  DefaultFormalParameter(NormalFormalParameter parameter, this.kind,
-      this.separator, Expression defaultValue) {
-    _parameter = _becomeParentOf(parameter);
-    _defaultValue = _becomeParentOf(defaultValue);
-  }
-
-  @override
-  Token get beginToken => _parameter.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_parameter)..add(separator)..add(_defaultValue);
-
-  /**
-   * Return the expression computing the default value for the parameter, or
-   * `null` if there is no default value.
-   */
-  Expression get defaultValue => _defaultValue;
-
-  /**
-   * Set the expression computing the default value for the parameter to the
-   * given [expression].
-   */
-  void set defaultValue(Expression expression) {
-    _defaultValue = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get endToken {
-    if (_defaultValue != null) {
-      return _defaultValue.endToken;
-    }
-    return _parameter.endToken;
-  }
-
-  @override
-  SimpleIdentifier get identifier => _parameter.identifier;
-
-  @override
-  bool get isConst => _parameter != null && _parameter.isConst;
-
-  @override
-  bool get isFinal => _parameter != null && _parameter.isFinal;
-
-  @override
-  NodeList<Annotation> get metadata => _parameter.metadata;
-
-  /**
-   * Return the formal parameter with which the default value is associated.
-   */
-  NormalFormalParameter get parameter => _parameter;
-
-  /**
-   * Set the formal parameter with which the default value is associated to the
-   * given [formalParameter].
-   */
-  void set parameter(NormalFormalParameter formalParameter) {
-    _parameter = _becomeParentOf(formalParameter);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitDefaultFormalParameter(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_parameter, visitor);
-    _safelyVisitChild(_defaultValue, visitor);
-  }
-}
-
-/**
- * A node that represents a directive.
- *
- * > directive ::=
- * >     [ExportDirective]
- * >   | [ImportDirective]
- * >   | [LibraryDirective]
- * >   | [PartDirective]
- * >   | [PartOfDirective]
- */
-abstract class Directive extends AnnotatedNode {
-  /**
-   * The element associated with this directive, or `null` if the AST structure
-   * has not been resolved or if this directive could not be resolved.
-   */
-  Element element;
-
-  /**
-   * Initialize a newly create directive. Either or both of the [comment] and
-   * [metadata] can be `null` if the directive does not have the corresponding
-   * attribute.
-   */
-  Directive(Comment comment, List<Annotation> metadata)
-      : super(comment, metadata);
-
-  /**
-   * Return the token representing the keyword that introduces this directive
-   * ('import', 'export', 'library' or 'part').
-   */
-  Token get keyword;
-}
-
-/**
- * A do statement.
- *
- * > doStatement ::=
- * >     'do' [Statement] 'while' '(' [Expression] ')' ';'
- */
-class DoStatement extends Statement {
-  /**
-   * The token representing the 'do' keyword.
-   */
-  Token doKeyword;
-
-  /**
-   * The body of the loop.
-   */
-  Statement _body;
-
-  /**
-   * The token representing the 'while' keyword.
-   */
-  Token whileKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The condition that determines when the loop will terminate.
-   */
-  Expression _condition;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created do loop.
-   */
-  DoStatement(
-      this.doKeyword,
-      Statement body,
-      this.whileKeyword,
-      this.leftParenthesis,
-      Expression condition,
-      this.rightParenthesis,
-      this.semicolon) {
-    _body = _becomeParentOf(body);
-    _condition = _becomeParentOf(condition);
-  }
-
-  @override
-  Token get beginToken => doKeyword;
-
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body => _body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement) {
-    _body = _becomeParentOf(statement);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(doKeyword)
-    ..add(_body)
-    ..add(whileKeyword)
-    ..add(leftParenthesis)
-    ..add(_condition)
-    ..add(rightParenthesis)
-    ..add(semicolon);
-
-  /**
-   * Return the condition that determines when the loop will terminate.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the condition that determines when the loop will terminate to the given
-   * [expression].
-   */
-  void set condition(Expression expression) {
-    _condition = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitDoStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_body, visitor);
-    _safelyVisitChild(_condition, visitor);
-  }
-}
-
-/**
- * A dotted name, used in a configuration within an import or export directive.
- *
- * > dottedName ::=
- * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
- */
-class DottedName extends AstNode {
-  /**
-   * The components of the identifier.
-   */
-  NodeList<SimpleIdentifier> _components;
-
-  /**
-   * Initialize a newly created dotted name.
-   */
-  DottedName(List<SimpleIdentifier> components) {
-    _components = new NodeList<SimpleIdentifier>(this, components);
-  }
-
-  @override
-  Token get beginToken => _components.beginToken;
-
-  @override
-  // TODO(paulberry): add "." tokens.
-  Iterable get childEntities => new ChildEntities()..addAll(_components);
-
-  /**
-   * Return the components of the identifier.
-   */
-  NodeList<SimpleIdentifier> get components => _components;
-
-  @override
-  Token get endToken => _components.endToken;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitDottedName(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _components.accept(visitor);
-  }
-}
-
-/**
- * A floating point literal expression.
- *
- * > doubleLiteral ::=
- * >     decimalDigit+ ('.' decimalDigit*)? exponent?
- * >   | '.' decimalDigit+ exponent?
- * >
- * > exponent ::=
- * >     ('e' | 'E') ('+' | '-')? decimalDigit+
- */
-class DoubleLiteral extends Literal {
-  /**
-   * The token representing the literal.
-   */
-  Token literal;
-
-  /**
-   * The value of the literal.
-   */
-  double value;
-
-  /**
-   * Initialize a newly created floating point literal.
-   */
-  DoubleLiteral(this.literal, this.value);
-
-  @override
-  Token get beginToken => literal;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(literal);
-
-  @override
-  Token get endToken => literal;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitDoubleLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * An empty function body, which can only appear in constructors or abstract
- * methods.
- *
- * > emptyFunctionBody ::=
- * >     ';'
- */
-class EmptyFunctionBody extends FunctionBody {
-  /**
-   * The token representing the semicolon that marks the end of the function
-   * body.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created function body.
-   */
-  EmptyFunctionBody(this.semicolon);
-
-  @override
-  Token get beginToken => semicolon;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitEmptyFunctionBody(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // Empty function bodies have no children.
-  }
-}
-
-/**
- * An empty statement.
- *
- * > emptyStatement ::=
- * >     ';'
- */
-class EmptyStatement extends Statement {
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created empty statement.
-   */
-  EmptyStatement(this.semicolon);
-
-  @override
-  Token get beginToken => semicolon;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitEmptyStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * The declaration of an enum constant.
- */
-class EnumConstantDeclaration extends Declaration {
-  /**
-   * The name of the constant.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * Initialize a newly created enum constant declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the constant does not have the
-   * corresponding attribute. (Technically, enum constants cannot have metadata,
-   * but we allow it for consistency.)
-   */
-  EnumConstantDeclaration(
-      Comment comment, List<Annotation> metadata, SimpleIdentifier name)
-      : super(comment, metadata) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities..add(_name);
-
-  @override
-  FieldElement get element =>
-      _name == null ? null : (_name.staticElement as FieldElement);
-
-  @override
-  Token get endToken => _name.endToken;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
-
-  /**
-   * Return the name of the constant.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the constant to the given [name].
-   */
-  void set name(SimpleIdentifier name) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitEnumConstantDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-  }
-}
-
-/**
- * The declaration of an enumeration.
- *
- * > enumType ::=
- * >     metadata 'enum' [SimpleIdentifier] '{' [SimpleIdentifier] (',' [SimpleIdentifier])* (',')? '}'
- */
-class EnumDeclaration extends NamedCompilationUnitMember {
-  /**
-   * The 'enum' keyword.
-   */
-  Token enumKeyword;
-
-  /**
-   * The left curly bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The enumeration constants being declared.
-   */
-  NodeList<EnumConstantDeclaration> _constants;
-
-  /**
-   * The right curly bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created enumeration declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the declaration does not have the
-   * corresponding attribute. The list of [constants] must contain at least one
-   * value.
-   */
-  EnumDeclaration(
-      Comment comment,
-      List<Annotation> metadata,
-      this.enumKeyword,
-      SimpleIdentifier name,
-      this.leftBracket,
-      List<EnumConstantDeclaration> constants,
-      this.rightBracket)
-      : super(comment, metadata, name) {
-    _constants = new NodeList<EnumConstantDeclaration>(this, constants);
-  }
-
-  @override
-  // TODO(brianwilkerson) Add commas?
-  Iterable get childEntities => super._childEntities
-    ..add(enumKeyword)
-    ..add(_name)
-    ..add(leftBracket)
-    ..addAll(_constants)
-    ..add(rightBracket);
-
-  /**
-   * Return the enumeration constants being declared.
-   */
-  NodeList<EnumConstantDeclaration> get constants => _constants;
-
-  @override
-  ClassElement get element =>
-      _name != null ? (_name.staticElement as ClassElement) : null;
-
-  @override
-  Token get endToken => rightBracket;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => enumKeyword;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-    _constants.accept(visitor);
-  }
-}
-
-/**
- * Ephemeral identifiers are created as needed to mimic the presence of an empty
- * identifier.
- */
-class EphemeralIdentifier extends SimpleIdentifier {
-  EphemeralIdentifier(AstNode parent, int location)
-      : super(new StringToken(TokenType.IDENTIFIER, "", location)) {
-    parent._becomeParentOf(this);
-  }
-}
-
-/**
- * An export directive.
- *
- * > exportDirective ::=
- * >     [Annotation] 'export' [StringLiteral] [Combinator]* ';'
- */
-class ExportDirective extends NamespaceDirective {
-  /**
-   * Initialize a newly created export directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute. The list of [combinators] can be `null` if there
-   * are no combinators.
-   */
-  ExportDirective(
-      Comment comment,
-      List<Annotation> metadata,
-      Token keyword,
-      StringLiteral libraryUri,
-      List<Configuration> configurations,
-      List<Combinator> combinators,
-      Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, configurations,
-            combinators, semicolon);
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(_uri)
-    ..addAll(combinators)
-    ..add(semicolon);
-
-  @override
-  ExportElement get element => super.element as ExportElement;
-
-  @override
-  LibraryElement get uriElement {
-    if (element != null) {
-      return element.exportedLibrary;
-    }
-    return null;
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitExportDirective(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    combinators.accept(visitor);
-  }
-}
-
-/**
- * A node that represents an expression.
- *
- * > expression ::=
- * >     [AssignmentExpression]
- * >   | [ConditionalExpression] cascadeSection*
- * >   | [ThrowExpression]
- */
-abstract class Expression extends AstNode {
-  /**
-   * An empty list of expressions.
-   */
-  static const List<Expression> EMPTY_LIST = const <Expression>[];
-
-  /**
-   * The static type of this expression, or `null` if the AST structure has not
-   * been resolved.
-   */
-  DartType staticType;
-
-  /**
-   * The propagated type of this expression, or `null` if type propagation has
-   * not been performed on the AST structure.
-   */
-  DartType propagatedType;
-
-  /**
-   * Return the best parameter element information available for this
-   * expression. If type propagation was able to find a better parameter element
-   * than static analysis, that type will be returned. Otherwise, the result of
-   * static analysis will be returned.
-   */
-  ParameterElement get bestParameterElement {
-    ParameterElement propagatedElement = propagatedParameterElement;
-    if (propagatedElement != null) {
-      return propagatedElement;
-    }
-    return staticParameterElement;
-  }
-
-  /**
-   * Return the best type information available for this expression. If type
-   * propagation was able to find a better type than static analysis, that type
-   * will be returned. Otherwise, the result of static analysis will be
-   * returned. If no type analysis has been performed, then the type 'dynamic'
-   * will be returned.
-   */
-  DartType get bestType {
-    if (propagatedType != null) {
-      return propagatedType;
-    } else if (staticType != null) {
-      return staticType;
-    }
-    return DynamicTypeImpl.instance;
-  }
-
-  /**
-   * Return `true` if this expression is syntactically valid for the LHS of an
-   * [AssignmentExpression].
-   */
-  bool get isAssignable => false;
-
-  /**
-   * Return the precedence of this expression. The precedence is a positive
-   * integer value that defines how the source code is parsed into an AST. For
-   * example `a * b + c` is parsed as `(a * b) + c` because the precedence of
-   * `*` is greater than the precedence of `+`.
-   *
-   * Clients should not assume that returned values will stay the same, they
-   * might change as result of specification change. Only relative order should
-   * be used.
-   */
-  int get precedence;
-
-  /**
-   * If this expression is an argument to an invocation, and the AST structure
-   * has been resolved, and the function being invoked is known based on
-   * propagated type information, and this expression corresponds to one of the
-   * parameters of the function being invoked, then return the parameter element
-   * representing the parameter to which the value of this expression will be
-   * bound. Otherwise, return `null`.
-   */
-  ParameterElement get propagatedParameterElement {
-    AstNode parent = this.parent;
-    if (parent is ArgumentList) {
-      return parent._getPropagatedParameterElementFor(this);
-    } else if (parent is IndexExpression) {
-      IndexExpression indexExpression = parent;
-      if (identical(indexExpression.index, this)) {
-        return indexExpression._propagatedParameterElementForIndex;
-      }
-    } else if (parent is BinaryExpression) {
-      BinaryExpression binaryExpression = parent;
-      if (identical(binaryExpression.rightOperand, this)) {
-        return binaryExpression._propagatedParameterElementForRightOperand;
-      }
-    } else if (parent is AssignmentExpression) {
-      AssignmentExpression assignmentExpression = parent;
-      if (identical(assignmentExpression.rightHandSide, this)) {
-        return assignmentExpression._propagatedParameterElementForRightHandSide;
-      }
-    } else if (parent is PrefixExpression) {
-      return parent._propagatedParameterElementForOperand;
-    } else if (parent is PostfixExpression) {
-      return parent._propagatedParameterElementForOperand;
-    }
-    return null;
-  }
-
-  /**
-   * If this expression is an argument to an invocation, and the AST structure
-   * has been resolved, and the function being invoked is known based on static
-   * type information, and this expression corresponds to one of the parameters
-   * of the function being invoked, then return the parameter element
-   * representing the parameter to which the value of this expression will be
-   * bound. Otherwise, return `null`.
-   */
-  ParameterElement get staticParameterElement {
-    AstNode parent = this.parent;
-    if (parent is ArgumentList) {
-      return parent._getStaticParameterElementFor(this);
-    } else if (parent is IndexExpression) {
-      IndexExpression indexExpression = parent;
-      if (identical(indexExpression.index, this)) {
-        return indexExpression._staticParameterElementForIndex;
-      }
-    } else if (parent is BinaryExpression) {
-      BinaryExpression binaryExpression = parent;
-      if (identical(binaryExpression.rightOperand, this)) {
-        return binaryExpression._staticParameterElementForRightOperand;
-      }
-    } else if (parent is AssignmentExpression) {
-      AssignmentExpression assignmentExpression = parent;
-      if (identical(assignmentExpression.rightHandSide, this)) {
-        return assignmentExpression._staticParameterElementForRightHandSide;
-      }
-    } else if (parent is PrefixExpression) {
-      return parent._staticParameterElementForOperand;
-    } else if (parent is PostfixExpression) {
-      return parent._staticParameterElementForOperand;
-    }
-    return null;
-  }
-}
-
-/**
- * A function body consisting of a single expression.
- *
- * > expressionFunctionBody ::=
- * >     'async'? '=>' [Expression] ';'
- */
-class ExpressionFunctionBody extends FunctionBody {
-  /**
-   * The token representing the 'async' keyword, or `null` if there is no such
-   * keyword.
-   */
-  Token keyword;
-
-  /**
-   * The token introducing the expression that represents the body of the
-   * function.
-   */
-  Token functionDefinition;
-
-  /**
-   * The expression representing the body of the function.
-   */
-  Expression _expression;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created function body consisting of a block of
-   * statements. The [keyword] can be `null` if the function body is not an
-   * async function body.
-   */
-  ExpressionFunctionBody(this.keyword, this.functionDefinition,
-      Expression expression, this.semicolon) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken {
-    if (keyword != null) {
-      return keyword;
-    }
-    return functionDefinition;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(keyword)
-    ..add(functionDefinition)
-    ..add(_expression)
-    ..add(semicolon);
-
-  @override
-  Token get endToken {
-    if (semicolon != null) {
-      return semicolon;
-    }
-    return _expression.endToken;
-  }
-
-  /**
-   * Return the expression representing the body of the function.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression representing the body of the function to the given
-   * [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  bool get isAsynchronous => keyword != null;
-
-  @override
-  bool get isSynchronous => keyword == null;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitExpressionFunctionBody(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * An expression used as a statement.
- *
- * > expressionStatement ::=
- * >     [Expression]? ';'
- */
-class ExpressionStatement extends Statement {
-  /**
-   * The expression that comprises the statement.
-   */
-  Expression _expression;
-
-  /**
-   * The semicolon terminating the statement, or `null` if the expression is a
-   * function expression and therefore isn't followed by a semicolon.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created expression statement.
-   */
-  ExpressionStatement(Expression expression, this.semicolon) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => _expression.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_expression)..add(semicolon);
-
-  @override
-  Token get endToken {
-    if (semicolon != null) {
-      return semicolon;
-    }
-    return _expression.endToken;
-  }
-
-  /**
-   * Return the expression that comprises the statement.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression that comprises the statement to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  bool get isSynthetic => _expression.isSynthetic && semicolon.isSynthetic;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitExpressionStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * The "extends" clause in a class declaration.
- *
- * > extendsClause ::=
- * >     'extends' [TypeName]
- */
-class ExtendsClause extends AstNode {
-  /**
-   * The token representing the 'extends' keyword.
-   */
-  Token extendsKeyword;
-
-  /**
-   * The name of the class that is being extended.
-   */
-  TypeName _superclass;
-
-  /**
-   * Initialize a newly created extends clause.
-   */
-  ExtendsClause(this.extendsKeyword, TypeName superclass) {
-    _superclass = _becomeParentOf(superclass);
-  }
-
-  @override
-  Token get beginToken => extendsKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(extendsKeyword)..add(_superclass);
-
-  @override
-  Token get endToken => _superclass.endToken;
-
-  /**
-   * Return the name of the class that is being extended.
-   */
-  TypeName get superclass => _superclass;
-
-  /**
-   * Set the name of the class that is being extended to the given [name].
-   */
-  void set superclass(TypeName name) {
-    _superclass = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitExtendsClause(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_superclass, visitor);
-  }
-}
-
-/**
- * The declaration of one or more fields of the same type.
- *
- * > fieldDeclaration ::=
- * >     'static'? [VariableDeclarationList] ';'
- */
-class FieldDeclaration extends ClassMember {
-  /**
-   * The token representing the 'static' keyword, or `null` if the fields are
-   * not static.
-   */
-  Token staticKeyword;
-
-  /**
-   * The fields being declared.
-   */
-  VariableDeclarationList _fieldList;
-
-  /**
-   * The semicolon terminating the declaration.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created field declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the declaration does not have the
-   * corresponding attribute. The [staticKeyword] can be `null` if the field is
-   * not a static field.
-   */
-  FieldDeclaration(Comment comment, List<Annotation> metadata,
-      this.staticKeyword, VariableDeclarationList fieldList, this.semicolon)
-      : super(comment, metadata) {
-    _fieldList = _becomeParentOf(fieldList);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(staticKeyword)..add(_fieldList)..add(semicolon);
-
-  @override
-  Element get element => null;
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the fields being declared.
-   */
-  VariableDeclarationList get fields => _fieldList;
-
-  /**
-   * Set the fields being declared to the given list of [fields].
-   */
-  void set fields(VariableDeclarationList fields) {
-    _fieldList = _becomeParentOf(fields);
-  }
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (staticKeyword != null) {
-      return staticKeyword;
-    }
-    return _fieldList.beginToken;
-  }
-
-  /**
-   * Return `true` if the fields are declared to be static.
-   */
-  bool get isStatic => staticKeyword != null;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFieldDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_fieldList, visitor);
-  }
-}
-
-/**
- * A field formal parameter.
- *
- * > fieldFormalParameter ::=
- * >     ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
- * >     'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
- */
-class FieldFormalParameter extends NormalFormalParameter {
-  /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or
-   * `null` if no keyword was used.
-   */
-  Token keyword;
-
-  /**
-   * The name of the declared type of the parameter, or `null` if the parameter
-   * does not have a declared type.
-   */
-  TypeName _type;
-
-  /**
-   * The token representing the 'this' keyword.
-   */
-  Token thisKeyword;
-
-  /**
-   * The token representing the period.
-   */
-  Token period;
-
-  /**
-   * The type parameters associated with the method, or `null` if the method is
-   * not a generic method.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The parameters of the function-typed parameter, or `null` if this is not a
-   * function-typed field formal parameter.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * Initialize a newly created formal parameter. Either or both of the
-   * [comment] and [metadata] can be `null` if the parameter does not have the
-   * corresponding attribute. The [keyword] can be `null` if there is a type.
-   * The [type] must be `null` if the keyword is 'var'. The [thisKeyword] and
-   * [period] can be `null` if the keyword 'this' was not provided.  The
-   * [parameters] can be `null` if this is not a function-typed field formal
-   * parameter.
-   */
-  FieldFormalParameter(
-      Comment comment,
-      List<Annotation> metadata,
-      this.keyword,
-      TypeName type,
-      this.thisKeyword,
-      this.period,
-      SimpleIdentifier identifier,
-      TypeParameterList typeParameters,
-      FormalParameterList parameters)
-      : super(comment, metadata, identifier) {
-    _type = _becomeParentOf(type);
-    _typeParameters = _becomeParentOf(typeParameters);
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  @override
-  Token get beginToken {
-    if (keyword != null) {
-      return keyword;
-    } else if (_type != null) {
-      return _type.beginToken;
-    }
-    return thisKeyword;
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(keyword)
-    ..add(_type)
-    ..add(thisKeyword)
-    ..add(period)
-    ..add(identifier)
-    ..add(_parameters);
-
-  @override
-  Token get endToken {
-    if (_parameters != null) {
-      return _parameters.endToken;
-    }
-    return identifier.endToken;
-  }
-
-  @override
-  bool get isConst =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.CONST;
-
-  @override
-  bool get isFinal =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.FINAL;
-
-  /**
-   * Return the parameters of the function-typed parameter, or `null` if this is
-   * not a function-typed field formal parameter.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters of the function-typed parameter to the given
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  /**
-   * Return the name of the declared type of the parameter, or `null` if the
-   * parameter does not have a declared type. Note that if this is a
-   * function-typed field formal parameter this is the return type of the
-   * function.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the declared type of the parameter to the given [typeName].
-   */
-  void set type(TypeName typeName) {
-    _type = _becomeParentOf(typeName);
-  }
-
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFieldFormalParameter(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_type, visitor);
-    _safelyVisitChild(identifier, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_parameters, visitor);
-  }
-}
-
-/**
- * A for-each statement.
- *
- * > forEachStatement ::=
- * >     'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
- * >   | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
- */
-class ForEachStatement extends Statement {
-  /**
-   * The token representing the 'await' keyword, or `null` if there is no
-   * 'await' keyword.
-   */
-  Token awaitKeyword;
-
-  /**
-   * The token representing the 'for' keyword.
-   */
-  Token forKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The declaration of the loop variable, or `null` if the loop variable is a
-   * simple identifier.
-   */
-  DeclaredIdentifier _loopVariable;
-
-  /**
-   * The loop variable, or `null` if the loop variable is declared in the 'for'.
-   */
-  SimpleIdentifier _identifier;
-
-  /**
-   * The token representing the 'in' keyword.
-   */
-  Token inKeyword;
-
-  /**
-   * The expression evaluated to produce the iterator.
-   */
-  Expression _iterable;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The body of the loop.
-   */
-  Statement _body;
-
-  /**
-   * Initialize a newly created for-each statement whose loop control variable
-   * is declared internally (in the for-loop part). The [awaitKeyword] can be
-   * `null` if this is not an asynchronous for loop.
-   */
-  ForEachStatement.withDeclaration(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      DeclaredIdentifier loopVariable,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _loopVariable = _becomeParentOf(loopVariable);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
-   * Initialize a newly created for-each statement whose loop control variable
-   * is declared outside the for loop. The [awaitKeyword] can be `null` if this
-   * is not an asynchronous for loop.
-   */
-  ForEachStatement.withReference(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      SimpleIdentifier identifier,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _identifier = _becomeParentOf(identifier);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  Token get beginToken => forKeyword;
-
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body => _body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement) {
-    _body = _becomeParentOf(statement);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(awaitKeyword)
-    ..add(forKeyword)
-    ..add(leftParenthesis)
-    ..add(_loopVariable)
-    ..add(_identifier)
-    ..add(inKeyword)
-    ..add(_iterable)
-    ..add(rightParenthesis)
-    ..add(_body);
-
-  @override
-  Token get endToken => _body.endToken;
-
-  /**
-   * Return the loop variable, or `null` if the loop variable is declared in the
-   * 'for'.
-   */
-  SimpleIdentifier get identifier => _identifier;
-
-  /**
-   * Set the loop variable to the given [identifier].
-   */
-  void set identifier(SimpleIdentifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the expression evaluated to produce the iterator.
-   */
-  Expression get iterable => _iterable;
-
-  /**
-   * Set the expression evaluated to produce the iterator to the given
-   * [expression].
-   */
-  void set iterable(Expression expression) {
-    _iterable = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the declaration of the loop variable, or `null` if the loop variable
-   * is a simple identifier.
-   */
-  DeclaredIdentifier get loopVariable => _loopVariable;
-
-  /**
-   * Set the declaration of the loop variable to the given [variable].
-   */
-  void set loopVariable(DeclaredIdentifier variable) {
-    _loopVariable = _becomeParentOf(variable);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitForEachStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_loopVariable, visitor);
-    _safelyVisitChild(_identifier, visitor);
-    _safelyVisitChild(_iterable, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * A node representing a parameter to a function.
- *
- * > formalParameter ::=
- * >     [NormalFormalParameter]
- * >   | [DefaultFormalParameter]
- */
-abstract class FormalParameter extends AstNode {
-  /**
-   * Return the element representing this parameter, or `null` if this parameter
-   * has not been resolved.
-   */
-  ParameterElement get element {
-    SimpleIdentifier identifier = this.identifier;
-    if (identifier == null) {
-      return null;
-    }
-    return identifier.staticElement as ParameterElement;
-  }
-
-  /**
-   * Return the name of the parameter being declared.
-   */
-  SimpleIdentifier get identifier;
-
-  /**
-   * Return `true` if this parameter was declared with the 'const' modifier.
-   */
-  bool get isConst;
-
-  /**
-   * Return `true` if this parameter was declared with the 'final' modifier.
-   * Parameters that are declared with the 'const' modifier will return `false`
-   * even though they are implicitly final.
-   */
-  bool get isFinal;
-
-  /**
-   * Return the kind of this parameter.
-   */
-  ParameterKind get kind;
-
-  /**
-   * Return the annotations associated with this parameter.
-   */
-  NodeList<Annotation> get metadata;
-}
-
-/**
- * The formal parameter list of a method declaration, function declaration, or
- * function type alias.
- *
- * While the grammar requires all optional formal parameters to follow all of
- * the normal formal parameters and at most one grouping of optional formal
- * parameters, this class does not enforce those constraints. All parameters are
- * flattened into a single list, which can have any or all kinds of parameters
- * (normal, named, and positional) in any order.
- *
- * > formalParameterList ::=
- * >     '(' ')'
- * >   | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
- * >   | '(' optionalFormalParameters ')'
- * >
- * > normalFormalParameters ::=
- * >     [NormalFormalParameter] (',' [NormalFormalParameter])*
- * >
- * > optionalFormalParameters ::=
- * >     optionalPositionalFormalParameters
- * >   | namedFormalParameters
- * >
- * > optionalPositionalFormalParameters ::=
- * >     '[' [DefaultFormalParameter] (',' [DefaultFormalParameter])* ']'
- * >
- * > namedFormalParameters ::=
- * >     '{' [DefaultFormalParameter] (',' [DefaultFormalParameter])* '}'
- */
-class FormalParameterList extends AstNode {
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The parameters associated with the method.
-   */
-  NodeList<FormalParameter> _parameters;
-
-  /**
-   * The left square bracket ('[') or left curly brace ('{') introducing the
-   * optional parameters, or `null` if there are no optional parameters.
-   */
-  Token leftDelimiter;
-
-  /**
-   * The right square bracket (']') or right curly brace ('}') terminating the
-   * optional parameters, or `null` if there are no optional parameters.
-   */
-  Token rightDelimiter;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * Initialize a newly created parameter list. The list of [parameters] can be
-   * `null` if there are no parameters. The [leftDelimiter] and [rightDelimiter]
-   * can be `null` if there are no optional parameters.
-   */
-  FormalParameterList(this.leftParenthesis, List<FormalParameter> parameters,
-      this.leftDelimiter, this.rightDelimiter, this.rightParenthesis) {
-    _parameters = new NodeList<FormalParameter>(this, parameters);
-  }
-
-  @override
-  Token get beginToken => leftParenthesis;
-
-  @override
-  Iterable get childEntities {
-    // TODO(paulberry): include commas.
-    ChildEntities result = new ChildEntities()..add(leftParenthesis);
-    bool leftDelimiterNeeded = leftDelimiter != null;
-    for (FormalParameter parameter in _parameters) {
-      if (leftDelimiterNeeded && leftDelimiter.offset < parameter.offset) {
-        result.add(leftDelimiter);
-        leftDelimiterNeeded = false;
-      }
-      result.add(parameter);
-    }
-    return result..add(rightDelimiter)..add(rightParenthesis);
-  }
-
-  @override
-  Token get endToken => rightParenthesis;
-
-  /**
-   * Return a list containing the elements representing the parameters in this
-   * list. The list will contain `null`s if the parameters in this list have not
-   * been resolved.
-   */
-  List<ParameterElement> get parameterElements {
-    int count = _parameters.length;
-    List<ParameterElement> types = new List<ParameterElement>(count);
-    for (int i = 0; i < count; i++) {
-      types[i] = _parameters[i].element;
-    }
-    return types;
-  }
-
-  /**
-   * Return the parameters associated with the method.
-   */
-  NodeList<FormalParameter> get parameters => _parameters;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFormalParameterList(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _parameters.accept(visitor);
-  }
-}
-
-/**
- * A for statement.
- *
- * > forStatement ::=
- * >     'for' '(' forLoopParts ')' [Statement]
- * >
- * > forLoopParts ::=
- * >     forInitializerStatement ';' [Expression]? ';' [Expression]?
- * >
- * > forInitializerStatement ::=
- * >     [DefaultFormalParameter]
- * >   | [Expression]?
- */
-class ForStatement extends Statement {
-  /**
-   * The token representing the 'for' keyword.
-   */
-  Token forKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The declaration of the loop variables, or `null` if there are no variables.
-   * Note that a for statement cannot have both a variable list and an
-   * initialization expression, but can validly have neither.
-   */
-  VariableDeclarationList _variableList;
-
-  /**
-   * The initialization expression, or `null` if there is no initialization
-   * expression. Note that a for statement cannot have both a variable list and
-   * an initialization expression, but can validly have neither.
-   */
-  Expression _initialization;
-
-  /**
-   * The semicolon separating the initializer and the condition.
-   */
-  Token leftSeparator;
-
-  /**
-   * The condition used to determine when to terminate the loop, or `null` if
-   * there is no condition.
-   */
-  Expression _condition;
-
-  /**
-   * The semicolon separating the condition and the updater.
-   */
-  Token rightSeparator;
-
-  /**
-   * The list of expressions run after each execution of the loop body.
-   */
-  NodeList<Expression> _updaters;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The body of the loop.
-   */
-  Statement _body;
-
-  /**
-   * Initialize a newly created for statement. Either the [variableList] or the
-   * [initialization] must be `null`. Either the [condition] and the list of
-   * [updaters] can be `null` if the loop does not have the corresponding
-   * attribute.
-   */
-  ForStatement(
-      this.forKeyword,
-      this.leftParenthesis,
-      VariableDeclarationList variableList,
-      Expression initialization,
-      this.leftSeparator,
-      Expression condition,
-      this.rightSeparator,
-      List<Expression> updaters,
-      this.rightParenthesis,
-      Statement body) {
-    _variableList = _becomeParentOf(variableList);
-    _initialization = _becomeParentOf(initialization);
-    _condition = _becomeParentOf(condition);
-    _updaters = new NodeList<Expression>(this, updaters);
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  Token get beginToken => forKeyword;
-
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body => _body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement) {
-    _body = _becomeParentOf(statement);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(forKeyword)
-    ..add(leftParenthesis)
-    ..add(_variableList)
-    ..add(_initialization)
-    ..add(leftSeparator)
-    ..add(_condition)
-    ..add(rightSeparator)
-    ..addAll(_updaters)
-    ..add(rightParenthesis)
-    ..add(_body);
-
-  /**
-   * Return the condition used to determine when to terminate the loop, or
-   * `null` if there is no condition.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the condition used to determine when to terminate the loop to the given
-   * [expression].
-   */
-  void set condition(Expression expression) {
-    _condition = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get endToken => _body.endToken;
-
-  /**
-   * Return the initialization expression, or `null` if there is no
-   * initialization expression.
-   */
-  Expression get initialization => _initialization;
-
-  /**
-   * Set the initialization expression to the given [expression].
-   */
-  void set initialization(Expression initialization) {
-    _initialization = _becomeParentOf(initialization);
-  }
-
-  /**
-   * Return the list of expressions run after each execution of the loop body.
-   */
-  NodeList<Expression> get updaters => _updaters;
-
-  /**
-   * Return the declaration of the loop variables, or `null` if there are no
-   * variables.
-   */
-  VariableDeclarationList get variables => _variableList;
-
-  /**
-   * Set the declaration of the loop variables to the given [variableList].
-   */
-  void set variables(VariableDeclarationList variableList) {
-    _variableList = _becomeParentOf(variableList);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitForStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_variableList, visitor);
-    _safelyVisitChild(_initialization, visitor);
-    _safelyVisitChild(_condition, visitor);
-    _updaters.accept(visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * A node representing the body of a function or method.
- *
- * > functionBody ::=
- * >     [BlockFunctionBody]
- * >   | [EmptyFunctionBody]
- * >   | [ExpressionFunctionBody]
- */
-abstract class FunctionBody extends AstNode {
-  /**
-   * Return `true` if this function body is asynchronous.
-   */
-  bool get isAsynchronous => false;
-
-  /**
-   * Return `true` if this function body is a generator.
-   */
-  bool get isGenerator => false;
-
-  /**
-   * Return `true` if this function body is synchronous.
-   */
-  bool get isSynchronous => true;
-
-  /**
-   * Return the token representing the 'async' or 'sync' keyword, or `null` if
-   * there is no such keyword.
-   */
-  Token get keyword => null;
-
-  /**
-   * Return the star following the 'async' or 'sync' keyword, or `null` if there
-   * is no star.
-   */
-  Token get star => null;
-}
-
-/**
- * A top-level declaration.
- *
- * > functionDeclaration ::=
- * >     'external' functionSignature
- * >   | functionSignature [FunctionBody]
- * >
- * > functionSignature ::=
- * >     [Type]? ('get' | 'set')? [SimpleIdentifier] [FormalParameterList]
- */
-class FunctionDeclaration extends NamedCompilationUnitMember {
-  /**
-   * The token representing the 'external' keyword, or `null` if this is not an
-   * external function.
-   */
-  Token externalKeyword;
-
-  /**
-   * The return type of the function, or `null` if no return type was declared.
-   */
-  TypeName _returnType;
-
-  /**
-   * The token representing the 'get' or 'set' keyword, or `null` if this is a
-   * function declaration rather than a property declaration.
-   */
-  Token propertyKeyword;
-
-  /**
-   * The function expression being wrapped.
-   */
-  FunctionExpression _functionExpression;
-
-  /**
-   * Initialize a newly created function declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the function does not have the
-   * corresponding attribute. The [externalKeyword] can be `null` if the
-   * function is not an external function. The [returnType] can be `null` if no
-   * return type was specified. The [propertyKeyword] can be `null` if the
-   * function is neither a getter or a setter.
-   */
-  FunctionDeclaration(
-      Comment comment,
-      List<Annotation> metadata,
-      this.externalKeyword,
-      TypeName returnType,
-      this.propertyKeyword,
-      SimpleIdentifier name,
-      FunctionExpression functionExpression)
-      : super(comment, metadata, name) {
-    _returnType = _becomeParentOf(returnType);
-    _functionExpression = _becomeParentOf(functionExpression);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(externalKeyword)
-    ..add(_returnType)
-    ..add(propertyKeyword)
-    ..add(_name)
-    ..add(_functionExpression);
-
-  @override
-  ExecutableElement get element =>
-      _name != null ? (_name.staticElement as ExecutableElement) : null;
-
-  @override
-  Token get endToken => _functionExpression.endToken;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (externalKeyword != null) {
-      return externalKeyword;
-    } else if (_returnType != null) {
-      return _returnType.beginToken;
-    } else if (propertyKeyword != null) {
-      return propertyKeyword;
-    } else if (_name != null) {
-      return _name.beginToken;
-    }
-    return _functionExpression.beginToken;
-  }
-
-  /**
-   * Return the function expression being wrapped.
-   */
-  FunctionExpression get functionExpression => _functionExpression;
-
-  /**
-   * Set the function expression being wrapped to the given
-   * [functionExpression].
-   */
-  void set functionExpression(FunctionExpression functionExpression) {
-    _functionExpression = _becomeParentOf(functionExpression);
-  }
-
-  /**
-   * Return `true` if this function declares a getter.
-   */
-  bool get isGetter =>
-      propertyKeyword != null &&
-      (propertyKeyword as KeywordToken).keyword == Keyword.GET;
-
-  /**
-   * Return `true` if this function declares a setter.
-   */
-  bool get isSetter =>
-      propertyKeyword != null &&
-      (propertyKeyword as KeywordToken).keyword == Keyword.SET;
-
-  /**
-   * Return the return type of the function, or `null` if no return type was
-   * declared.
-   */
-  TypeName get returnType => _returnType;
-
-  /**
-   * Set the return type of the function to the given [returnType].
-   */
-  void set returnType(TypeName returnType) {
-    _returnType = _becomeParentOf(returnType);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_returnType, visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_functionExpression, visitor);
-  }
-}
-
-/**
- * A [FunctionDeclaration] used as a statement.
- */
-class FunctionDeclarationStatement extends Statement {
-  /**
-   * The function declaration being wrapped.
-   */
-  FunctionDeclaration _functionDeclaration;
-
-  /**
-   * Initialize a newly created function declaration statement.
-   */
-  FunctionDeclarationStatement(FunctionDeclaration functionDeclaration) {
-    _functionDeclaration = _becomeParentOf(functionDeclaration);
-  }
-
-  @override
-  Token get beginToken => _functionDeclaration.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(_functionDeclaration);
-
-  @override
-  Token get endToken => _functionDeclaration.endToken;
-
-  /**
-   * Return the function declaration being wrapped.
-   */
-  FunctionDeclaration get functionDeclaration => _functionDeclaration;
-
-  /**
-   * Set the function declaration being wrapped to the given
-   * [functionDeclaration].
-   */
-  void set functionDeclaration(FunctionDeclaration functionDeclaration) {
-    _functionDeclaration = _becomeParentOf(functionDeclaration);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionDeclarationStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_functionDeclaration, visitor);
-  }
-}
-
-/**
- * A function expression.
- *
- * > functionExpression ::=
- * >     [TypeParameterList]? [FormalParameterList] [FunctionBody]
- */
-class FunctionExpression extends Expression {
-  /**
-   * The type parameters associated with the method, or `null` if the method is
-   * not a generic method.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The parameters associated with the function.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * The body of the function, or `null` if this is an external function.
-   */
-  FunctionBody _body;
-
-  /**
-   * The element associated with the function, or `null` if the AST structure
-   * has not been resolved.
-   */
-  ExecutableElement element;
-
-  /**
-   * Initialize a newly created function declaration.
-   */
-  FunctionExpression(TypeParameterList typeParameters,
-      FormalParameterList parameters, FunctionBody body) {
-    _typeParameters = _becomeParentOf(typeParameters);
-    _parameters = _becomeParentOf(parameters);
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  Token get beginToken {
-    if (_typeParameters != null) {
-      return _typeParameters.beginToken;
-    } else if (_parameters != null) {
-      return _parameters.beginToken;
-    } else if (_body != null) {
-      return _body.beginToken;
-    }
-    // This should never be reached because external functions must be named,
-    // hence either the body or the name should be non-null.
-    throw new IllegalStateException("Non-external functions must have a body");
-  }
-
-  /**
-   * Return the body of the function, or `null` if this is an external function.
-   */
-  FunctionBody get body => _body;
-
-  /**
-   * Set the body of the function to the given [functionBody].
-   */
-  void set body(FunctionBody functionBody) {
-    _body = _becomeParentOf(functionBody);
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_parameters)..add(_body);
-
-  @override
-  Token get endToken {
-    if (_body != null) {
-      return _body.endToken;
-    } else if (_parameters != null) {
-      return _parameters.endToken;
-    }
-    // This should never be reached because external functions must be named,
-    // hence either the body or the name should be non-null.
-    throw new IllegalStateException("Non-external functions must have a body");
-  }
-
-  /**
-   * Return the parameters associated with the function.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters associated with the function to the given list of
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  @override
-  int get precedence => 16;
-
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_parameters, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * The invocation of a function resulting from evaluating an expression.
- * Invocations of methods and other forms of functions are represented by
- * [MethodInvocation] nodes. Invocations of getters and setters are represented
- * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
- *
- * > functionExpressionInvocation ::=
- * >     [Expression] [TypeArgumentList]? [ArgumentList]
- */
-class FunctionExpressionInvocation extends Expression {
-  /**
-   * The expression producing the function being invoked.
-   */
-  Expression _function;
-
-  /**
-   * The type arguments to be applied to the method being invoked, or `null` if
-   * no type arguments were provided.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * The list of arguments to the function.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The element associated with the function being invoked based on static type
-   * information, or `null` if the AST structure has not been resolved or the
-   * function could not be resolved.
-   */
-  ExecutableElement staticElement;
-
-  /**
-   * The function type of the method invocation, or `null` if the AST
-   * structure has not been resolved, or if the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be an
-   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
-   * interface type that implements `Function`.
-   */
-  DartType staticInvokeType;
-
-  /**
-   * The element associated with the function being invoked based on propagated
-   * type information, or `null` if the AST structure has not been resolved or
-   * the function could not be resolved.
-   */
-  ExecutableElement propagatedElement;
-
-  /**
-   * Like [staticInvokeType], but reflects propagated type information.
-   */
-  DartType propagatedInvokeType;
-
-  /**
-   * Initialize a newly created function expression invocation.
-   */
-  FunctionExpressionInvocation(Expression function,
-      TypeArgumentList typeArguments, ArgumentList argumentList) {
-    _function = _becomeParentOf(function);
-    _typeArguments = _becomeParentOf(typeArguments);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  /**
-   * Return the list of arguments to the method.
-   */
-  ArgumentList get argumentList => _argumentList;
-
-  /**
-   * Set the list of arguments to the method to the given [argumentList].
-   */
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  Token get beginToken => _function.beginToken;
-
-  /**
-   * Return the best element available for the function being invoked. If
-   * resolution was able to find a better element based on type propagation,
-   * that element will be returned. Otherwise, the element found using the
-   * result of static analysis will be returned. If resolution has not been
-   * performed, then `null` will be returned.
-   */
-  ExecutableElement get bestElement {
-    ExecutableElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_function)..add(_argumentList);
-
-  @override
-  Token get endToken => _argumentList.endToken;
-
-  /**
-   * Return the expression producing the function being invoked.
-   */
-  Expression get function => _function;
-
-  /**
-   * Set the expression producing the function being invoked to the given
-   * [expression].
-   */
-  void set function(Expression expression) {
-    _function = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * Return the type arguments to be applied to the method being invoked, or
-   * `null` if no type arguments were provided.
-   */
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  /**
-   * Set the type arguments to be applied to the method being invoked to the
-   * given [typeArguments].
-   */
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_function, visitor);
-    _safelyVisitChild(_typeArguments, visitor);
-    _safelyVisitChild(_argumentList, visitor);
-  }
-}
-
-/**
- * A function type alias.
- *
- * > functionTypeAlias ::=
- * >     functionPrefix [TypeParameterList]? [FormalParameterList] ';'
- * >
- * > functionPrefix ::=
- * >     [TypeName]? [SimpleIdentifier]
- */
-class FunctionTypeAlias extends TypeAlias {
-  /**
-   * The name of the return type of the function type being defined, or `null`
-   * if no return type was given.
-   */
-  TypeName _returnType;
-
-  /**
-   * The type parameters for the function type, or `null` if the function type
-   * does not have any type parameters.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The parameters associated with the function type.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * Initialize a newly created function type alias. Either or both of the
-   * [comment] and [metadata] can be `null` if the function does not have the
-   * corresponding attribute. The [returnType] can be `null` if no return type
-   * was specified. The [typeParameters] can be `null` if the function has no
-   * type parameters.
-   */
-  FunctionTypeAlias(
-      Comment comment,
-      List<Annotation> metadata,
-      Token keyword,
-      TypeName returnType,
-      SimpleIdentifier name,
-      TypeParameterList typeParameters,
-      FormalParameterList parameters,
-      Token semicolon)
-      : super(comment, metadata, keyword, name, semicolon) {
-    _returnType = _becomeParentOf(returnType);
-    _typeParameters = _becomeParentOf(typeParameters);
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(typedefKeyword)
-    ..add(_returnType)
-    ..add(_name)
-    ..add(_typeParameters)
-    ..add(_parameters)
-    ..add(semicolon);
-
-  @override
-  FunctionTypeAliasElement get element =>
-      _name != null ? (_name.staticElement as FunctionTypeAliasElement) : null;
-
-  /**
-   * Return the parameters associated with the function type.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters associated with the function type to the given list of
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  /**
-   * Return the name of the return type of the function type being defined, or
-   * `null` if no return type was given.
-   */
-  TypeName get returnType => _returnType;
-
-  /**
-   * Set the name of the return type of the function type being defined to the
-   * given [typeName].
-   */
-  void set returnType(TypeName typeName) {
-    _returnType = _becomeParentOf(typeName);
-  }
-
-  /**
-   * Return the type parameters for the function type, or `null` if the function
-   * type does not have any type parameters.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters for the function type to the given list of
-   * [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionTypeAlias(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_returnType, visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_parameters, visitor);
-  }
-}
-
-/**
- * A function-typed formal parameter.
- *
- * > functionSignature ::=
- * >     [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
- */
-class FunctionTypedFormalParameter extends NormalFormalParameter {
-  /**
-   * The return type of the function, or `null` if the function does not have a
-   * return type.
-   */
-  TypeName _returnType;
-
-  /**
-   * The type parameters associated with the function, or `null` if the function
-   * is not a generic function.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The parameters of the function-typed parameter.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * Initialize a newly created formal parameter. Either or both of the
-   * [comment] and [metadata] can be `null` if the parameter does not have the
-   * corresponding attribute. The [returnType] can be `null` if no return type
-   * was specified.
-   */
-  FunctionTypedFormalParameter(
-      Comment comment,
-      List<Annotation> metadata,
-      TypeName returnType,
-      SimpleIdentifier identifier,
-      TypeParameterList typeParameters,
-      FormalParameterList parameters)
-      : super(comment, metadata, identifier) {
-    _returnType = _becomeParentOf(returnType);
-    _typeParameters = _becomeParentOf(typeParameters);
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  @override
-  Token get beginToken {
-    if (_returnType != null) {
-      return _returnType.beginToken;
-    }
-    return identifier.beginToken;
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(_returnType)..add(identifier)..add(parameters);
-
-  @override
-  Token get endToken => _parameters.endToken;
-
-  @override
-  bool get isConst => false;
-
-  @override
-  bool get isFinal => false;
-
-  /**
-   * Return the parameters of the function-typed parameter.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters of the function-typed parameter to the given
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  /**
-   * Return the return type of the function, or `null` if the function does not
-   * have a return type.
-   */
-  TypeName get returnType => _returnType;
-
-  /**
-   * Set the return type of the function to the given [type].
-   */
-  void set returnType(TypeName type) {
-    _returnType = _becomeParentOf(type);
-  }
-
-  /**
-   * Return the type parameters associated with this function, or `null` if
-   * this function is not a generic function.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_returnType, visitor);
-    _safelyVisitChild(identifier, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_parameters, visitor);
-  }
-}
-
-/**
- * A combinator that restricts the names being imported to those that are not in
- * a given list.
- *
- * > hideCombinator ::=
- * >     'hide' [SimpleIdentifier] (',' [SimpleIdentifier])*
- */
-class HideCombinator extends Combinator {
-  /**
-   * The list of names from the library that are hidden by this combinator.
-   */
-  NodeList<SimpleIdentifier> _hiddenNames;
-
-  /**
-   * Initialize a newly created import show combinator.
-   */
-  HideCombinator(Token keyword, List<SimpleIdentifier> hiddenNames)
-      : super(keyword) {
-    _hiddenNames = new NodeList<SimpleIdentifier>(this, hiddenNames);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(keyword)
-    ..addAll(_hiddenNames);
-
-  @override
-  Token get endToken => _hiddenNames.endToken;
-
-  /**
-   * Return the list of names from the library that are hidden by this
-   * combinator.
-   */
-  NodeList<SimpleIdentifier> get hiddenNames => _hiddenNames;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitHideCombinator(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _hiddenNames.accept(visitor);
-  }
-}
-
-/**
- * A node that represents an identifier.
- *
- * > identifier ::=
- * >     [SimpleIdentifier]
- * >   | [PrefixedIdentifier]
- */
-abstract class Identifier extends Expression {
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  Element get bestElement;
-
-  @override
-  bool get isAssignable => true;
-
-  /**
-   * Return the lexical representation of the identifier.
-   */
-  String get name;
-
-  /**
-   * Return the element associated with this identifier based on propagated type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved. One example of the latter case is an
-   * identifier that is not defined within the scope in which it appears.
-   */
-  Element get propagatedElement;
-
-  /**
-   * Return the element associated with this identifier based on static type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved. One example of the latter case is an
-   * identifier that is not defined within the scope in which it appears
-   */
-  Element get staticElement;
-
-  /**
-   * Return `true` if the given [name] is visible only within the library in
-   * which it is declared.
-   */
-  static bool isPrivateName(String name) =>
-      StringUtilities.startsWithChar(name, 0x5F);
-}
-
-/**
- * An if statement.
- *
- * > ifStatement ::=
- * >     'if' '(' [Expression] ')' [Statement] ('else' [Statement])?
- */
-class IfStatement extends Statement {
-  /**
-   * The token representing the 'if' keyword.
-   */
-  Token ifKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The condition used to determine which of the statements is executed next.
-   */
-  Expression _condition;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The statement that is executed if the condition evaluates to `true`.
-   */
-  Statement _thenStatement;
-
-  /**
-   * The token representing the 'else' keyword, or `null` if there is no else
-   * statement.
-   */
-  Token elseKeyword;
-
-  /**
-   * The statement that is executed if the condition evaluates to `false`, or
-   * `null` if there is no else statement.
-   */
-  Statement _elseStatement;
-
-  /**
-   * Initialize a newly created if statement. The [elseKeyword] and
-   * [elseStatement] can be `null` if there is no else clause.
-   */
-  IfStatement(
-      this.ifKeyword,
-      this.leftParenthesis,
-      Expression condition,
-      this.rightParenthesis,
-      Statement thenStatement,
-      this.elseKeyword,
-      Statement elseStatement) {
-    _condition = _becomeParentOf(condition);
-    _thenStatement = _becomeParentOf(thenStatement);
-    _elseStatement = _becomeParentOf(elseStatement);
-  }
-
-  @override
-  Token get beginToken => ifKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(ifKeyword)
-    ..add(leftParenthesis)
-    ..add(_condition)
-    ..add(rightParenthesis)
-    ..add(_thenStatement)
-    ..add(elseKeyword)
-    ..add(_elseStatement);
-
-  /**
-   * Return the condition used to determine which of the statements is executed
-   * next.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the condition used to determine which of the statements is executed
-   * next to the given [expression].
-   */
-  void set condition(Expression expression) {
-    _condition = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the statement that is executed if the condition evaluates to
-   * `false`, or `null` if there is no else statement.
-   */
-  Statement get elseStatement => _elseStatement;
-
-  /**
-   * Set the statement that is executed if the condition evaluates to `false`
-   * to the given [statement].
-   */
-  void set elseStatement(Statement statement) {
-    _elseStatement = _becomeParentOf(statement);
-  }
-
-  @override
-  Token get endToken {
-    if (_elseStatement != null) {
-      return _elseStatement.endToken;
-    }
-    return _thenStatement.endToken;
-  }
-
-  /**
-   * Return the statement that is executed if the condition evaluates to `true`.
-   */
-  Statement get thenStatement => _thenStatement;
-
-  /**
-   * Set the statement that is executed if the condition evaluates to `true` to
-   * the given [statement].
-   */
-  void set thenStatement(Statement statement) {
-    _thenStatement = _becomeParentOf(statement);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitIfStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_condition, visitor);
-    _safelyVisitChild(_thenStatement, visitor);
-    _safelyVisitChild(_elseStatement, visitor);
-  }
-}
-
-/**
- * The "implements" clause in an class declaration.
- *
- * > implementsClause ::=
- * >     'implements' [TypeName] (',' [TypeName])*
- */
-class ImplementsClause extends AstNode {
-  /**
-   * The token representing the 'implements' keyword.
-   */
-  Token implementsKeyword;
-
-  /**
-   * The interfaces that are being implemented.
-   */
-  NodeList<TypeName> _interfaces;
-
-  /**
-   * Initialize a newly created implements clause.
-   */
-  ImplementsClause(this.implementsKeyword, List<TypeName> interfaces) {
-    _interfaces = new NodeList<TypeName>(this, interfaces);
-  }
-
-  @override
-  Token get beginToken => implementsKeyword;
-
-  @override
-  // TODO(paulberry): add commas.
-  Iterable get childEntities => new ChildEntities()
-    ..add(implementsKeyword)
-    ..addAll(interfaces);
-
-  @override
-  Token get endToken => _interfaces.endToken;
-
-  /**
-   * Return the list of the interfaces that are being implemented.
-   */
-  NodeList<TypeName> get interfaces => _interfaces;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _interfaces.accept(visitor);
-  }
-}
-
-/**
- * An import directive.
- *
- * > importDirective ::=
- * >     [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
- * >   | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
- */
-class ImportDirective extends NamespaceDirective {
-  static Comparator<ImportDirective> COMPARATOR =
-      (ImportDirective import1, ImportDirective import2) {
-    //
-    // uri
-    //
-    StringLiteral uri1 = import1.uri;
-    StringLiteral uri2 = import2.uri;
-    String uriStr1 = uri1.stringValue;
-    String uriStr2 = uri2.stringValue;
-    if (uriStr1 != null || uriStr2 != null) {
-      if (uriStr1 == null) {
-        return -1;
-      } else if (uriStr2 == null) {
-        return 1;
-      } else {
-        int compare = uriStr1.compareTo(uriStr2);
-        if (compare != 0) {
-          return compare;
-        }
-      }
-    }
-    //
-    // as
-    //
-    SimpleIdentifier prefix1 = import1.prefix;
-    SimpleIdentifier prefix2 = import2.prefix;
-    String prefixStr1 = prefix1 != null ? prefix1.name : null;
-    String prefixStr2 = prefix2 != null ? prefix2.name : null;
-    if (prefixStr1 != null || prefixStr2 != null) {
-      if (prefixStr1 == null) {
-        return -1;
-      } else if (prefixStr2 == null) {
-        return 1;
-      } else {
-        int compare = prefixStr1.compareTo(prefixStr2);
-        if (compare != 0) {
-          return compare;
-        }
-      }
-    }
-    //
-    // hides and shows
-    //
-    NodeList<Combinator> combinators1 = import1.combinators;
-    List<String> allHides1 = new List<String>();
-    List<String> allShows1 = new List<String>();
-    for (Combinator combinator in combinators1) {
-      if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        for (SimpleIdentifier simpleIdentifier in hides) {
-          allHides1.add(simpleIdentifier.name);
-        }
-      } else {
-        NodeList<SimpleIdentifier> shows =
-            (combinator as ShowCombinator).shownNames;
-        for (SimpleIdentifier simpleIdentifier in shows) {
-          allShows1.add(simpleIdentifier.name);
-        }
-      }
-    }
-    NodeList<Combinator> combinators2 = import2.combinators;
-    List<String> allHides2 = new List<String>();
-    List<String> allShows2 = new List<String>();
-    for (Combinator combinator in combinators2) {
-      if (combinator is HideCombinator) {
-        NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        for (SimpleIdentifier simpleIdentifier in hides) {
-          allHides2.add(simpleIdentifier.name);
-        }
-      } else {
-        NodeList<SimpleIdentifier> shows =
-            (combinator as ShowCombinator).shownNames;
-        for (SimpleIdentifier simpleIdentifier in shows) {
-          allShows2.add(simpleIdentifier.name);
-        }
-      }
-    }
-    // test lengths of combinator lists first
-    if (allHides1.length != allHides2.length) {
-      return allHides1.length - allHides2.length;
-    }
-    if (allShows1.length != allShows2.length) {
-      return allShows1.length - allShows2.length;
-    }
-    // next ensure that the lists are equivalent
-    if (!javaCollectionContainsAll(allHides1, allHides2)) {
-      return -1;
-    }
-    if (!javaCollectionContainsAll(allShows1, allShows2)) {
-      return -1;
-    }
-    return 0;
-  };
-
-  /**
-   * The token representing the 'deferred' keyword, or `null` if the imported is
-   * not deferred.
-   */
-  Token deferredKeyword;
-
-  /**
-   * The token representing the 'as' keyword, or `null` if the imported names are
-   * not prefixed.
-   */
-  Token asKeyword;
-
-  /**
-   * The prefix to be used with the imported names, or `null` if the imported
-   * names are not prefixed.
-   */
-  SimpleIdentifier _prefix;
-
-  /**
-   * Initialize a newly created import directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the function does not have the
-   * corresponding attribute. The [deferredKeyword] can be `null` if the import
-   * is not deferred. The [asKeyword] and [prefix] can be `null` if the import
-   * does not specify a prefix. The list of [combinators] can be `null` if there
-   * are no combinators.
-   */
-  ImportDirective(
-      Comment comment,
-      List<Annotation> metadata,
-      Token keyword,
-      StringLiteral libraryUri,
-      List<Configuration> configurations,
-      this.deferredKeyword,
-      this.asKeyword,
-      SimpleIdentifier prefix,
-      List<Combinator> combinators,
-      Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, configurations,
-            combinators, semicolon) {
-    _prefix = _becomeParentOf(prefix);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(_uri)
-    ..add(deferredKeyword)
-    ..add(asKeyword)
-    ..add(_prefix)
-    ..addAll(combinators)
-    ..add(semicolon);
-
-  @override
-  ImportElement get element => super.element as ImportElement;
-
-  /**
-   * Return the prefix to be used with the imported names, or `null` if the
-   * imported names are not prefixed.
-   */
-  SimpleIdentifier get prefix => _prefix;
-
-  /**
-   * Set the prefix to be used with the imported names to the given [identifier].
-   */
-  void set prefix(SimpleIdentifier identifier) {
-    _prefix = _becomeParentOf(identifier);
-  }
-
-  @override
-  LibraryElement get uriElement {
-    ImportElement element = this.element;
-    if (element == null) {
-      return null;
-    }
-    return element.importedLibrary;
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitImportDirective(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_prefix, visitor);
-    combinators.accept(visitor);
-  }
-}
-
-/**
- * An index expression.
- *
- * > indexExpression ::=
- * >     [Expression] '[' [Expression] ']'
- */
-class IndexExpression extends Expression {
-  /**
-   * The expression used to compute the object being indexed, or `null` if this
-   * index expression is part of a cascade expression.
-   */
-  Expression _target;
-
-  /**
-   * The period ("..") before a cascaded index expression, or `null` if this
-   * index expression is not part of a cascade expression.
-   */
-  Token period;
-
-  /**
-   * The left square bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The expression used to compute the index.
-   */
-  Expression _index;
-
-  /**
-   * The right square bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * The element associated with the operator based on the static type of the
-   * target, or `null` if the AST structure has not been resolved or if the
-   * operator could not be resolved.
-   */
-  MethodElement staticElement;
-
-  /**
-   * The element associated with the operator based on the propagated type of
-   * the target, or `null` if the AST structure has not been resolved or if the
-   * operator could not be resolved.
-   */
-  MethodElement propagatedElement;
-
-  /**
-   * If this expression is both in a getter and setter context, the
-   * [AuxiliaryElements] will be set to hold onto the static and propagated
-   * information. The auxiliary element will hold onto the elements from the
-   * getter context.
-   */
-  AuxiliaryElements auxiliaryElements = null;
-
-  /**
-   * Initialize a newly created index expression.
-   */
-  IndexExpression.forCascade(
-      this.period, this.leftBracket, Expression index, this.rightBracket) {
-    _index = _becomeParentOf(index);
-  }
-
-  /**
-   * Initialize a newly created index expression.
-   */
-  IndexExpression.forTarget(Expression target, this.leftBracket,
-      Expression index, this.rightBracket) {
-    _target = _becomeParentOf(target);
-    _index = _becomeParentOf(index);
-  }
-
-  @override
-  Token get beginToken {
-    if (_target != null) {
-      return _target.beginToken;
-    }
-    return period;
-  }
-
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  MethodElement get bestElement {
-    MethodElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_target)
-    ..add(period)
-    ..add(leftBracket)
-    ..add(_index)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the expression used to compute the index.
-   */
-  Expression get index => _index;
-
-  /**
-   * Set the expression used to compute the index to the given [expression].
-   */
-  void set index(Expression expression) {
-    _index = _becomeParentOf(expression);
-  }
-
-  @override
-  bool get isAssignable => true;
-
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
-  bool get isCascaded => period != null;
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * Return the expression used to compute the object being indexed. If this
-   * index expression is not part of a cascade expression, then this is the same
-   * as [target]. If this index expression is part of a cascade expression, then
-   * the target expression stored with the cascade expression is returned.
-   */
-  Expression get realTarget {
-    if (isCascaded) {
-      AstNode ancestor = parent;
-      while (ancestor is! CascadeExpression) {
-        if (ancestor == null) {
-          return _target;
-        }
-        ancestor = ancestor.parent;
-      }
-      return (ancestor as CascadeExpression).target;
-    }
-    return _target;
-  }
-
-  /**
-   * Return the expression used to compute the object being indexed, or `null`
-   * if this index expression is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
-  Expression get target => _target;
-
-  /**
-   * Set the expression used to compute the object being indexed to the given
-   * [expression].
-   */
-  void set target(Expression expression) {
-    _target = _becomeParentOf(expression);
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the index
-   * expression will be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _propagatedParameterElementForIndex {
-    if (propagatedElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = propagatedElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the index expression will
-   * be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _staticParameterElementForIndex {
-    if (staticElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = staticElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitIndexExpression(this);
-
-  /**
-   * Return `true` if this expression is computing a right-hand value (that is,
-   * if this expression is in a context where the operator '[]' will be
-   * invoked).
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
-  bool inGetterContext() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    AstNode parent = this.parent;
-    if (parent is AssignmentExpression) {
-      AssignmentExpression assignment = parent;
-      if (identical(assignment.leftHandSide, this) &&
-          assignment.operator.type == TokenType.EQ) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return `true` if this expression is computing a left-hand value (that is,
-   * if this expression is in a context where the operator '[]=' will be
-   * invoked).
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
-  bool inSetterContext() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    AstNode parent = this.parent;
-    if (parent is PrefixExpression) {
-      return parent.operator.type.isIncrementOperator;
-    } else if (parent is PostfixExpression) {
-      return true;
-    } else if (parent is AssignmentExpression) {
-      return identical(parent.leftHandSide, this);
-    }
-    return false;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_target, visitor);
-    _safelyVisitChild(_index, visitor);
-  }
-}
-
-/**
- * An instance creation expression.
- *
- * > newExpression ::=
- * >     ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
- */
-class InstanceCreationExpression extends Expression {
-  /**
-   * The 'new' or 'const' keyword used to indicate how an object should be
-   * created.
-   */
-  Token keyword;
-
-  /**
-   * The name of the constructor to be invoked.
-   */
-  ConstructorName _constructorName;
-
-  /**
-   * The list of arguments to the constructor.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The element associated with the constructor based on static type
-   * information, or `null` if the AST structure has not been resolved or if the
-   * constructor could not be resolved.
-   */
-  ConstructorElement staticElement;
-
-  /**
-   * Initialize a newly created instance creation expression.
-   */
-  InstanceCreationExpression(this.keyword, ConstructorName constructorName,
-      ArgumentList argumentList) {
-    _constructorName = _becomeParentOf(constructorName);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  /**
-   * Return the list of arguments to the constructor.
-   */
-  ArgumentList get argumentList => _argumentList;
-
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  Token get beginToken => keyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(keyword)
-    ..add(_constructorName)
-    ..add(_argumentList);
-
-  /**
-   * Return the name of the constructor to be invoked.
-   */
-  ConstructorName get constructorName => _constructorName;
-
-  /**
-   * Set the name of the constructor to be invoked to the given [name].
-   */
-  void set constructorName(ConstructorName name) {
-    _constructorName = _becomeParentOf(name);
-  }
-
-  @override
-  Token get endToken => _argumentList.endToken;
-
-  /**
-   * Return `true` if this creation expression is used to invoke a constant
-   * constructor.
-   */
-  bool get isConst =>
-      keyword is KeywordToken &&
-      (keyword as KeywordToken).keyword == Keyword.CONST;
-
-  @override
-  int get precedence => 16;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitInstanceCreationExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_constructorName, visitor);
-    _safelyVisitChild(_argumentList, visitor);
-  }
-}
-
-/**
- * An integer literal expression.
- *
- * > integerLiteral ::=
- * >     decimalIntegerLiteral
- * >   | hexadecimalIntegerLiteral
- * >
- * > decimalIntegerLiteral ::=
- * >     decimalDigit+
- * >
- * > hexadecimalIntegerLiteral ::=
- * >     '0x' hexadecimalDigit+
- * >   | '0X' hexadecimalDigit+
- */
-class IntegerLiteral extends Literal {
-  /**
-   * The token representing the literal.
-   */
-  Token literal;
-
-  /**
-   * The value of the literal.
-   */
-  int value = 0;
-
-  /**
-   * Initialize a newly created integer literal.
-   */
-  IntegerLiteral(this.literal, this.value);
-
-  @override
-  Token get beginToken => literal;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(literal);
-
-  @override
-  Token get endToken => literal;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitIntegerLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A node within a [StringInterpolation].
- *
- * > interpolationElement ::=
- * >     [InterpolationExpression]
- * >   | [InterpolationString]
- */
-abstract class InterpolationElement extends AstNode {}
-
-/**
- * An expression embedded in a string interpolation.
- *
- * > interpolationExpression ::=
- * >     '$' [SimpleIdentifier]
- * >   | '$' '{' [Expression] '}'
- */
-class InterpolationExpression extends InterpolationElement {
-  /**
-   * The token used to introduce the interpolation expression; either '$' if the
-   * expression is a simple identifier or '${' if the expression is a full
-   * expression.
-   */
-  Token leftBracket;
-
-  /**
-   * The expression to be evaluated for the value to be converted into a string.
-   */
-  Expression _expression;
-
-  /**
-   * The right curly bracket, or `null` if the expression is an identifier
-   * without brackets.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created interpolation expression.
-   */
-  InterpolationExpression(
-      this.leftBracket, Expression expression, this.rightBracket) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => leftBracket;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftBracket)
-    ..add(_expression)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken {
-    if (rightBracket != null) {
-      return rightBracket;
-    }
-    return _expression.endToken;
-  }
-
-  /**
-   * Return the expression to be evaluated for the value to be converted into a
-   * string.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression to be evaluated for the value to be converted into a
-   * string to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitInterpolationExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A non-empty substring of an interpolated string.
- *
- * > interpolationString ::=
- * >     characters
- */
-class InterpolationString extends InterpolationElement {
-  /**
-   * The characters that will be added to the string.
-   */
-  Token contents;
-
-  /**
-   * The value of the literal.
-   */
-  String value;
-
-  /**
-   * Initialize a newly created string of characters that are part of a string
-   * interpolation.
-   */
-  InterpolationString(this.contents, this.value);
-
-  @override
-  Token get beginToken => contents;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(contents);
-
-  /**
-   * Return the offset of the after-last contents character.
-   */
-  int get contentsEnd {
-    String lexeme = contents.lexeme;
-    return offset + new StringLexemeHelper(lexeme, true, true).end;
-  }
-
-  /**
-   * Return the offset of the first contents character.
-   */
-  int get contentsOffset {
-    int offset = contents.offset;
-    String lexeme = contents.lexeme;
-    return offset + new StringLexemeHelper(lexeme, true, true).start;
-  }
-
-  @override
-  Token get endToken => contents;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitInterpolationString(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {}
-}
-
-/**
- * An is expression.
- *
- * > isExpression ::=
- * >     [Expression] 'is' '!'? [TypeName]
- */
-class IsExpression extends Expression {
-  /**
-   * The expression used to compute the value whose type is being tested.
-   */
-  Expression _expression;
-
-  /**
-   * The is operator.
-   */
-  Token isOperator;
-
-  /**
-   * The not operator, or `null` if the sense of the test is not negated.
-   */
-  Token notOperator;
-
-  /**
-   * The name of the type being tested for.
-   */
-  TypeName _type;
-
-  /**
-   * Initialize a newly created is expression. The [notOperator] can be `null`
-   * if the sense of the test is not negated.
-   */
-  IsExpression(
-      Expression expression, this.isOperator, this.notOperator, TypeName type) {
-    _expression = _becomeParentOf(expression);
-    _type = _becomeParentOf(type);
-  }
-
-  @override
-  Token get beginToken => _expression.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_expression)
-    ..add(isOperator)
-    ..add(notOperator)
-    ..add(_type);
-
-  @override
-  Token get endToken => _type.endToken;
-
-  /**
-   * Return the expression used to compute the value whose type is being tested.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression used to compute the value whose type is being tested to
-   * the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 7;
-
-  /**
-   * Return the name of the type being tested for.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the type being tested for to the given [name].
-   */
-  void set type(TypeName name) {
-    _type = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitIsExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-    _safelyVisitChild(_type, visitor);
-  }
-}
-
-/**
- * A label on either a [LabeledStatement] or a [NamedExpression].
- *
- * > label ::=
- * >     [SimpleIdentifier] ':'
- */
-class Label extends AstNode {
-  /**
-   * The label being associated with the statement.
-   */
-  SimpleIdentifier _label;
-
-  /**
-   * The colon that separates the label from the statement.
-   */
-  Token colon;
-
-  /**
-   * Initialize a newly created label.
-   */
-  Label(SimpleIdentifier label, this.colon) {
-    _label = _becomeParentOf(label);
-  }
-
-  @override
-  Token get beginToken => _label.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(_label)..add(colon);
-
-  @override
-  Token get endToken => colon;
-
-  /**
-   * Return the label being associated with the statement.
-   */
-  SimpleIdentifier get label => _label;
-
-  /**
-   * Set the label being associated with the statement to the given [label].
-   */
-  void set label(SimpleIdentifier label) {
-    _label = _becomeParentOf(label);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitLabel(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_label, visitor);
-  }
-}
-
-/**
- * A statement that has a label associated with them.
- *
- * > labeledStatement ::=
- * >    [Label]+ [Statement]
- */
-class LabeledStatement extends Statement {
-  /**
-   * The labels being associated with the statement.
-   */
-  NodeList<Label> _labels;
-
-  /**
-   * The statement with which the labels are being associated.
-   */
-  Statement _statement;
-
-  /**
-   * Initialize a newly created labeled statement.
-   */
-  LabeledStatement(List<Label> labels, Statement statement) {
-    _labels = new NodeList<Label>(this, labels);
-    _statement = _becomeParentOf(statement);
-  }
-
-  @override
-  Token get beginToken {
-    if (!_labels.isEmpty) {
-      return _labels.beginToken;
-    }
-    return _statement.beginToken;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..addAll(_labels)
-    ..add(_statement);
-
-  @override
-  Token get endToken => _statement.endToken;
-
-  /**
-   * Return the labels being associated with the statement.
-   */
-  NodeList<Label> get labels => _labels;
-
-  /**
-   * Return the statement with which the labels are being associated.
-   */
-  Statement get statement => _statement;
-
-  /**
-   * Set the statement with which the labels are being associated to the given
-   * [statement].
-   */
-  void set statement(Statement statement) {
-    _statement = _becomeParentOf(statement);
-  }
-
-  @override
-  Statement get unlabeled => _statement.unlabeled;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitLabeledStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _labels.accept(visitor);
-    _safelyVisitChild(_statement, visitor);
-  }
-}
-
-/**
- * A library directive.
- *
- * > libraryDirective ::=
- * >     [Annotation] 'library' [Identifier] ';'
- */
-class LibraryDirective extends Directive {
-  /**
-   * The token representing the 'library' keyword.
-   */
-  Token libraryKeyword;
-
-  /**
-   * The name of the library being defined.
-   */
-  LibraryIdentifier _name;
-
-  /**
-   * The semicolon terminating the directive.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created library directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute.
-   */
-  LibraryDirective(Comment comment, List<Annotation> metadata,
-      this.libraryKeyword, LibraryIdentifier name, this.semicolon)
-      : super(comment, metadata) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(libraryKeyword)..add(_name)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => libraryKeyword;
-
-  @override
-  Token get keyword => libraryKeyword;
-
-  /**
-   * Return the name of the library being defined.
-   */
-  LibraryIdentifier get name => _name;
-
-  /**
-   * Set the name of the library being defined to the given [name].
-   */
-  void set name(LibraryIdentifier name) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitLibraryDirective(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-  }
-}
-
-/**
- * The identifier for a library.
- *
- * > libraryIdentifier ::=
- * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
- */
-class LibraryIdentifier extends Identifier {
-  /**
-   * The components of the identifier.
-   */
-  NodeList<SimpleIdentifier> _components;
-
-  /**
-   * Initialize a newly created prefixed identifier.
-   */
-  LibraryIdentifier(List<SimpleIdentifier> components) {
-    _components = new NodeList<SimpleIdentifier>(this, components);
-  }
-
-  @override
-  Token get beginToken => _components.beginToken;
-
-  @override
-  Element get bestElement => staticElement;
-
-  @override
-  // TODO(paulberry): add "." tokens.
-  Iterable get childEntities => new ChildEntities()..addAll(_components);
-
-  /**
-   * Return the components of the identifier.
-   */
-  NodeList<SimpleIdentifier> get components => _components;
-
-  @override
-  Token get endToken => _components.endToken;
-
-  @override
-  String get name {
-    StringBuffer buffer = new StringBuffer();
-    bool needsPeriod = false;
-    for (SimpleIdentifier identifier in _components) {
-      if (needsPeriod) {
-        buffer.write(".");
-      } else {
-        needsPeriod = true;
-      }
-      buffer.write(identifier.name);
-    }
-    return buffer.toString();
-  }
-
-  @override
-  int get precedence => 15;
-
-  @override
-  Element get propagatedElement => null;
-
-  @override
-  Element get staticElement => null;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitLibraryIdentifier(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _components.accept(visitor);
-  }
-}
-
-/**
- * A list literal.
- *
- * > listLiteral ::=
- * >     'const'? ('<' [TypeName] '>')? '[' ([Expression] ','?)? ']'
- */
-class ListLiteral extends TypedLiteral {
-  /**
-   * The left square bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The expressions used to compute the elements of the list.
-   */
-  NodeList<Expression> _elements;
-
-  /**
-   * The right square bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created list literal. The [constKeyword] can be `null`
-   * if the literal is not a constant. The [typeArguments] can be `null` if no
-   * type arguments were declared. The list of [elements] can be `null` if the
-   * list is empty.
-   */
-  ListLiteral(Token constKeyword, TypeArgumentList typeArguments,
-      this.leftBracket, List<Expression> elements, this.rightBracket)
-      : super(constKeyword, typeArguments) {
-    _elements = new NodeList<Expression>(this, elements);
-  }
-
-  @override
-  Token get beginToken {
-    if (constKeyword != null) {
-      return constKeyword;
-    }
-    TypeArgumentList typeArguments = this.typeArguments;
-    if (typeArguments != null) {
-      return typeArguments.beginToken;
-    }
-    return leftBracket;
-  }
-
-  @override
-  // TODO(paulberry): add commas.
-  Iterable get childEntities => super._childEntities
-    ..add(leftBracket)
-    ..addAll(_elements)
-    ..add(rightBracket);
-
-  /**
-   * Return the expressions used to compute the elements of the list.
-   */
-  NodeList<Expression> get elements => _elements;
-
-  @override
-  Token get endToken => rightBracket;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitListLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _elements.accept(visitor);
-  }
-}
-
-/**
- * A node that represents a literal expression.
- *
- * > literal ::=
- * >     [BooleanLiteral]
- * >   | [DoubleLiteral]
- * >   | [IntegerLiteral]
- * >   | [ListLiteral]
- * >   | [MapLiteral]
- * >   | [NullLiteral]
- * >   | [StringLiteral]
- */
-abstract class Literal extends Expression {
-  @override
-  int get precedence => 16;
-}
-
-/**
- * A literal map.
- *
- * > mapLiteral ::=
- * >     'const'? ('<' [TypeName] (',' [TypeName])* '>')?
- * >     '{' ([MapLiteralEntry] (',' [MapLiteralEntry])* ','?)? '}'
- */
-class MapLiteral extends TypedLiteral {
-  /**
-   * The left curly bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The entries in the map.
-   */
-  NodeList<MapLiteralEntry> _entries;
-
-  /**
-   * The right curly bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created map literal. The [constKeyword] can be `null` if
-   * the literal is not a constant. The [typeArguments] can be `null` if no type
-   * arguments were declared. The [entries] can be `null` if the map is empty.
-   */
-  MapLiteral(Token constKeyword, TypeArgumentList typeArguments,
-      this.leftBracket, List<MapLiteralEntry> entries, this.rightBracket)
-      : super(constKeyword, typeArguments) {
-    _entries = new NodeList<MapLiteralEntry>(this, entries);
-  }
-
-  @override
-  Token get beginToken {
-    if (constKeyword != null) {
-      return constKeyword;
-    }
-    TypeArgumentList typeArguments = this.typeArguments;
-    if (typeArguments != null) {
-      return typeArguments.beginToken;
-    }
-    return leftBracket;
-  }
-
-  @override
-  // TODO(paulberry): add commas.
-  Iterable get childEntities => super._childEntities
-    ..add(leftBracket)
-    ..addAll(entries)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the entries in the map.
-   */
-  NodeList<MapLiteralEntry> get entries => _entries;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitMapLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _entries.accept(visitor);
-  }
-}
-
-/**
- * A single key/value pair in a map literal.
- *
- * > mapLiteralEntry ::=
- * >     [Expression] ':' [Expression]
- */
-class MapLiteralEntry extends AstNode {
-  /**
-   * The expression computing the key with which the value will be associated.
-   */
-  Expression _key;
-
-  /**
-   * The colon that separates the key from the value.
-   */
-  Token separator;
-
-  /**
-   * The expression computing the value that will be associated with the key.
-   */
-  Expression _value;
-
-  /**
-   * Initialize a newly created map literal entry.
-   */
-  MapLiteralEntry(Expression key, this.separator, Expression value) {
-    _key = _becomeParentOf(key);
-    _value = _becomeParentOf(value);
-  }
-
-  @override
-  Token get beginToken => _key.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_key)..add(separator)..add(_value);
-
-  @override
-  Token get endToken => _value.endToken;
-
-  /**
-   * Return the expression computing the key with which the value will be
-   * associated.
-   */
-  Expression get key => _key;
-
-  /**
-   * Set the expression computing the key with which the value will be
-   * associated to the given [string].
-   */
-  void set key(Expression string) {
-    _key = _becomeParentOf(string);
-  }
-
-  /**
-   * Return the expression computing the value that will be associated with the
-   * key.
-   */
-  Expression get value => _value;
-
-  /**
-   * Set the expression computing the value that will be associated with the key
-   * to the given [expression].
-   */
-  void set value(Expression expression) {
-    _value = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitMapLiteralEntry(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_key, visitor);
-    _safelyVisitChild(_value, visitor);
-  }
-}
-
-/**
- * A method declaration.
- *
- * > methodDeclaration ::=
- * >     methodSignature [FunctionBody]
- * >
- * > methodSignature ::=
- * >     'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
- * >     methodName [TypeParameterList] [FormalParameterList]
- * >
- * > methodName ::=
- * >     [SimpleIdentifier]
- * >   | 'operator' [SimpleIdentifier]
- */
-class MethodDeclaration extends ClassMember {
-  /**
-   * The token for the 'external' keyword, or `null` if the constructor is not
-   * external.
-   */
-  Token externalKeyword;
-
-  /**
-   * The token representing the 'abstract' or 'static' keyword, or `null` if
-   * neither modifier was specified.
-   */
-  Token modifierKeyword;
-
-  /**
-   * The return type of the method, or `null` if no return type was declared.
-   */
-  TypeName _returnType;
-
-  /**
-   * The token representing the 'get' or 'set' keyword, or `null` if this is a
-   * method declaration rather than a property declaration.
-   */
-  Token propertyKeyword;
-
-  /**
-   * The token representing the 'operator' keyword, or `null` if this method
-   * does not declare an operator.
-   */
-  Token operatorKeyword;
-
-  /**
-   * The name of the method.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * The type parameters associated with the method, or `null` if the method is
-   * not a generic method.
-   */
-  TypeParameterList _typeParameters;
-
-  /**
-   * The parameters associated with the method, or `null` if this method
-   * declares a getter.
-   */
-  FormalParameterList _parameters;
-
-  /**
-   * The body of the method.
-   */
-  FunctionBody _body;
-
-  /**
-   * Initialize a newly created method declaration. Either or both of the
-   * [comment] and [metadata] can be `null` if the declaration does not have the
-   * corresponding attribute. The [externalKeyword] can be `null` if the method
-   * is not external. The [modifierKeyword] can be `null` if the method is
-   * neither abstract nor static. The [returnType] can be `null` if no return
-   * type was specified. The [propertyKeyword] can be `null` if the method is
-   * neither a getter or a setter. The [operatorKeyword] can be `null` if the
-   * method does not implement an operator. The [parameters] must be `null` if
-   * this method declares a getter.
-   */
-  MethodDeclaration(
-      Comment comment,
-      List<Annotation> metadata,
-      this.externalKeyword,
-      this.modifierKeyword,
-      TypeName returnType,
-      this.propertyKeyword,
-      this.operatorKeyword,
-      SimpleIdentifier name,
-      TypeParameterList typeParameters,
-      FormalParameterList parameters,
-      FunctionBody body)
-      : super(comment, metadata) {
-    _returnType = _becomeParentOf(returnType);
-    _name = _becomeParentOf(name);
-    _typeParameters = _becomeParentOf(typeParameters);
-    _parameters = _becomeParentOf(parameters);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
-   * Return the body of the method.
-   */
-  FunctionBody get body => _body;
-
-  /**
-   * Set the body of the method to the given [functionBody].
-   */
-  void set body(FunctionBody functionBody) {
-    _body = _becomeParentOf(functionBody);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(externalKeyword)
-    ..add(modifierKeyword)
-    ..add(_returnType)
-    ..add(propertyKeyword)
-    ..add(operatorKeyword)
-    ..add(_name)
-    ..add(_parameters)
-    ..add(_body);
-
-  /**
-   * Return the element associated with this method, or `null` if the AST
-   * structure has not been resolved. The element can either be a
-   * [MethodElement], if this represents the declaration of a normal method, or
-   * a [PropertyAccessorElement] if this represents the declaration of either a
-   * getter or a setter.
-   */
-  @override
-  ExecutableElement get element =>
-      _name != null ? (_name.staticElement as ExecutableElement) : null;
-
-  @override
-  Token get endToken => _body.endToken;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (modifierKeyword != null) {
-      return modifierKeyword;
-    } else if (_returnType != null) {
-      return _returnType.beginToken;
-    } else if (propertyKeyword != null) {
-      return propertyKeyword;
-    } else if (operatorKeyword != null) {
-      return operatorKeyword;
-    }
-    return _name.beginToken;
-  }
-
-  /**
-   * Return `true` if this method is declared to be an abstract method.
-   */
-  bool get isAbstract {
-    FunctionBody body = _body;
-    return externalKeyword == null &&
-        (body is EmptyFunctionBody && !body.semicolon.isSynthetic);
-  }
-
-  /**
-   * Return `true` if this method declares a getter.
-   */
-  bool get isGetter =>
-      propertyKeyword != null &&
-      (propertyKeyword as KeywordToken).keyword == Keyword.GET;
-
-  /**
-   * Return `true` if this method declares an operator.
-   */
-  bool get isOperator => operatorKeyword != null;
-
-  /**
-   * Return `true` if this method declares a setter.
-   */
-  bool get isSetter =>
-      propertyKeyword != null &&
-      (propertyKeyword as KeywordToken).keyword == Keyword.SET;
-
-  /**
-   * Return `true` if this method is declared to be a static method.
-   */
-  bool get isStatic =>
-      modifierKeyword != null &&
-      (modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
-
-  /**
-   * Return the name of the method.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the method to the given [identifier].
-   */
-  void set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the parameters associated with the method, or `null` if this method
-   * declares a getter.
-   */
-  FormalParameterList get parameters => _parameters;
-
-  /**
-   * Set the parameters associated with the method to the given list of
-   * [parameters].
-   */
-  void set parameters(FormalParameterList parameters) {
-    _parameters = _becomeParentOf(parameters);
-  }
-
-  /**
-   * Return the return type of the method, or `null` if no return type was
-   * declared.
-   */
-  TypeName get returnType => _returnType;
-
-  /**
-   * Set the return type of the method to the given [typeName].
-   */
-  void set returnType(TypeName typeName) {
-    _returnType = _becomeParentOf(typeName);
-  }
-
-  /**
-   * Return the type parameters associated with this method, or `null` if this
-   * method is not a generic method.
-   */
-  TypeParameterList get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters associated with this method to the given
-   * [typeParameters].
-   */
-  void set typeParameters(TypeParameterList typeParameters) {
-    _typeParameters = _becomeParentOf(typeParameters);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitMethodDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_returnType, visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_typeParameters, visitor);
-    _safelyVisitChild(_parameters, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * The invocation of either a function or a method. Invocations of functions
- * resulting from evaluating an expression are represented by
- * [FunctionExpressionInvocation] nodes. Invocations of getters and setters are
- * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
- *
- * > methodInvocation ::=
- * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
- */
-class MethodInvocation extends Expression {
-  /**
-   * The expression producing the object on which the method is defined, or
-   * `null` if there is no target (that is, the target is implicitly `this`).
-   */
-  Expression _target;
-
-  /**
-   * The operator that separates the target from the method name, or `null`
-   * if there is no target. In an ordinary method invocation this will be a
-   * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
-  Token operator;
-
-  /**
-   * The name of the method being invoked.
-   */
-  SimpleIdentifier _methodName;
-
-  /**
-   * The type arguments to be applied to the method being invoked, or `null` if
-   * no type arguments were provided.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * The list of arguments to the method.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The function type of the method invocation, or `null` if the AST
-   * structure has not been resolved, or if the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be an
-   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
-   * interface type that implements `Function`.
-   */
-  DartType staticInvokeType;
-
-  /**
-   * Like [staticInvokeType], but reflects propagated type information.
-   */
-  DartType propagatedInvokeType;
-
-  /**
-   * Initialize a newly created method invocation. The [target] and [operator]
-   * can be `null` if there is no target.
-   */
-  MethodInvocation(
-      Expression target,
-      this.operator,
-      SimpleIdentifier methodName,
-      TypeArgumentList typeArguments,
-      ArgumentList argumentList) {
-    _target = _becomeParentOf(target);
-    _methodName = _becomeParentOf(methodName);
-    _typeArguments = _becomeParentOf(typeArguments);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  /**
-   * Return the list of arguments to the method.
-   */
-  ArgumentList get argumentList => _argumentList;
-
-  /**
-   * Set the list of arguments to the method to the given [argumentList].
-   */
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  Token get beginToken {
-    if (_target != null) {
-      return _target.beginToken;
-    } else if (operator != null) {
-      return operator;
-    }
-    return _methodName.beginToken;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(_target)
-    ..add(operator)
-    ..add(_methodName)
-    ..add(_argumentList);
-
-  @override
-  Token get endToken => _argumentList.endToken;
-
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
-  bool get isCascaded =>
-      operator != null && operator.type == TokenType.PERIOD_PERIOD;
-
-  /**
-   * Return the name of the method being invoked.
-   */
-  SimpleIdentifier get methodName => _methodName;
-
-  /**
-   * Set the name of the method being invoked to the given [identifier].
-   */
-  void set methodName(SimpleIdentifier identifier) {
-    _methodName = _becomeParentOf(identifier);
-  }
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * Return the expression used to compute the receiver of the invocation. If
-   * this invocation is not part of a cascade expression, then this is the same
-   * as [target]. If this invocation is part of a cascade expression, then the
-   * target stored with the cascade expression is returned.
-   */
-  Expression get realTarget {
-    if (isCascaded) {
-      AstNode ancestor = parent;
-      while (ancestor is! CascadeExpression) {
-        if (ancestor == null) {
-          return _target;
-        }
-        ancestor = ancestor.parent;
-      }
-      return (ancestor as CascadeExpression).target;
-    }
-    return _target;
-  }
-
-  /**
-   * Return the expression producing the object on which the method is defined,
-   * or `null` if there is no target (that is, the target is implicitly `this`)
-   * or if this method invocation is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
-  Expression get target => _target;
-
-  /**
-   * Set the expression producing the object on which the method is defined to
-   * the given [expression].
-   */
-  void set target(Expression expression) {
-    _target = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the type arguments to be applied to the method being invoked, or
-   * `null` if no type arguments were provided.
-   */
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  /**
-   * Set the type arguments to be applied to the method being invoked to the
-   * given [typeArguments].
-   */
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_target, visitor);
-    _safelyVisitChild(_methodName, visitor);
-    _safelyVisitChild(_typeArguments, visitor);
-    _safelyVisitChild(_argumentList, visitor);
-  }
-}
-
-/**
- * A node that declares a single name within the scope of a compilation unit.
- */
-abstract class NamedCompilationUnitMember extends CompilationUnitMember {
-  /**
-   * The name of the member being declared.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * Initialize a newly created compilation unit member with the given [name].
-   * Either or both of the [comment] and [metadata] can be `null` if the member
-   * does not have the corresponding attribute.
-   */
-  NamedCompilationUnitMember(
-      Comment comment, List<Annotation> metadata, SimpleIdentifier name)
-      : super(comment, metadata) {
-    _name = _becomeParentOf(name);
-  }
-
-  /**
-   * Return the name of the member being declared.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the member being declared to the given [identifier].
-   */
-  void set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-}
-
-/**
- * An expression that has a name associated with it. They are used in method
- * invocations when there are named parameters.
- *
- * > namedExpression ::=
- * >     [Label] [Expression]
- */
-class NamedExpression extends Expression {
-  /**
-   * The name associated with the expression.
-   */
-  Label _name;
-
-  /**
-   * The expression with which the name is associated.
-   */
-  Expression _expression;
-
-  /**
-   * Initialize a newly created named expression..
-   */
-  NamedExpression(Label name, Expression expression) {
-    _name = _becomeParentOf(name);
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => _name.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_name)..add(_expression);
-
-  /**
-   * Return the element representing the parameter being named by this
-   * expression, or `null` if the AST structure has not been resolved or if
-   * there is no parameter with the same name as this expression.
-   */
-  ParameterElement get element {
-    Element element = _name.label.staticElement;
-    if (element is ParameterElement) {
-      return element;
-    }
-    return null;
-  }
-
-  @override
-  Token get endToken => _expression.endToken;
-
-  /**
-   * Return the expression with which the name is associated.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression with which the name is associated to the given
-   * [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the name associated with the expression.
-   */
-  Label get name => _name;
-
-  /**
-   * Set the name associated with the expression to the given [identifier].
-   */
-  void set name(Label identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  @override
-  int get precedence => 0;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitNamedExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A node that represents a directive that impacts the namespace of a library.
- *
- * > directive ::=
- * >     [ExportDirective]
- * >   | [ImportDirective]
- */
-abstract class NamespaceDirective extends UriBasedDirective {
-  /**
-   * The token representing the 'import' or 'export' keyword.
-   */
-  Token keyword;
-
-  /**
-   * The configurations used to control which library will actually be loaded at
-   * run-time.
-   */
-  NodeList<Configuration> _configurations;
-
-  /**
-   * The combinators used to control which names are imported or exported.
-   */
-  NodeList<Combinator> _combinators;
-
-  /**
-   * The semicolon terminating the directive.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created namespace directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute. The list of [combinators] can be `null` if there
-   * are no combinators.
-   */
-  NamespaceDirective(
-      Comment comment,
-      List<Annotation> metadata,
-      this.keyword,
-      StringLiteral libraryUri,
-      List<Configuration> configurations,
-      List<Combinator> combinators,
-      this.semicolon)
-      : super(comment, metadata, libraryUri) {
-    _configurations = new NodeList<Configuration>(this, configurations);
-    _combinators = new NodeList<Combinator>(this, combinators);
-  }
-
-  /**
-   * Return the combinators used to control how names are imported or exported.
-   */
-  NodeList<Combinator> get combinators => _combinators;
-
-  /**
-   * Return the configurations used to control which library will actually be
-   * loaded at run-time.
-   */
-  NodeList<Configuration> get configurations => _configurations;
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => keyword;
-
-  @override
-  LibraryElement get uriElement;
-}
-
-/**
- * The "native" clause in an class declaration.
- *
- * > nativeClause ::=
- * >     'native' [StringLiteral]
- */
-class NativeClause extends AstNode {
-  /**
-   * The token representing the 'native' keyword.
-   */
-  Token nativeKeyword;
-
-  /**
-   * The name of the native object that implements the class.
-   */
-  StringLiteral _name;
-
-  /**
-   * Initialize a newly created native clause.
-   */
-  NativeClause(this.nativeKeyword, StringLiteral name) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  Token get beginToken => nativeKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(nativeKeyword)..add(_name);
-
-  @override
-  Token get endToken => _name.endToken;
-
-  /**
-   * Return the name of the native object that implements the class.
-   */
-  StringLiteral get name => _name;
-
-  /**
-   * Set the name of the native object that implements the class to the given
-   * [name].
-   */
-  void set name(StringLiteral name) {
-    _name = _becomeParentOf(name);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitNativeClause(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_name, visitor);
-  }
-}
-
-/**
- * A function body that consists of a native keyword followed by a string
- * literal.
- *
- * > nativeFunctionBody ::=
- * >     'native' [SimpleStringLiteral] ';'
- */
-class NativeFunctionBody extends FunctionBody {
-  /**
-   * The token representing 'native' that marks the start of the function body.
-   */
-  Token nativeKeyword;
-
-  /**
-   * The string literal, after the 'native' token.
-   */
-  StringLiteral _stringLiteral;
-
-  /**
-   * The token representing the semicolon that marks the end of the function
-   * body.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created function body consisting of the 'native' token,
-   * a string literal, and a semicolon.
-   */
-  NativeFunctionBody(
-      this.nativeKeyword, StringLiteral stringLiteral, this.semicolon) {
-    _stringLiteral = _becomeParentOf(stringLiteral);
-  }
-
-  @override
-  Token get beginToken => nativeKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(nativeKeyword)
-    ..add(_stringLiteral)
-    ..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the string literal representing the string after the 'native' token.
-   */
-  StringLiteral get stringLiteral => _stringLiteral;
-
-  /**
-   * Set the string literal representing the string after the 'native' token to
-   * the given [stringLiteral].
-   */
-  void set stringLiteral(StringLiteral stringLiteral) {
-    _stringLiteral = _becomeParentOf(stringLiteral);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitNativeFunctionBody(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_stringLiteral, visitor);
-  }
-}
-
-/**
- * A list of AST nodes that have a common parent.
- */
-class NodeList<E extends AstNode> extends Object with ListMixin<E> {
-  /**
-   * The node that is the parent of each of the elements in the list.
-   */
-  AstNode owner;
-
-  /**
-   * The elements contained in the list.
-   */
-  List<E> _elements = <E>[];
-
-  /**
-   * Initialize a newly created list of nodes such that all of the nodes that
-   * are added to the list will have their parent set to the given [owner]. The
-   * list will initially be populated with the given [elements].
-   */
-  NodeList(this.owner, [List<E> elements]) {
-    addAll(elements);
-  }
-
-  /**
-   * Return the first token included in this node list's source range, or `null`
-   * if the list is empty.
-   */
-  Token get beginToken {
-    if (_elements.length == 0) {
-      return null;
-    }
-    return _elements[0].beginToken;
-  }
-
-  /**
-   * Return the last token included in this node list's source range, or `null`
-   * if the list is empty.
-   */
-  Token get endToken {
-    int length = _elements.length;
-    if (length == 0) {
-      return null;
-    }
-    return _elements[length - 1].endToken;
-  }
-
-  int get length => _elements.length;
-
-  @deprecated // Never intended for public use.
-  @override
-  void set length(int newLength) {
-    throw new UnsupportedError("Cannot resize NodeList.");
-  }
-
-  E operator [](int index) {
-    if (index < 0 || index >= _elements.length) {
-      throw new RangeError("Index: $index, Size: ${_elements.length}");
-    }
-    return _elements[index];
-  }
-
-  void operator []=(int index, E node) {
-    if (index < 0 || index >= _elements.length) {
-      throw new RangeError("Index: $index, Size: ${_elements.length}");
-    }
-    owner._becomeParentOf(node);
-    _elements[index] = node;
-  }
-
-  /**
-   * Use the given [visitor] to visit each of the nodes in this list.
-   */
-  accept(AstVisitor visitor) {
-    int length = _elements.length;
-    for (var i = 0; i < length; i++) {
-      _elements[i].accept(visitor);
-    }
-  }
-
-  @override
-  void add(E node) {
-    insert(length, node);
-  }
-
-  @override
-  bool addAll(Iterable<E> nodes) {
-    if (nodes != null && !nodes.isEmpty) {
-      _elements.addAll(nodes);
-      for (E node in nodes) {
-        owner._becomeParentOf(node);
-      }
-      return true;
-    }
-    return false;
-  }
-
-  @override
-  void clear() {
-    _elements = <E>[];
-  }
-
-  @override
-  void insert(int index, E node) {
-    int length = _elements.length;
-    if (index < 0 || index > length) {
-      throw new RangeError("Index: $index, Size: ${_elements.length}");
-    }
-    owner._becomeParentOf(node);
-    if (length == 0) {
-      _elements.add(node);
-    } else {
-      _elements.insert(index, node);
-    }
-  }
-
-  @override
-  E removeAt(int index) {
-    if (index < 0 || index >= _elements.length) {
-      throw new RangeError("Index: $index, Size: ${_elements.length}");
-    }
-    E removedNode = _elements[index];
-    _elements.removeAt(index);
-    return removedNode;
-  }
-}
-
-/**
- * A formal parameter that is required (is not optional).
- *
- * > normalFormalParameter ::=
- * >     [FunctionTypedFormalParameter]
- * >   | [FieldFormalParameter]
- * >   | [SimpleFormalParameter]
- */
-abstract class NormalFormalParameter extends FormalParameter {
-  /**
-   * The documentation comment associated with this parameter, or `null` if this
-   * parameter does not have a documentation comment associated with it.
-   */
-  Comment _comment;
-
-  /**
-   * The annotations associated with this parameter.
-   */
-  NodeList<Annotation> _metadata;
-
-  /**
-   * The name of the parameter being declared.
-   */
-  SimpleIdentifier _identifier;
-
-  /**
-   * Initialize a newly created formal parameter. Either or both of the
-   * [comment] and [metadata] can be `null` if the parameter does not have the
-   * corresponding attribute.
-   */
-  NormalFormalParameter(
-      Comment comment, List<Annotation> metadata, SimpleIdentifier identifier) {
-    _comment = _becomeParentOf(comment);
-    _metadata = new NodeList<Annotation>(this, metadata);
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the documentation comment associated with this parameter, or `null`
-   * if this parameter does not have a documentation comment associated with it.
-   */
-  Comment get documentationComment => _comment;
-
-  /**
-   * Set the documentation comment associated with this parameter to the given
-   * [comment].
-   */
-  void set documentationComment(Comment comment) {
-    _comment = _becomeParentOf(comment);
-  }
-
-  @override
-  SimpleIdentifier get identifier => _identifier;
-
-  /**
-   * Set the name of the parameter being declared to the given [identifier].
-   */
-  void set identifier(SimpleIdentifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  @override
-  ParameterKind get kind {
-    AstNode parent = this.parent;
-    if (parent is DefaultFormalParameter) {
-      return parent.kind;
-    }
-    return ParameterKind.REQUIRED;
-  }
-
-  @override
-  NodeList<Annotation> get metadata => _metadata;
-
-  /**
-   * Set the metadata associated with this node to the given [metadata].
-   */
-  void set metadata(List<Annotation> metadata) {
-    _metadata.clear();
-    _metadata.addAll(metadata);
-  }
-
-  /**
-   * Return a list containing the comment and annotations associated with this
-   * parameter, sorted in lexical order.
-   */
-  List<AstNode> get sortedCommentAndAnnotations {
-    return <AstNode>[]
-      ..add(_comment)
-      ..addAll(_metadata)
-      ..sort(AstNode.LEXICAL_ORDER);
-  }
-
-  ChildEntities get _childEntities {
-    ChildEntities result = new ChildEntities();
-    if (_commentIsBeforeAnnotations()) {
-      result
-        ..add(_comment)
-        ..addAll(_metadata);
-    } else {
-      result.addAll(sortedCommentAndAnnotations);
-    }
-    return result;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    //
-    // Note that subclasses are responsible for visiting the identifier because
-    // they often need to visit other nodes before visiting the identifier.
-    //
-    if (_commentIsBeforeAnnotations()) {
-      _safelyVisitChild(_comment, visitor);
-      _metadata.accept(visitor);
-    } else {
-      for (AstNode child in sortedCommentAndAnnotations) {
-        child.accept(visitor);
-      }
-    }
-  }
-
-  /**
-   * Return `true` if the comment is lexically before any annotations.
-   */
-  bool _commentIsBeforeAnnotations() {
-    if (_comment == null || _metadata.isEmpty) {
-      return true;
-    }
-    Annotation firstAnnotation = _metadata[0];
-    return _comment.offset < firstAnnotation.offset;
-  }
-}
-
-/**
- * A null literal expression.
- *
- * > nullLiteral ::=
- * >     'null'
- */
-class NullLiteral extends Literal {
-  /**
-   * The token representing the literal.
-   */
-  Token literal;
-
-  /**
-   * Initialize a newly created null literal.
-   */
-  NullLiteral(this.literal);
-
-  @override
-  Token get beginToken => literal;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(literal);
-
-  @override
-  Token get endToken => literal;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitNullLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A parenthesized expression.
- *
- * > parenthesizedExpression ::=
- * >     '(' [Expression] ')'
- */
-class ParenthesizedExpression extends Expression {
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The expression within the parentheses.
-   */
-  Expression _expression;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * Initialize a newly created parenthesized expression.
-   */
-  ParenthesizedExpression(
-      this.leftParenthesis, Expression expression, this.rightParenthesis) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => leftParenthesis;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftParenthesis)
-    ..add(_expression)
-    ..add(rightParenthesis);
-
-  @override
-  Token get endToken => rightParenthesis;
-
-  /**
-   * Return the expression within the parentheses.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression within the parentheses to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 15;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitParenthesizedExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A part directive.
- *
- * > partDirective ::=
- * >     [Annotation] 'part' [StringLiteral] ';'
- */
-class PartDirective extends UriBasedDirective {
-  /**
-   * The token representing the 'part' keyword.
-   */
-  Token partKeyword;
-
-  /**
-   * The semicolon terminating the directive.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created part directive. Either or both of the [comment]
-   * and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute.
-   */
-  PartDirective(Comment comment, List<Annotation> metadata, this.partKeyword,
-      StringLiteral partUri, this.semicolon)
-      : super(comment, metadata, partUri);
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(partKeyword)..add(_uri)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => partKeyword;
-
-  @override
-  Token get keyword => partKeyword;
-
-  @override
-  CompilationUnitElement get uriElement => element as CompilationUnitElement;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPartDirective(this);
-}
-
-/**
- * A part-of directive.
- *
- * > partOfDirective ::=
- * >     [Annotation] 'part' 'of' [Identifier] ';'
- */
-class PartOfDirective extends Directive {
-  /**
-   * The token representing the 'part' keyword.
-   */
-  Token partKeyword;
-
-  /**
-   * The token representing the 'of' keyword.
-   */
-  Token ofKeyword;
-
-  /**
-   * The name of the library that the containing compilation unit is part of.
-   */
-  LibraryIdentifier _libraryName;
-
-  /**
-   * The semicolon terminating the directive.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created part-of directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute.
-   */
-  PartOfDirective(Comment comment, List<Annotation> metadata, this.partKeyword,
-      this.ofKeyword, LibraryIdentifier libraryName, this.semicolon)
-      : super(comment, metadata) {
-    _libraryName = _becomeParentOf(libraryName);
-  }
-
-  @override
-  Iterable get childEntities => super._childEntities
-    ..add(partKeyword)
-    ..add(ofKeyword)
-    ..add(_libraryName)
-    ..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => partKeyword;
-
-  @override
-  Token get keyword => partKeyword;
-
-  /**
-   * Return the name of the library that the containing compilation unit is part
-   * of.
-   */
-  LibraryIdentifier get libraryName => _libraryName;
-
-  /**
-   * Set the name of the library that the containing compilation unit is part of
-   * to the given [libraryName].
-   */
-  void set libraryName(LibraryIdentifier libraryName) {
-    _libraryName = _becomeParentOf(libraryName);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_libraryName, visitor);
-  }
-}
-
-/**
- * A postfix unary expression.
- *
- * > postfixExpression ::=
- * >     [Expression] [Token]
- */
-class PostfixExpression extends Expression {
-  /**
-   * The expression computing the operand for the operator.
-   */
-  Expression _operand;
-
-  /**
-   * The postfix operator being applied to the operand.
-   */
-  Token operator;
-
-  /**
-   * The element associated with this the operator based on the propagated type
-   * of the operand, or `null` if the AST structure has not been resolved, if
-   * the operator is not user definable, or if the operator could not be
-   * resolved.
-   */
-  MethodElement propagatedElement;
-
-  /**
-   * The element associated with the operator based on the static type of the
-   * operand, or `null` if the AST structure has not been resolved, if the
-   * operator is not user definable, or if the operator could not be resolved.
-   */
-  MethodElement staticElement;
-
-  /**
-   * Initialize a newly created postfix expression.
-   */
-  PostfixExpression(Expression operand, this.operator) {
-    _operand = _becomeParentOf(operand);
-  }
-
-  @override
-  Token get beginToken => _operand.beginToken;
-
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  MethodElement get bestElement {
-    MethodElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_operand)..add(operator);
-
-  @override
-  Token get endToken => operator;
-
-  /**
-   * Return the expression computing the operand for the operator.
-   */
-  Expression get operand => _operand;
-
-  /**
-   * Set the expression computing the operand for the operator to the given
-   * [expression].
-   */
-  void set operand(Expression expression) {
-    _operand = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _propagatedParameterElementForOperand {
-    if (propagatedElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = propagatedElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  ParameterElement get _staticParameterElementForOperand {
-    if (staticElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = staticElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPostfixExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_operand, visitor);
-  }
-}
-
-/**
- * An identifier that is prefixed or an access to an object property where the
- * target of the property access is a simple identifier.
- *
- * > prefixedIdentifier ::=
- * >     [SimpleIdentifier] '.' [SimpleIdentifier]
- */
-class PrefixedIdentifier extends Identifier {
-  /**
-   * The prefix associated with the library in which the identifier is defined.
-   */
-  SimpleIdentifier _prefix;
-
-  /**
-   * The period used to separate the prefix from the identifier.
-   */
-  Token period;
-
-  /**
-   * The identifier being prefixed.
-   */
-  SimpleIdentifier _identifier;
-
-  /**
-   * Initialize a newly created prefixed identifier.
-   */
-  PrefixedIdentifier(
-      SimpleIdentifier prefix, this.period, SimpleIdentifier identifier) {
-    _prefix = _becomeParentOf(prefix);
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  @override
-  Token get beginToken => _prefix.beginToken;
-
-  @override
-  Element get bestElement {
-    if (_identifier == null) {
-      return null;
-    }
-    return _identifier.bestElement;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_prefix)..add(period)..add(_identifier);
-
-  @override
-  Token get endToken => _identifier.endToken;
-
-  /**
-   * Return the identifier being prefixed.
-   */
-  SimpleIdentifier get identifier => _identifier;
-
-  /**
-   * Set the identifier being prefixed to the given [identifier].
-   */
-  void set identifier(SimpleIdentifier identifier) {
-    _identifier = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return `true` if this type is a deferred type. If the AST structure has not
-   * been resolved, then return `false`.
-   *
-   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
-   * </i>p.T</i> where <i>p</i> is a deferred prefix.
-   */
-  bool get isDeferred {
-    Element element = _prefix.staticElement;
-    if (element is! PrefixElement) {
-      return false;
-    }
-    PrefixElement prefixElement = element as PrefixElement;
-    List<ImportElement> imports =
-        prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
-    if (imports.length != 1) {
-      return false;
-    }
-    return imports[0].isDeferred;
-  }
-
-  @override
-  String get name => "${_prefix.name}.${_identifier.name}";
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * Return the prefix associated with the library in which the identifier is
-   * defined.
-   */
-  SimpleIdentifier get prefix => _prefix;
-
-  /**
-   * Set the prefix associated with the library in which the identifier is
-   * defined to the given [identifier].
-   */
-  void set prefix(SimpleIdentifier identifier) {
-    _prefix = _becomeParentOf(identifier);
-  }
-
-  @override
-  Element get propagatedElement {
-    if (_identifier == null) {
-      return null;
-    }
-    return _identifier.propagatedElement;
-  }
-
-  @override
-  Element get staticElement {
-    if (_identifier == null) {
-      return null;
-    }
-    return _identifier.staticElement;
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPrefixedIdentifier(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_prefix, visitor);
-    _safelyVisitChild(_identifier, visitor);
-  }
-}
-
-/**
- * A prefix unary expression.
- *
- * > prefixExpression ::=
- * >     [Token] [Expression]
- */
-class PrefixExpression extends Expression {
-  /**
-   * The prefix operator being applied to the operand.
-   */
-  Token operator;
-
-  /**
-   * The expression computing the operand for the operator.
-   */
-  Expression _operand;
-
-  /**
-   * The element associated with the operator based on the static type of the
-   * operand, or `null` if the AST structure has not been resolved, if the
-   * operator is not user definable, or if the operator could not be resolved.
-   */
-  MethodElement staticElement;
-
-  /**
-   * The element associated with the operator based on the propagated type of
-   * the operand, or `null` if the AST structure has not been resolved, if the
-   * operator is not user definable, or if the operator could not be resolved.
-   */
-  MethodElement propagatedElement;
-
-  /**
-   * Initialize a newly created prefix expression.
-   */
-  PrefixExpression(this.operator, Expression operand) {
-    _operand = _becomeParentOf(operand);
-  }
-
-  @override
-  Token get beginToken => operator;
-
-  /**
-   * Return the best element available for this operator. If resolution was able
-   * to find a better element based on type propagation, that element will be
-   * returned. Otherwise, the element found using the result of static analysis
-   * will be returned. If resolution has not been performed, then `null` will be
-   * returned.
-   */
-  MethodElement get bestElement {
-    MethodElement element = propagatedElement;
-    if (element == null) {
-      element = staticElement;
-    }
-    return element;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(operator)..add(_operand);
-
-  @override
-  Token get endToken => _operand.endToken;
-
-  /**
-   * Return the expression computing the operand for the operator.
-   */
-  Expression get operand => _operand;
-
-  /**
-   * Set the expression computing the operand for the operator to the given
-   * [expression].
-   */
-  void set operand(Expression expression) {
-    _operand = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 14;
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
-  ParameterElement get _propagatedParameterElementForOperand {
-    if (propagatedElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = propagatedElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  ParameterElement get _staticParameterElementForOperand {
-    if (staticElement == null) {
-      return null;
-    }
-    List<ParameterElement> parameters = staticElement.parameters;
-    if (parameters.length < 1) {
-      return null;
-    }
-    return parameters[0];
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPrefixExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_operand, visitor);
-  }
-}
-
-/**
- * The access of a property of an object.
- *
- * Note, however, that accesses to properties of objects can also be represented
- * as [PrefixedIdentifier] nodes in cases where the target is also a simple
- * identifier.
- *
- * > propertyAccess ::=
- * >     [Expression] '.' [SimpleIdentifier]
- */
-class PropertyAccess extends Expression {
-  /**
-   * The expression computing the object defining the property being accessed.
-   */
-  Expression _target;
-
-  /**
-   * The property access operator.
-   */
-  Token operator;
-
-  /**
-   * The name of the property being accessed.
-   */
-  SimpleIdentifier _propertyName;
-
-  /**
-   * Initialize a newly created property access expression.
-   */
-  PropertyAccess(
-      Expression target, this.operator, SimpleIdentifier propertyName) {
-    _target = _becomeParentOf(target);
-    _propertyName = _becomeParentOf(propertyName);
-  }
-
-  @override
-  Token get beginToken {
-    if (_target != null) {
-      return _target.beginToken;
-    }
-    return operator;
-  }
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_target)..add(operator)..add(_propertyName);
-
-  @override
-  Token get endToken => _propertyName.endToken;
-
-  @override
-  bool get isAssignable => true;
-
-  /**
-   * Return `true` if this expression is cascaded. If it is, then the target of
-   * this expression is not stored locally but is stored in the nearest ancestor
-   * that is a [CascadeExpression].
-   */
-  bool get isCascaded =>
-      operator != null && operator.type == TokenType.PERIOD_PERIOD;
-
-  @override
-  int get precedence => 15;
-
-  /**
-   * Return the name of the property being accessed.
-   */
-  SimpleIdentifier get propertyName => _propertyName;
-
-  /**
-   * Set the name of the property being accessed to the given [identifier].
-   */
-  void set propertyName(SimpleIdentifier identifier) {
-    _propertyName = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the expression used to compute the receiver of the invocation. If
-   * this invocation is not part of a cascade expression, then this is the same
-   * as [target]. If this invocation is part of a cascade expression, then the
-   * target stored with the cascade expression is returned.
-   */
-  Expression get realTarget {
-    if (isCascaded) {
-      AstNode ancestor = parent;
-      while (ancestor is! CascadeExpression) {
-        if (ancestor == null) {
-          return _target;
-        }
-        ancestor = ancestor.parent;
-      }
-      return (ancestor as CascadeExpression).target;
-    }
-    return _target;
-  }
-
-  /**
-   * Return the expression computing the object defining the property being
-   * accessed, or `null` if this property access is part of a cascade expression.
-   *
-   * Use [realTarget] to get the target independent of whether this is part of a
-   * cascade expression.
-   */
-  Expression get target => _target;
-
-  /**
-   * Set the expression computing the object defining the property being
-   * accessed to the given [expression].
-   */
-  void set target(Expression expression) {
-    _target = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitPropertyAccess(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_target, visitor);
-    _safelyVisitChild(_propertyName, visitor);
-  }
-}
-
-/**
- * The invocation of a constructor in the same class from within a constructor's
- * initialization list.
- *
- * > redirectingConstructorInvocation ::=
- * >     'this' ('.' identifier)? arguments
- */
-class RedirectingConstructorInvocation extends ConstructorInitializer {
-  /**
-   * The token for the 'this' keyword.
-   */
-  Token thisKeyword;
-
-  /**
-   * The token for the period before the name of the constructor that is being
-   * invoked, or `null` if the unnamed constructor is being invoked.
-   */
-  Token period;
-
-  /**
-   * The name of the constructor that is being invoked, or `null` if the unnamed
-   * constructor is being invoked.
-   */
-  SimpleIdentifier _constructorName;
-
-  /**
-   * The list of arguments to the constructor.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The element associated with the constructor based on static type
-   * information, or `null` if the AST structure has not been resolved or if the
-   * constructor could not be resolved.
-   */
-  ConstructorElement staticElement;
-
-  /**
-   * Initialize a newly created redirecting invocation to invoke the constructor
-   * with the given name with the given arguments. The [constructorName] can be
-   * `null` if the constructor being invoked is the unnamed constructor.
-   */
-  RedirectingConstructorInvocation(this.thisKeyword, this.period,
-      SimpleIdentifier constructorName, ArgumentList argumentList) {
-    _constructorName = _becomeParentOf(constructorName);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  /**
-   * Return the list of arguments to the constructor.
-   */
-  ArgumentList get argumentList => _argumentList;
-
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  Token get beginToken => thisKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(thisKeyword)
-    ..add(period)
-    ..add(_constructorName)
-    ..add(_argumentList);
-
-  /**
-   * Return the name of the constructor that is being invoked, or `null` if the
-   * unnamed constructor is being invoked.
-   */
-  SimpleIdentifier get constructorName => _constructorName;
-
-  /**
-   * Set the name of the constructor that is being invoked to the given
-   * [identifier].
-   */
-  void set constructorName(SimpleIdentifier identifier) {
-    _constructorName = _becomeParentOf(identifier);
-  }
-
-  @override
-  Token get endToken => _argumentList.endToken;
-
-  @override
-  accept(AstVisitor visitor) =>
-      visitor.visitRedirectingConstructorInvocation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_constructorName, visitor);
-    _safelyVisitChild(_argumentList, visitor);
-  }
-}
-
-/**
- * A rethrow expression.
- *
- * > rethrowExpression ::=
- * >     'rethrow'
- */
-class RethrowExpression extends Expression {
-  /**
-   * The token representing the 'rethrow' keyword.
-   */
-  Token rethrowKeyword;
-
-  /**
-   * Initialize a newly created rethrow expression.
-   */
-  RethrowExpression(this.rethrowKeyword);
-
-  @override
-  Token get beginToken => rethrowKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(rethrowKeyword);
-
-  @override
-  Token get endToken => rethrowKeyword;
-
-  @override
-  int get precedence => 0;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitRethrowExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A return statement.
- *
- * > returnStatement ::=
- * >     'return' [Expression]? ';'
- */
-class ReturnStatement extends Statement {
-  /**
-   * The token representing the 'return' keyword.
-   */
-  Token returnKeyword;
-
-  /**
-   * The expression computing the value to be returned, or `null` if no explicit
-   * value was provided.
-   */
-  Expression _expression;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created return statement. The [expression] can be `null`
-   * if no explicit value was provided.
-   */
-  ReturnStatement(this.returnKeyword, Expression expression, this.semicolon) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => returnKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(returnKeyword)..add(_expression)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the expression computing the value to be returned, or `null` if no
-   * explicit value was provided.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression computing the value to be returned to the given
-   * [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * A script tag that can optionally occur at the beginning of a compilation unit.
- *
- * > scriptTag ::=
- * >     '#!' (~NEWLINE)* NEWLINE
- */
-class ScriptTag extends AstNode {
-  /**
-   * The token representing this script tag.
-   */
-  Token scriptTag;
-
-  /**
-   * Initialize a newly created script tag.
-   */
-  ScriptTag(this.scriptTag);
-
-  @override
-  Token get beginToken => scriptTag;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(scriptTag);
-
-  @override
-  Token get endToken => scriptTag;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitScriptTag(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A combinator that restricts the names being imported to those in a given list.
- *
- * > showCombinator ::=
- * >     'show' [SimpleIdentifier] (',' [SimpleIdentifier])*
- */
-class ShowCombinator extends Combinator {
-  /**
-   * The list of names from the library that are made visible by this combinator.
-   */
-  NodeList<SimpleIdentifier> _shownNames;
-
-  /**
-   * Initialize a newly created import show combinator.
-   */
-  ShowCombinator(Token keyword, List<SimpleIdentifier> shownNames)
-      : super(keyword) {
-    _shownNames = new NodeList<SimpleIdentifier>(this, shownNames);
-  }
-
-  @override
-  // TODO(paulberry): add commas.
-  Iterable get childEntities => new ChildEntities()
-    ..add(keyword)
-    ..addAll(_shownNames);
-
-  @override
-  Token get endToken => _shownNames.endToken;
-
-  /**
-   * Return the list of names from the library that are made visible by this
-   * combinator.
-   */
-  NodeList<SimpleIdentifier> get shownNames => _shownNames;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitShowCombinator(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _shownNames.accept(visitor);
-  }
-}
-
-/**
- * A simple formal parameter.
- *
- * > simpleFormalParameter ::=
- * >     ('final' [TypeName] | 'var' | [TypeName])? [SimpleIdentifier]
- */
-class SimpleFormalParameter extends NormalFormalParameter {
-  /**
-   * The token representing either the 'final', 'const' or 'var' keyword, or
-   * `null` if no keyword was used.
-   */
-  Token keyword;
-
-  /**
-   * The name of the declared type of the parameter, or `null` if the parameter
-   * does not have a declared type.
-   */
-  TypeName _type;
-
-  /**
-   * Initialize a newly created formal parameter. Either or both of the
-   * [comment] and [metadata] can be `null` if the parameter does not have the
-   * corresponding attribute. The [keyword] can be `null` if a type was
-   * specified. The [type] must be `null` if the keyword is 'var'.
-   */
-  SimpleFormalParameter(Comment comment, List<Annotation> metadata,
-      this.keyword, TypeName type, SimpleIdentifier identifier)
-      : super(comment, metadata, identifier) {
-    _type = _becomeParentOf(type);
-  }
-
-  @override
-  Token get beginToken {
-    NodeList<Annotation> metadata = this.metadata;
-    if (!metadata.isEmpty) {
-      return metadata.beginToken;
-    } else if (keyword != null) {
-      return keyword;
-    } else if (_type != null) {
-      return _type.beginToken;
-    }
-    return identifier.beginToken;
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(keyword)..add(_type)..add(identifier);
-
-  @override
-  Token get endToken => identifier.endToken;
-
-  @override
-  bool get isConst =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.CONST;
-
-  @override
-  bool get isFinal =>
-      (keyword is KeywordToken) &&
-      (keyword as KeywordToken).keyword == Keyword.FINAL;
-
-  /**
-   * Return the name of the declared type of the parameter, or `null` if the
-   * parameter does not have a declared type.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the name of the declared type of the parameter to the given [typeName].
-   */
-  void set type(TypeName typeName) {
-    _type = _becomeParentOf(typeName);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSimpleFormalParameter(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_type, visitor);
-    _safelyVisitChild(identifier, visitor);
-  }
-}
-
-/**
- * A simple identifier.
- *
- * > simpleIdentifier ::=
- * >     initialCharacter internalCharacter*
- * >
- * > initialCharacter ::= '_' | '$' | letter
- * >
- * > internalCharacter ::= '_' | '$' | letter | digit
- */
-class SimpleIdentifier extends Identifier {
-  /**
-   * The token representing the identifier.
-   */
-  Token token;
-
-  /**
-   * The element associated with this identifier based on static type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved.
-   */
-  Element _staticElement;
-
-  /**
-   * The element associated with this identifier based on propagated type
-   * information, or `null` if the AST structure has not been resolved or if
-   * this identifier could not be resolved.
-   */
-  Element _propagatedElement;
-
-  /**
-   * If this expression is both in a getter and setter context, the
-   * [AuxiliaryElements] will be set to hold onto the static and propagated
-   * information. The auxiliary element will hold onto the elements from the
-   * getter context.
-   */
-  AuxiliaryElements auxiliaryElements = null;
-
-  /**
-   * Initialize a newly created identifier.
-   */
-  SimpleIdentifier(this.token);
-
-  @override
-  Token get beginToken => token;
-
-  @override
-  Element get bestElement {
-    if (_propagatedElement == null) {
-      return _staticElement;
-    }
-    return _propagatedElement;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(token);
-
-  @override
-  Token get endToken => token;
-
-  /**
-   * Return `true` if this identifier is the "name" part of a prefixed
-   * identifier or a method invocation.
-   */
-  bool get isQualified {
-    AstNode parent = this.parent;
-    if (parent is PrefixedIdentifier) {
-      return identical(parent.identifier, this);
-    }
-    if (parent is PropertyAccess) {
-      return identical(parent.propertyName, this);
-    }
-    if (parent is MethodInvocation) {
-      MethodInvocation invocation = parent;
-      return identical(invocation.methodName, this) &&
-          invocation.realTarget != null;
-    }
-    return false;
-  }
-
-  @override
-  bool get isSynthetic => token.isSynthetic;
-
-  @override
-  String get name => token.lexeme;
-
-  @override
-  int get precedence => 16;
-
-  @override
-  Element get propagatedElement => _propagatedElement;
-
-  /**
-   * Set the element associated with this identifier based on propagated type
-   * information to the given [element].
-   */
-  void set propagatedElement(Element element) {
-    _propagatedElement = _validateElement(element);
-  }
-
-  @override
-  Element get staticElement => _staticElement;
-
-  /**
-   * Set the element associated with this identifier based on static type
-   * information to the given [element].
-   */
-  void set staticElement(Element element) {
-    _staticElement = _validateElement(element);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSimpleIdentifier(this);
-
-  /**
-   * Return `true` if this identifier is the name being declared in a
-   * declaration.
-   */
-  bool inDeclarationContext() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    AstNode parent = this.parent;
-    if (parent is CatchClause) {
-      CatchClause clause = parent;
-      return identical(this, clause.exceptionParameter) ||
-          identical(this, clause.stackTraceParameter);
-    } else if (parent is ClassDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is ClassTypeAlias) {
-      return identical(this, parent.name);
-    } else if (parent is ConstructorDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is DeclaredIdentifier) {
-      return identical(this, parent.identifier);
-    } else if (parent is EnumDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is EnumConstantDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is FunctionDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is FunctionTypeAlias) {
-      return identical(this, parent.name);
-    } else if (parent is ImportDirective) {
-      return identical(this, parent.prefix);
-    } else if (parent is Label) {
-      return identical(this, parent.label) &&
-          (parent.parent is LabeledStatement);
-    } else if (parent is MethodDeclaration) {
-      return identical(this, parent.name);
-    } else if (parent is FunctionTypedFormalParameter ||
-        parent is SimpleFormalParameter) {
-      return identical(this, (parent as NormalFormalParameter).identifier);
-    } else if (parent is TypeParameter) {
-      return identical(this, parent.name);
-    } else if (parent is VariableDeclaration) {
-      return identical(this, parent.name);
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if this expression is computing a right-hand value.
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
-  bool inGetterContext() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    AstNode parent = this.parent;
-    AstNode target = this;
-    // skip prefix
-    if (parent is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
-      if (identical(prefixed.prefix, this)) {
-        return true;
-      }
-      parent = prefixed.parent;
-      target = prefixed;
-    } else if (parent is PropertyAccess) {
-      PropertyAccess access = parent as PropertyAccess;
-      if (identical(access.target, this)) {
-        return true;
-      }
-      parent = access.parent;
-      target = access;
-    }
-    // skip label
-    if (parent is Label) {
-      return false;
-    }
-    // analyze usage
-    if (parent is AssignmentExpression) {
-      if (identical(parent.leftHandSide, target) &&
-          parent.operator.type == TokenType.EQ) {
-        return false;
-      }
-    }
-    if (parent is ForEachStatement) {
-      if (identical(parent.identifier, target)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Return `true` if this expression is computing a left-hand value.
-   *
-   * Note that [inGetterContext] and [inSetterContext] are not opposites, nor
-   * are they mutually exclusive. In other words, it is possible for both
-   * methods to return `true` when invoked on the same node.
-   */
-  bool inSetterContext() {
-    // TODO(brianwilkerson) Convert this to a getter.
-    AstNode parent = this.parent;
-    AstNode target = this;
-    // skip prefix
-    if (parent is PrefixedIdentifier) {
-      PrefixedIdentifier prefixed = parent as PrefixedIdentifier;
-      // if this is the prefix, then return false
-      if (identical(prefixed.prefix, this)) {
-        return false;
-      }
-      parent = prefixed.parent;
-      target = prefixed;
-    } else if (parent is PropertyAccess) {
-      PropertyAccess access = parent as PropertyAccess;
-      if (identical(access.target, this)) {
-        return false;
-      }
-      parent = access.parent;
-      target = access;
-    }
-    // analyze usage
-    if (parent is PrefixExpression) {
-      return parent.operator.type.isIncrementOperator;
-    } else if (parent is PostfixExpression) {
-      return true;
-    } else if (parent is AssignmentExpression) {
-      return identical(parent.leftHandSide, target);
-    } else if (parent is ForEachStatement) {
-      return identical(parent.identifier, target);
-    }
-    return false;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-
-  /**
-   * Return the given element if it is valid, or report the problem and return
-   * `null` if it is not appropriate.
-   *
-   * The [parent] is the parent of the element, used for reporting when there is
-   * a problem.
-   * The [isValid] is `true` if the element is appropriate.
-   * The [element] is the element to be associated with this identifier.
-   */
-  Element _returnOrReportElement(
-      AstNode parent, bool isValid, Element element) {
-    if (!isValid) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Internal error: attempting to set the name of a ${parent.runtimeType} to a ${element.runtimeType}",
-          new CaughtException(new AnalysisException(), null));
-      return null;
-    }
-    return element;
-  }
-
-  /**
-   * Return the given [element] if it is an appropriate element based on the
-   * parent of this identifier, or `null` if it is not appropriate.
-   */
-  Element _validateElement(Element element) {
-    if (element == null) {
-      return null;
-    }
-    AstNode parent = this.parent;
-    if (parent is ClassDeclaration && identical(parent.name, this)) {
-      return _returnOrReportElement(parent, element is ClassElement, element);
-    } else if (parent is ClassTypeAlias && identical(parent.name, this)) {
-      return _returnOrReportElement(parent, element is ClassElement, element);
-    } else if (parent is DeclaredIdentifier &&
-        identical(parent.identifier, this)) {
-      return _returnOrReportElement(
-          parent, element is LocalVariableElement, element);
-    } else if (parent is FormalParameter &&
-        identical(parent.identifier, this)) {
-      return _returnOrReportElement(
-          parent, element is ParameterElement, element);
-    } else if (parent is FunctionDeclaration && identical(parent.name, this)) {
-      return _returnOrReportElement(
-          parent, element is ExecutableElement, element);
-    } else if (parent is FunctionTypeAlias && identical(parent.name, this)) {
-      return _returnOrReportElement(
-          parent, element is FunctionTypeAliasElement, element);
-    } else if (parent is MethodDeclaration && identical(parent.name, this)) {
-      return _returnOrReportElement(
-          parent, element is ExecutableElement, element);
-    } else if (parent is TypeParameter && identical(parent.name, this)) {
-      return _returnOrReportElement(
-          parent, element is TypeParameterElement, element);
-    } else if (parent is VariableDeclaration && identical(parent.name, this)) {
-      return _returnOrReportElement(
-          parent, element is VariableElement, element);
-    }
-    return element;
-  }
-}
-
-/**
- * A string literal expression that does not contain any interpolations.
- *
- * > simpleStringLiteral ::=
- * >     rawStringLiteral
- * >   | basicStringLiteral
- * >
- * > rawStringLiteral ::=
- * >     'r' basicStringLiteral
- * >
- * > simpleStringLiteral ::=
- * >     multiLineStringLiteral
- * >   | singleLineStringLiteral
- * >
- * > multiLineStringLiteral ::=
- * >     "'''" characters "'''"
- * >   | '"""' characters '"""'
- * >
- * > singleLineStringLiteral ::=
- * >     "'" characters "'"
- * >   | '"' characters '"'
- */
-class SimpleStringLiteral extends SingleStringLiteral {
-  /**
-   * The token representing the literal.
-   */
-  Token literal;
-
-  /**
-   * The value of the literal.
-   */
-  String _value;
-
-  /**
-   * Initialize a newly created simple string literal.
-   */
-  SimpleStringLiteral(this.literal, String value) {
-    _value = StringUtilities.intern(value);
-  }
-
-  @override
-  Token get beginToken => literal;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(literal);
-
-  @override
-  int get contentsEnd => offset + _helper.end;
-
-  @override
-  int get contentsOffset => offset + _helper.start;
-
-  @override
-  Token get endToken => literal;
-
-  @override
-  bool get isMultiline => _helper.isMultiline;
-
-  @override
-  bool get isRaw => _helper.isRaw;
-
-  @override
-  bool get isSingleQuoted => _helper.isSingleQuoted;
-
-  @override
-  bool get isSynthetic => literal.isSynthetic;
-
-  /**
-   * Return the value of the literal.
-   */
-  String get value => _value;
-
-  /**
-   * Set the value of the literal to the given [string].
-   */
-  void set value(String string) {
-    _value = StringUtilities.intern(_value);
-  }
-
-  StringLexemeHelper get _helper {
-    return new StringLexemeHelper(literal.lexeme, true, true);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSimpleStringLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-
-  @override
-  void _appendStringValue(StringBuffer buffer) {
-    buffer.write(value);
-  }
-}
-
-/**
- * A single string literal expression.
- *
- * > singleStringLiteral ::=
- * >     [SimpleStringLiteral]
- * >   | [StringInterpolation]
- */
-abstract class SingleStringLiteral extends StringLiteral {
-  /**
-   * Return the offset of the after-last contents character.
-   */
-  int get contentsEnd;
-
-  /**
-   * Return the offset of the first contents character.
-   * If the string is multiline, then leading whitespaces are skipped.
-   */
-  int get contentsOffset;
-
-  /**
-   * Return `true` if this string literal is a multi-line string.
-   */
-  bool get isMultiline;
-
-  /**
-   * Return `true` if this string literal is a raw string.
-   */
-  bool get isRaw;
-
-  /**
-   * Return `true` if this string literal uses single quotes (' or ''').
-   * Return `false` if this string literal uses double quotes (" or """).
-   */
-  bool get isSingleQuoted;
-}
-
-/**
- * A node that represents a statement.
- *
- * > statement ::=
- * >     [Block]
- * >   | [VariableDeclarationStatement]
- * >   | [ForStatement]
- * >   | [ForEachStatement]
- * >   | [WhileStatement]
- * >   | [DoStatement]
- * >   | [SwitchStatement]
- * >   | [IfStatement]
- * >   | [TryStatement]
- * >   | [BreakStatement]
- * >   | [ContinueStatement]
- * >   | [ReturnStatement]
- * >   | [ExpressionStatement]
- * >   | [FunctionDeclarationStatement]
- */
-abstract class Statement extends AstNode {
-  /**
-   * If this is a labeled statement, return the unlabeled portion of the
-   * statement.  Otherwise return the statement itself.
-   */
-  Statement get unlabeled => this;
-}
-
-/**
- * A string interpolation literal.
- *
- * > stringInterpolation ::=
- * >     ''' [InterpolationElement]* '''
- * >   | '"' [InterpolationElement]* '"'
- */
-class StringInterpolation extends SingleStringLiteral {
-  /**
-   * The elements that will be composed to produce the resulting string.
-   */
-  NodeList<InterpolationElement> _elements;
-
-  /**
-   * Initialize a newly created string interpolation expression.
-   */
-  StringInterpolation(List<InterpolationElement> elements) {
-    _elements = new NodeList<InterpolationElement>(this, elements);
-  }
-
-  @override
-  Token get beginToken => _elements.beginToken;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..addAll(_elements);
-
-  @override
-  int get contentsEnd {
-    InterpolationString element = _elements.last;
-    return element.contentsEnd;
-  }
-
-  @override
-  int get contentsOffset {
-    InterpolationString element = _elements.first;
-    return element.contentsOffset;
-  }
-
-  /**
-   * Return the elements that will be composed to produce the resulting string.
-   */
-  NodeList<InterpolationElement> get elements => _elements;
-
-  @override
-  Token get endToken => _elements.endToken;
-
-  @override
-  bool get isMultiline => _firstHelper.isMultiline;
-
-  @override
-  bool get isRaw => false;
-
-  @override
-  bool get isSingleQuoted => _firstHelper.isSingleQuoted;
-
-  StringLexemeHelper get _firstHelper {
-    InterpolationString lastString = _elements.first;
-    String lexeme = lastString.contents.lexeme;
-    return new StringLexemeHelper(lexeme, true, false);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitStringInterpolation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _elements.accept(visitor);
-  }
-
-  @override
-  void _appendStringValue(StringBuffer buffer) {
-    throw new IllegalArgumentException();
-  }
-}
-
-/**
- * A helper for analyzing string lexemes.
- */
-class StringLexemeHelper {
-  final String lexeme;
-  final bool isFirst;
-  final bool isLast;
-
-  bool isRaw = false;
-  bool isSingleQuoted = false;
-  bool isMultiline = false;
-  int start = 0;
-  int end;
-
-  StringLexemeHelper(this.lexeme, this.isFirst, this.isLast) {
-    if (isFirst) {
-      isRaw = StringUtilities.startsWithChar(lexeme, 0x72);
-      if (isRaw) {
-        start++;
-      }
-      if (StringUtilities.startsWith3(lexeme, start, 0x27, 0x27, 0x27)) {
-        isSingleQuoted = true;
-        isMultiline = true;
-        start += 3;
-        start = _trimInitialWhitespace(start);
-      } else if (StringUtilities.startsWith3(lexeme, start, 0x22, 0x22, 0x22)) {
-        isSingleQuoted = false;
-        isMultiline = true;
-        start += 3;
-        start = _trimInitialWhitespace(start);
-      } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x27) {
-        isSingleQuoted = true;
-        isMultiline = false;
-        start++;
-      } else if (start < lexeme.length && lexeme.codeUnitAt(start) == 0x22) {
-        isSingleQuoted = false;
-        isMultiline = false;
-        start++;
-      }
-    }
-    end = lexeme.length;
-    if (isLast) {
-      if (start + 3 <= end &&
-          (StringUtilities.endsWith3(lexeme, 0x22, 0x22, 0x22) ||
-              StringUtilities.endsWith3(lexeme, 0x27, 0x27, 0x27))) {
-        end -= 3;
-      } else if (start + 1 <= end &&
-          (StringUtilities.endsWithChar(lexeme, 0x22) ||
-              StringUtilities.endsWithChar(lexeme, 0x27))) {
-        end -= 1;
-      }
-    }
-  }
-
-  /**
-   * Given the [lexeme] for a multi-line string whose content begins at the
-   * given [start] index, return the index of the first character that is
-   * included in the value of the string. According to the specification:
-   *
-   * If the first line of a multiline string consists solely of the whitespace
-   * characters defined by the production WHITESPACE 20.1), possibly prefixed
-   * by \, then that line is ignored, including the new line at its end.
-   */
-  int _trimInitialWhitespace(int start) {
-    int length = lexeme.length;
-    int index = start;
-    while (index < length) {
-      int currentChar = lexeme.codeUnitAt(index);
-      if (currentChar == 0x0D) {
-        if (index + 1 < length && lexeme.codeUnitAt(index + 1) == 0x0A) {
-          return index + 2;
-        }
-        return index + 1;
-      } else if (currentChar == 0x0A) {
-        return index + 1;
-      } else if (currentChar == 0x5C) {
-        if (index + 1 >= length) {
-          return start;
-        }
-        currentChar = lexeme.codeUnitAt(index + 1);
-        if (currentChar != 0x0D &&
-            currentChar != 0x0A &&
-            currentChar != 0x09 &&
-            currentChar != 0x20) {
-          return start;
-        }
-      } else if (currentChar != 0x09 && currentChar != 0x20) {
-        return start;
-      }
-      index++;
-    }
-    return start;
-  }
-}
-
-/**
- * A string literal expression.
- *
- * > stringLiteral ::=
- * >     [SimpleStringLiteral]
- * >   | [AdjacentStrings]
- * >   | [StringInterpolation]
- */
-abstract class StringLiteral extends Literal {
-  /**
-   * Return the value of the string literal, or `null` if the string is not a
-   * constant string without any string interpolation.
-   */
-  String get stringValue {
-    StringBuffer buffer = new StringBuffer();
-    try {
-      _appendStringValue(buffer);
-    } on IllegalArgumentException {
-      return null;
-    }
-    return buffer.toString();
-  }
-
-  /**
-   * Append the value of this string literal to the given [buffer]. Throw an
-   * [IllegalArgumentException] if the string is not a constant string without
-   * any string interpolation.
-   */
-  void _appendStringValue(StringBuffer buffer);
-}
-
-/**
- * The invocation of a superclass' constructor from within a constructor's
- * initialization list.
- *
- * > superInvocation ::=
- * >     'super' ('.' [SimpleIdentifier])? [ArgumentList]
- */
-class SuperConstructorInvocation extends ConstructorInitializer {
-  /**
-   * The token for the 'super' keyword.
-   */
-  Token superKeyword;
-
-  /**
-   * The token for the period before the name of the constructor that is being
-   * invoked, or `null` if the unnamed constructor is being invoked.
-   */
-  Token period;
-
-  /**
-   * The name of the constructor that is being invoked, or `null` if the unnamed
-   * constructor is being invoked.
-   */
-  SimpleIdentifier _constructorName;
-
-  /**
-   * The list of arguments to the constructor.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The element associated with the constructor based on static type
-   * information, or `null` if the AST structure has not been resolved or if the
-   * constructor could not be resolved.
-   */
-  ConstructorElement staticElement;
-
-  /**
-   * Initialize a newly created super invocation to invoke the inherited
-   * constructor with the given name with the given arguments. The [period] and
-   * [constructorName] can be `null` if the constructor being invoked is the
-   * unnamed constructor.
-   */
-  SuperConstructorInvocation(this.superKeyword, this.period,
-      SimpleIdentifier constructorName, ArgumentList argumentList) {
-    _constructorName = _becomeParentOf(constructorName);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  /**
-   * Return the list of arguments to the constructor.
-   */
-  ArgumentList get argumentList => _argumentList;
-
-  /**
-   * Set the list of arguments to the constructor to the given [argumentList].
-   */
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  Token get beginToken => superKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(superKeyword)
-    ..add(period)
-    ..add(_constructorName)
-    ..add(_argumentList);
-
-  /**
-   * Return the name of the constructor that is being invoked, or `null` if the
-   * unnamed constructor is being invoked.
-   */
-  SimpleIdentifier get constructorName => _constructorName;
-
-  /**
-   * Set the name of the constructor that is being invoked to the given
-   * [identifier].
-   */
-  void set constructorName(SimpleIdentifier identifier) {
-    _constructorName = _becomeParentOf(identifier);
-  }
-
-  @override
-  Token get endToken => _argumentList.endToken;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_constructorName, visitor);
-    _safelyVisitChild(_argumentList, visitor);
-  }
-}
-
-/**
- * A super expression.
- *
- * > superExpression ::=
- * >     'super'
- */
-class SuperExpression extends Expression {
-  /**
-   * The token representing the 'super' keyword.
-   */
-  Token superKeyword;
-
-  /**
-   * Initialize a newly created super expression.
-   */
-  SuperExpression(this.superKeyword);
-
-  @override
-  Token get beginToken => superKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(superKeyword);
-
-  @override
-  Token get endToken => superKeyword;
-
-  @override
-  int get precedence => 16;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSuperExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A case in a switch statement.
- *
- * > switchCase ::=
- * >     [SimpleIdentifier]* 'case' [Expression] ':' [Statement]*
- */
-class SwitchCase extends SwitchMember {
-  /**
-   * The expression controlling whether the statements will be executed.
-   */
-  Expression _expression;
-
-  /**
-   * Initialize a newly created switch case. The list of [labels] can be `null`
-   * if there are no labels.
-   */
-  SwitchCase(List<Label> labels, Token keyword, Expression expression,
-      Token colon, List<Statement> statements)
-      : super(labels, keyword, colon, statements) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..addAll(labels)
-    ..add(keyword)
-    ..add(_expression)
-    ..add(colon)
-    ..addAll(statements);
-
-  /**
-   * Return the expression controlling whether the statements will be executed.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression controlling whether the statements will be executed to
-   * the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSwitchCase(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    labels.accept(visitor);
-    _safelyVisitChild(_expression, visitor);
-    statements.accept(visitor);
-  }
-}
-
-/**
- * The default case in a switch statement.
- *
- * > switchDefault ::=
- * >     [SimpleIdentifier]* 'default' ':' [Statement]*
- */
-class SwitchDefault extends SwitchMember {
-  /**
-   * Initialize a newly created switch default. The list of [labels] can be
-   * `null` if there are no labels.
-   */
-  SwitchDefault(List<Label> labels, Token keyword, Token colon,
-      List<Statement> statements)
-      : super(labels, keyword, colon, statements);
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..addAll(labels)
-    ..add(keyword)
-    ..add(colon)
-    ..addAll(statements);
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSwitchDefault(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    labels.accept(visitor);
-    statements.accept(visitor);
-  }
-}
-
-/**
- * An element within a switch statement.
- *
- * > switchMember ::=
- * >     switchCase
- * >   | switchDefault
- */
-abstract class SwitchMember extends AstNode {
-  /**
-   * The labels associated with the switch member.
-   */
-  NodeList<Label> _labels;
-
-  /**
-   * The token representing the 'case' or 'default' keyword.
-   */
-  Token keyword;
-
-  /**
-   * The colon separating the keyword or the expression from the statements.
-   */
-  Token colon;
-
-  /**
-   * The statements that will be executed if this switch member is selected.
-   */
-  NodeList<Statement> _statements;
-
-  /**
-   * Initialize a newly created switch member. The list of [labels] can be
-   * `null` if there are no labels.
-   */
-  SwitchMember(List<Label> labels, this.keyword, this.colon,
-      List<Statement> statements) {
-    _labels = new NodeList<Label>(this, labels);
-    _statements = new NodeList<Statement>(this, statements);
-  }
-
-  @override
-  Token get beginToken {
-    if (!_labels.isEmpty) {
-      return _labels.beginToken;
-    }
-    return keyword;
-  }
-
-  @override
-  Token get endToken {
-    if (!_statements.isEmpty) {
-      return _statements.endToken;
-    }
-    return colon;
-  }
-
-  /**
-   * Return the labels associated with the switch member.
-   */
-  NodeList<Label> get labels => _labels;
-
-  /**
-   * Return the statements that will be executed if this switch member is
-   * selected.
-   */
-  NodeList<Statement> get statements => _statements;
-}
-
-/**
- * A switch statement.
- *
- * > switchStatement ::=
- * >     'switch' '(' [Expression] ')' '{' [SwitchCase]* [SwitchDefault]? '}'
- */
-class SwitchStatement extends Statement {
-  /**
-   * The token representing the 'switch' keyword.
-   */
-  Token switchKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The expression used to determine which of the switch members will be
-   * selected.
-   */
-  Expression _expression;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The left curly bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The switch members that can be selected by the expression.
-   */
-  NodeList<SwitchMember> _members;
-
-  /**
-   * The right curly bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created switch statement. The list of [members] can be
-   * `null` if there are no switch members.
-   */
-  SwitchStatement(
-      this.switchKeyword,
-      this.leftParenthesis,
-      Expression expression,
-      this.rightParenthesis,
-      this.leftBracket,
-      List<SwitchMember> members,
-      this.rightBracket) {
-    _expression = _becomeParentOf(expression);
-    _members = new NodeList<SwitchMember>(this, members);
-  }
-
-  @override
-  Token get beginToken => switchKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(switchKeyword)
-    ..add(leftParenthesis)
-    ..add(_expression)
-    ..add(rightParenthesis)
-    ..add(leftBracket)
-    ..addAll(_members)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the expression used to determine which of the switch members will be
-   * selected.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression used to determine which of the switch members will be
-   * selected to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return the switch members that can be selected by the expression.
-   */
-  NodeList<SwitchMember> get members => _members;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSwitchStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-    _members.accept(visitor);
-  }
-}
-
-/**
- * A symbol literal expression.
- *
- * > symbolLiteral ::=
- * >     '#' (operator | (identifier ('.' identifier)*))
- */
-class SymbolLiteral extends Literal {
-  /**
-   * The token introducing the literal.
-   */
-  Token poundSign;
-
-  /**
-   * The components of the literal.
-   */
-  final List<Token> components;
-
-  /**
-   * Initialize a newly created symbol literal.
-   */
-  SymbolLiteral(this.poundSign, this.components);
-
-  @override
-  Token get beginToken => poundSign;
-
-  @override
-  // TODO(paulberry): add "." tokens.
-  Iterable get childEntities => new ChildEntities()
-    ..add(poundSign)
-    ..addAll(components);
-
-  @override
-  Token get endToken => components[components.length - 1];
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitSymbolLiteral(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A this expression.
- *
- * > thisExpression ::=
- * >     'this'
- */
-class ThisExpression extends Expression {
-  /**
-   * The token representing the 'this' keyword.
-   */
-  Token thisKeyword;
-
-  /**
-   * Initialize a newly created this expression.
-   */
-  ThisExpression(this.thisKeyword);
-
-  @override
-  Token get beginToken => thisKeyword;
-
-  @override
-  Iterable get childEntities => new ChildEntities()..add(thisKeyword);
-
-  @override
-  Token get endToken => thisKeyword;
-
-  @override
-  int get precedence => 16;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitThisExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    // There are no children to visit.
-  }
-}
-
-/**
- * A throw expression.
- *
- * > throwExpression ::=
- * >     'throw' [Expression]
- */
-class ThrowExpression extends Expression {
-  /**
-   * The token representing the 'throw' keyword.
-   */
-  Token throwKeyword;
-
-  /**
-   * The expression computing the exception to be thrown.
-   */
-  Expression _expression;
-
-  /**
-   * Initialize a newly created throw expression.
-   */
-  ThrowExpression(this.throwKeyword, Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken => throwKeyword;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(throwKeyword)..add(_expression);
-
-  @override
-  Token get endToken {
-    if (_expression != null) {
-      return _expression.endToken;
-    }
-    return throwKeyword;
-  }
-
-  /**
-   * Return the expression computing the exception to be thrown.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression computing the exception to be thrown to the given
-   * [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  int get precedence => 0;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitThrowExpression(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
-
-/**
- * The declaration of one or more top-level variables of the same type.
- *
- * > topLevelVariableDeclaration ::=
- * >     ('final' | 'const') type? staticFinalDeclarationList ';'
- * >   | variableDeclaration ';'
- */
-class TopLevelVariableDeclaration extends CompilationUnitMember {
-  /**
-   * The top-level variables being declared.
-   */
-  VariableDeclarationList _variableList;
-
-  /**
-   * The semicolon terminating the declaration.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created top-level variable declaration. Either or both
-   * of the [comment] and [metadata] can be `null` if the variable does not have
-   * the corresponding attribute.
-   */
-  TopLevelVariableDeclaration(Comment comment, List<Annotation> metadata,
-      VariableDeclarationList variableList, this.semicolon)
-      : super(comment, metadata) {
-    _variableList = _becomeParentOf(variableList);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(_variableList)..add(semicolon);
-
-  @override
-  Element get element => null;
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => _variableList.beginToken;
-
-  /**
-   * Return the top-level variables being declared.
-   */
-  VariableDeclarationList get variables => _variableList;
-
-  /**
-   * Set the top-level variables being declared to the given list of
-   * [variables].
-   */
-  void set variables(VariableDeclarationList variables) {
-    _variableList = _becomeParentOf(variables);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTopLevelVariableDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_variableList, visitor);
-  }
-}
-
-/**
- * A try statement.
- *
- * > tryStatement ::=
- * >     'try' [Block] ([CatchClause]+ finallyClause? | finallyClause)
- * >
- * > finallyClause ::=
- * >     'finally' [Block]
- */
-class TryStatement extends Statement {
-  /**
-   * The token representing the 'try' keyword.
-   */
-  Token tryKeyword;
-
-  /**
-   * The body of the statement.
-   */
-  Block _body;
-
-  /**
-   * The catch clauses contained in the try statement.
-   */
-  NodeList<CatchClause> _catchClauses;
-
-  /**
-   * The token representing the 'finally' keyword, or `null` if the statement
-   * does not contain a finally clause.
-   */
-  Token finallyKeyword;
-
-  /**
-   * The finally block contained in the try statement, or `null` if the
-   * statement does not contain a finally clause.
-   */
-  Block _finallyBlock;
-
-  /**
-   * Initialize a newly created try statement. The list of [catchClauses] can be
-   * `null` if there are no catch clauses. The [finallyKeyword] and
-   * [finallyBlock] can be `null` if there is no finally clause.
-   */
-  TryStatement(this.tryKeyword, Block body, List<CatchClause> catchClauses,
-      this.finallyKeyword, Block finallyBlock) {
-    _body = _becomeParentOf(body);
-    _catchClauses = new NodeList<CatchClause>(this, catchClauses);
-    _finallyBlock = _becomeParentOf(finallyBlock);
-  }
-
-  @override
-  Token get beginToken => tryKeyword;
-
-  /**
-   * Return the body of the statement.
-   */
-  Block get body => _body;
-
-  /**
-   * Set the body of the statement to the given [block].
-   */
-  void set body(Block block) {
-    _body = _becomeParentOf(block);
-  }
-
-  /**
-   * Return the catch clauses contained in the try statement.
-   */
-  NodeList<CatchClause> get catchClauses => _catchClauses;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(tryKeyword)
-    ..add(_body)
-    ..addAll(_catchClauses)
-    ..add(finallyKeyword)
-    ..add(_finallyBlock);
-
-  @override
-  Token get endToken {
-    if (_finallyBlock != null) {
-      return _finallyBlock.endToken;
-    } else if (finallyKeyword != null) {
-      return finallyKeyword;
-    } else if (!_catchClauses.isEmpty) {
-      return _catchClauses.endToken;
-    }
-    return _body.endToken;
-  }
-
-  /**
-   * Return the finally block contained in the try statement, or `null` if the
-   * statement does not contain a finally clause.
-   */
-  Block get finallyBlock => _finallyBlock;
-
-  /**
-   * Set the finally block contained in the try statement to the given [block].
-   */
-  void set finallyBlock(Block block) {
-    _finallyBlock = _becomeParentOf(block);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTryStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_body, visitor);
-    _catchClauses.accept(visitor);
-    _safelyVisitChild(_finallyBlock, visitor);
-  }
-}
-
-/**
- * The declaration of a type alias.
- *
- * > typeAlias ::=
- * >     'typedef' typeAliasBody
- * >
- * > typeAliasBody ::=
- * >     classTypeAlias
- * >   | functionTypeAlias
- */
-abstract class TypeAlias extends NamedCompilationUnitMember {
-  /**
-   * The token representing the 'typedef' keyword.
-   */
-  Token typedefKeyword;
-
-  /**
-   * The semicolon terminating the declaration.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created type alias. Either or both of the [comment] and
-   * [metadata] can be `null` if the declaration does not have the corresponding
-   * attribute.
-   */
-  TypeAlias(Comment comment, List<Annotation> metadata, this.typedefKeyword,
-      SimpleIdentifier name, this.semicolon)
-      : super(comment, metadata, name);
-
-  @override
-  Token get endToken => semicolon;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
-}
-
-/**
- * A list of type arguments.
- *
- * > typeArguments ::=
- * >     '<' typeName (',' typeName)* '>'
- */
-class TypeArgumentList extends AstNode {
-  /**
-   * The left bracket.
-   */
-  Token leftBracket;
-
-  /**
-   * The type arguments associated with the type.
-   */
-  NodeList<TypeName> _arguments;
-
-  /**
-   * The right bracket.
-   */
-  Token rightBracket;
-
-  /**
-   * Initialize a newly created list of type arguments.
-   */
-  TypeArgumentList(
-      this.leftBracket, List<TypeName> arguments, this.rightBracket) {
-    _arguments = new NodeList<TypeName>(this, arguments);
-  }
-
-  /**
-   * Return the type arguments associated with the type.
-   */
-  NodeList<TypeName> get arguments => _arguments;
-
-  @override
-  Token get beginToken => leftBracket;
-
-  @override
-  // TODO(paulberry): Add commas.
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftBracket)
-    ..addAll(_arguments)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTypeArgumentList(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _arguments.accept(visitor);
-  }
-}
-
-/**
- * A literal that has a type associated with it.
- *
- * > typedLiteral ::=
- * >     [ListLiteral]
- * >   | [MapLiteral]
- */
-abstract class TypedLiteral extends Literal {
-  /**
-   * The token representing the 'const' keyword, or `null` if the literal is not
-   * a constant.
-   */
-  Token constKeyword;
-
-  /**
-   * The type argument associated with this literal, or `null` if no type
-   * arguments were declared.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * Initialize a newly created typed literal. The [constKeyword] can be `null`\
-   * if the literal is not a constant. The [typeArguments] can be `null` if no
-   * type arguments were declared.
-   */
-  TypedLiteral(this.constKeyword, TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  /**
-   * Return the type argument associated with this literal, or `null` if no type
-   * arguments were declared.
-   */
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  /**
-   * Set the type argument associated with this literal to the given
-   * [typeArguments].
-   */
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  ChildEntities get _childEntities =>
-      new ChildEntities()..add(constKeyword)..add(_typeArguments);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_typeArguments, visitor);
-  }
-}
-
-/**
- * The name of a type, which can optionally include type arguments.
- *
- * > typeName ::=
- * >     [Identifier] typeArguments?
- */
-class TypeName extends AstNode {
-  /**
-   * The name of the type.
-   */
-  Identifier _name;
-
-  /**
-   * The type arguments associated with the type, or `null` if there are no type
-   * arguments.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * The type being named, or `null` if the AST structure has not been resolved.
-   */
-  DartType type;
-
-  /**
-   * Initialize a newly created type name. The [typeArguments] can be `null` if
-   * there are no type arguments.
-   */
-  TypeName(Identifier name, TypeArgumentList typeArguments) {
-    _name = _becomeParentOf(name);
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
-  Token get beginToken => _name.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_name)..add(_typeArguments);
-
-  @override
-  Token get endToken {
-    if (_typeArguments != null) {
-      return _typeArguments.endToken;
-    }
-    return _name.endToken;
-  }
-
-  /**
-   * Return `true` if this type is a deferred type.
-   *
-   * 15.1 Static Types: A type <i>T</i> is deferred iff it is of the form
-   * </i>p.T</i> where <i>p</i> is a deferred prefix.
-   */
-  bool get isDeferred {
-    Identifier identifier = name;
-    if (identifier is! PrefixedIdentifier) {
-      return false;
-    }
-    return (identifier as PrefixedIdentifier).isDeferred;
-  }
-
-  @override
-  bool get isSynthetic => _name.isSynthetic && _typeArguments == null;
-
-  /**
-   * Return the name of the type.
-   */
-  Identifier get name => _name;
-
-  /**
-   * Set the name of the type to the given [identifier].
-   */
-  void set name(Identifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  /**
-   * Return the type arguments associated with the type, or `null` if there are
-   * no type arguments.
-   */
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  /**
-   * Set the type arguments associated with the type to the given
-   * [typeArguments].
-   */
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTypeName(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_typeArguments, visitor);
-  }
-}
-
-/**
- * A type parameter.
- *
- * > typeParameter ::=
- * >     [SimpleIdentifier] ('extends' [TypeName])?
- */
-class TypeParameter extends Declaration {
-  /**
-   * The name of the type parameter.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * The token representing the 'extends' keyword, or `null` if there is no
-   * explicit upper bound.
-   */
-  Token extendsKeyword;
-
-  /**
-   * The name of the upper bound for legal arguments, or `null` if there is no
-   * explicit upper bound.
-   */
-  TypeName _bound;
-
-  /**
-   * Initialize a newly created type parameter. Either or both of the [comment]
-   * and [metadata] can be `null` if the parameter does not have the
-   * corresponding attribute. The [extendsKeyword] and [bound] can be `null` if
-   * the parameter does not have an upper bound.
-   */
-  TypeParameter(Comment comment, List<Annotation> metadata,
-      SimpleIdentifier name, this.extendsKeyword, TypeName bound)
-      : super(comment, metadata) {
-    _name = _becomeParentOf(name);
-    _bound = _becomeParentOf(bound);
-  }
-
-  /**
-   * Return the name of the upper bound for legal arguments, or `null` if there
-   * is no explicit upper bound.
-   */
-  TypeName get bound => _bound;
-
-  /**
-   * Set the name of the upper bound for legal arguments to the given
-   * [typeName].
-   */
-  void set bound(TypeName typeName) {
-    _bound = _becomeParentOf(typeName);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(_name)..add(extendsKeyword)..add(_bound);
-
-  @override
-  TypeParameterElement get element =>
-      _name != null ? (_name.staticElement as TypeParameterElement) : null;
-
-  @override
-  Token get endToken {
-    if (_bound == null) {
-      return _name.endToken;
-    }
-    return _bound.endToken;
-  }
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
-
-  /**
-   * Return the name of the type parameter.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the type parameter to the given [identifier].
-   */
-  void set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTypeParameter(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_bound, visitor);
-  }
-}
-
-/**
- * Type parameters within a declaration.
- *
- * > typeParameterList ::=
- * >     '<' [TypeParameter] (',' [TypeParameter])* '>'
- */
-class TypeParameterList extends AstNode {
-  /**
-   * The left angle bracket.
-   */
-  final Token leftBracket;
-
-  /**
-   * The type parameters in the list.
-   */
-  NodeList<TypeParameter> _typeParameters;
-
-  /**
-   * The right angle bracket.
-   */
-  final Token rightBracket;
-
-  /**
-   * Initialize a newly created list of type parameters.
-   */
-  TypeParameterList(
-      this.leftBracket, List<TypeParameter> typeParameters, this.rightBracket) {
-    _typeParameters = new NodeList<TypeParameter>(this, typeParameters);
-  }
-
-  @override
-  Token get beginToken => leftBracket;
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(leftBracket)
-    ..addAll(_typeParameters)
-    ..add(rightBracket);
-
-  @override
-  Token get endToken => rightBracket;
-
-  /**
-   * Return the type parameters for the type.
-   */
-  NodeList<TypeParameter> get typeParameters => _typeParameters;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitTypeParameterList(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _typeParameters.accept(visitor);
-  }
-}
-
-/**
- * A directive that references a URI.
- *
- * > uriBasedDirective ::=
- * >     [ExportDirective]
- * >   | [ImportDirective]
- * >   | [PartDirective]
- */
-abstract class UriBasedDirective extends Directive {
-  /**
-   * The prefix of a URI using the `dart-ext` scheme to reference a native code
-   * library.
-   */
-  static String _DART_EXT_SCHEME = "dart-ext:";
-
-  /**
-   * The URI referenced by this directive.
-   */
-  StringLiteral _uri;
-
-  /**
-   * The content of the URI.
-   */
-  String uriContent;
-
-  /**
-   * The source to which the URI was resolved.
-   */
-  Source source;
-
-  /**
-   * Initialize a newly create URI-based directive. Either or both of the
-   * [comment] and [metadata] can be `null` if the directive does not have the
-   * corresponding attribute.
-   */
-  UriBasedDirective(
-      Comment comment, List<Annotation> metadata, StringLiteral uri)
-      : super(comment, metadata) {
-    _uri = _becomeParentOf(uri);
-  }
-
-  /**
-   * Return the URI referenced by this directive.
-   */
-  StringLiteral get uri => _uri;
-
-  /**
-   * Set the URI referenced by this directive to the given [uri].
-   */
-  void set uri(StringLiteral uri) {
-    _uri = _becomeParentOf(uri);
-  }
-
-  /**
-   * Return the element associated with the URI of this directive, or `null` if
-   * the AST structure has not been resolved or if the URI could not be
-   * resolved. Examples of the latter case include a directive that contains an
-   * invalid URL or a URL that does not exist.
-   */
-  Element get uriElement;
-
-  /**
-   * Validate this directive, but do not check for existence. Return a code
-   * indicating the problem if there is one, or `null` no problem
-   */
-  UriValidationCode validate() {
-    StringLiteral uriLiteral = uri;
-    if (uriLiteral is StringInterpolation) {
-      return UriValidationCode.URI_WITH_INTERPOLATION;
-    }
-    String uriContent = this.uriContent;
-    if (uriContent == null) {
-      return UriValidationCode.INVALID_URI;
-    }
-    if (this is ImportDirective && uriContent.startsWith(_DART_EXT_SCHEME)) {
-      return UriValidationCode.URI_WITH_DART_EXT_SCHEME;
-    }
-    try {
-      parseUriWithException(Uri.encodeFull(uriContent));
-    } on URISyntaxException {
-      return UriValidationCode.INVALID_URI;
-    }
-    return null;
-  }
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_uri, visitor);
-  }
-}
-
-/**
- * Validation codes returned by [UriBasedDirective.validate].
- */
-class UriValidationCode {
-  static const UriValidationCode INVALID_URI =
-      const UriValidationCode('INVALID_URI');
-
-  static const UriValidationCode URI_WITH_INTERPOLATION =
-      const UriValidationCode('URI_WITH_INTERPOLATION');
-
-  static const UriValidationCode URI_WITH_DART_EXT_SCHEME =
-      const UriValidationCode('URI_WITH_DART_EXT_SCHEME');
-
-  /**
-   * The name of the validation code.
-   */
-  final String name;
-
-  /**
-   * Initialize a newly created validation code to have the given [name].
-   */
-  const UriValidationCode(this.name);
-
-  @override
-  String toString() => name;
-}
-
-/**
- * An identifier that has an initial value associated with it. Instances of this
- * class are always children of the class [VariableDeclarationList].
- *
- * > variableDeclaration ::=
- * >     [SimpleIdentifier] ('=' [Expression])?
- *
- * TODO(paulberry): the grammar does not allow metadata to be associated with
- * a VariableDeclaration, and currently we don't record comments for it either.
- * Consider changing the class hierarchy so that [VariableDeclaration] does not
- * extend [Declaration].
- */
-class VariableDeclaration extends Declaration {
-  /**
-   * The name of the variable being declared.
-   */
-  SimpleIdentifier _name;
-
-  /**
-   * The equal sign separating the variable name from the initial value, or
-   * `null` if the initial value was not specified.
-   */
-  Token equals;
-
-  /**
-   * The expression used to compute the initial value for the variable, or
-   * `null` if the initial value was not specified.
-   */
-  Expression _initializer;
-
-  /**
-   * Initialize a newly created variable declaration. The [equals] and
-   * [initializer] can be `null` if there is no initializer.
-   */
-  VariableDeclaration(
-      SimpleIdentifier name, this.equals, Expression initializer)
-      : super(null, null) {
-    _name = _becomeParentOf(name);
-    _initializer = _becomeParentOf(initializer);
-  }
-
-  @override
-  Iterable get childEntities =>
-      super._childEntities..add(_name)..add(equals)..add(_initializer);
-
-  /**
-   * This overridden implementation of getDocumentationComment() looks in the
-   * grandparent node for Dartdoc comments if no documentation is specifically
-   * available on the node.
-   */
-  @override
-  Comment get documentationComment {
-    Comment comment = super.documentationComment;
-    if (comment == null) {
-      if (parent != null && parent.parent != null) {
-        AstNode node = parent.parent;
-        if (node is AnnotatedNode) {
-          return node.documentationComment;
-        }
-      }
-    }
-    return comment;
-  }
-
-  @override
-  VariableElement get element =>
-      _name != null ? (_name.staticElement as VariableElement) : null;
-
-  @override
-  Token get endToken {
-    if (_initializer != null) {
-      return _initializer.endToken;
-    }
-    return _name.endToken;
-  }
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
-
-  /**
-   * Return the expression used to compute the initial value for the variable,
-   * or `null` if the initial value was not specified.
-   */
-  Expression get initializer => _initializer;
-
-  /**
-   * Set the expression used to compute the initial value for the variable to
-   * the given [expression].
-   */
-  void set initializer(Expression expression) {
-    _initializer = _becomeParentOf(expression);
-  }
-
-  /**
-   * Return `true` if this variable was declared with the 'const' modifier.
-   */
-  bool get isConst {
-    AstNode parent = this.parent;
-    return parent is VariableDeclarationList && parent.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 {
-    AstNode parent = this.parent;
-    return parent is VariableDeclarationList && parent.isFinal;
-  }
-
-  /**
-   * Return the name of the variable being declared.
-   */
-  SimpleIdentifier get name => _name;
-
-  /**
-   * Set the name of the variable being declared to the given [identifier].
-   */
-  void set name(SimpleIdentifier identifier) {
-    _name = _becomeParentOf(identifier);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitVariableDeclaration(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_name, visitor);
-    _safelyVisitChild(_initializer, visitor);
-  }
-}
-
-/**
- * The declaration of one or more variables of the same type.
- *
- * > variableDeclarationList ::=
- * >     finalConstVarOrType [VariableDeclaration] (',' [VariableDeclaration])*
- * >
- * > finalConstVarOrType ::=
- * >   | 'final' [TypeName]?
- * >   | 'const' [TypeName]?
- * >   | 'var'
- * >   | [TypeName]
- */
-class VariableDeclarationList extends AnnotatedNode {
-  /**
-   * The token representing the 'final', 'const' or 'var' keyword, or `null` if
-   * no keyword was included.
-   */
-  Token keyword;
-
-  /**
-   * The type of the variables being declared, or `null` if no type was provided.
-   */
-  TypeName _type;
-
-  /**
-   * A list containing the individual variables being declared.
-   */
-  NodeList<VariableDeclaration> _variables;
-
-  /**
-   * Initialize a newly created variable declaration list. Either or both of the
-   * [comment] and [metadata] can be `null` if the variable list does not have
-   * the corresponding attribute. The [keyword] can be `null` if a type was
-   * specified. The [type] must be `null` if the keyword is 'var'.
-   */
-  VariableDeclarationList(Comment comment, List<Annotation> metadata,
-      this.keyword, TypeName type, List<VariableDeclaration> variables)
-      : super(comment, metadata) {
-    _type = _becomeParentOf(type);
-    _variables = new NodeList<VariableDeclaration>(this, variables);
-  }
-
-  @override
-  // TODO(paulberry): include commas.
-  Iterable get childEntities => super._childEntities
-    ..add(keyword)
-    ..add(_type)
-    ..addAll(_variables);
-
-  @override
-  Token get endToken => _variables.endToken;
-
-  @override
-  Token get firstTokenAfterCommentAndMetadata {
-    if (keyword != null) {
-      return keyword;
-    } else if (_type != null) {
-      return _type.beginToken;
-    }
-    return _variables.beginToken;
-  }
-
-  /**
-   * Return `true` if the variables in this list were declared with the 'const'
-   * modifier.
-   */
-  bool get isConst =>
-      keyword is KeywordToken &&
-      (keyword as KeywordToken).keyword == Keyword.CONST;
-
-  /**
-   * Return `true` if the variables in this list were declared with the 'final'
-   * modifier. Variables that are declared with the 'const' modifier will return
-   * `false` even though they are implicitly final. (In other words, this is a
-   * syntactic check rather than a semantic check.)
-   */
-  bool get isFinal =>
-      keyword is KeywordToken &&
-      (keyword as KeywordToken).keyword == Keyword.FINAL;
-
-  /**
-   * Return the type of the variables being declared, or `null` if no type was
-   * provided.
-   */
-  TypeName get type => _type;
-
-  /**
-   * Set the type of the variables being declared to the given [typeName].
-   */
-  void set type(TypeName typeName) {
-    _type = _becomeParentOf(typeName);
-  }
-
-  /**
-   * Return a list containing the individual variables being declared.
-   */
-  NodeList<VariableDeclaration> get variables => _variables;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitVariableDeclarationList(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    super.visitChildren(visitor);
-    _safelyVisitChild(_type, visitor);
-    _variables.accept(visitor);
-  }
-}
-
-/**
- * A list of variables that are being declared in a context where a statement is
- * required.
- *
- * > variableDeclarationStatement ::=
- * >     [VariableDeclarationList] ';'
- */
-class VariableDeclarationStatement extends Statement {
-  /**
-   * The variables being declared.
-   */
-  VariableDeclarationList _variableList;
-
-  /**
-   * The semicolon terminating the statement.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created variable declaration statement.
-   */
-  VariableDeclarationStatement(
-      VariableDeclarationList variableList, this.semicolon) {
-    _variableList = _becomeParentOf(variableList);
-  }
-
-  @override
-  Token get beginToken => _variableList.beginToken;
-
-  @override
-  Iterable get childEntities =>
-      new ChildEntities()..add(_variableList)..add(semicolon);
-
-  @override
-  Token get endToken => semicolon;
-
-  /**
-   * Return the variables being declared.
-   */
-  VariableDeclarationList get variables => _variableList;
-
-  /**
-   * Set the variables being declared to the given list of [variables].
-   */
-  void set variables(VariableDeclarationList variables) {
-    _variableList = _becomeParentOf(variables);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitVariableDeclarationStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_variableList, visitor);
-  }
-}
-
-/**
- * A while statement.
- *
- * > whileStatement ::=
- * >     'while' '(' [Expression] ')' [Statement]
- */
-class WhileStatement extends Statement {
-  /**
-   * The token representing the 'while' keyword.
-   */
-  Token whileKeyword;
-
-  /**
-   * The left parenthesis.
-   */
-  Token leftParenthesis;
-
-  /**
-   * The expression used to determine whether to execute the body of the loop.
-   */
-  Expression _condition;
-
-  /**
-   * The right parenthesis.
-   */
-  Token rightParenthesis;
-
-  /**
-   * The body of the loop.
-   */
-  Statement _body;
-
-  /**
-   * Initialize a newly created while statement.
-   */
-  WhileStatement(this.whileKeyword, this.leftParenthesis, Expression condition,
-      this.rightParenthesis, Statement body) {
-    _condition = _becomeParentOf(condition);
-    _body = _becomeParentOf(body);
-  }
-
-  @override
-  Token get beginToken => whileKeyword;
-
-  /**
-   * Return the body of the loop.
-   */
-  Statement get body => _body;
-
-  /**
-   * Set the body of the loop to the given [statement].
-   */
-  void set body(Statement statement) {
-    _body = _becomeParentOf(statement);
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(whileKeyword)
-    ..add(leftParenthesis)
-    ..add(_condition)
-    ..add(rightParenthesis)
-    ..add(_body);
-
-  /**
-   * Return the expression used to determine whether to execute the body of the
-   * loop.
-   */
-  Expression get condition => _condition;
-
-  /**
-   * Set the expression used to determine whether to execute the body of the
-   * loop to the given [expression].
-   */
-  void set condition(Expression expression) {
-    _condition = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get endToken => _body.endToken;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_condition, visitor);
-    _safelyVisitChild(_body, visitor);
-  }
-}
-
-/**
- * The with clause in a class declaration.
- *
- * > withClause ::=
- * >     'with' [TypeName] (',' [TypeName])*
- */
-class WithClause extends AstNode {
-  /**
-   * The token representing the 'with' keyword.
-   */
-  Token withKeyword;
-
-  /**
-   * The names of the mixins that were specified.
-   */
-  NodeList<TypeName> _mixinTypes;
-
-  /**
-   * Initialize a newly created with clause.
-   */
-  WithClause(this.withKeyword, List<TypeName> mixinTypes) {
-    _mixinTypes = new NodeList<TypeName>(this, mixinTypes);
-  }
-
-  @override
-  Token get beginToken => withKeyword;
-
-  @override
-  // TODO(paulberry): add commas.
-  Iterable get childEntities => new ChildEntities()
-    ..add(withKeyword)
-    ..addAll(_mixinTypes);
-
-  @override
-  Token get endToken => _mixinTypes.endToken;
-
-  /**
-   * Return the names of the mixins that were specified.
-   */
-  NodeList<TypeName> get mixinTypes => _mixinTypes;
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitWithClause(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _mixinTypes.accept(visitor);
-  }
-}
-
-/**
- * A yield statement.
- *
- * > yieldStatement ::=
- * >     'yield' '*'? [Expression] ‘;’
- */
-class YieldStatement extends Statement {
-  /**
-   * The 'yield' keyword.
-   */
-  Token yieldKeyword;
-
-  /**
-   * The star optionally following the 'yield' keyword.
-   */
-  Token star;
-
-  /**
-   * The expression whose value will be yielded.
-   */
-  Expression _expression;
-
-  /**
-   * The semicolon following the expression.
-   */
-  Token semicolon;
-
-  /**
-   * Initialize a newly created yield expression. The [star] can be `null` if no
-   * star was provided.
-   */
-  YieldStatement(
-      this.yieldKeyword, this.star, Expression expression, this.semicolon) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  Token get beginToken {
-    if (yieldKeyword != null) {
-      return yieldKeyword;
-    }
-    return _expression.beginToken;
-  }
-
-  @override
-  Iterable get childEntities => new ChildEntities()
-    ..add(yieldKeyword)
-    ..add(star)
-    ..add(_expression)
-    ..add(semicolon);
-
-  @override
-  Token get endToken {
-    if (semicolon != null) {
-      return semicolon;
-    }
-    return _expression.endToken;
-  }
-
-  /**
-   * Return the expression whose value will be yielded.
-   */
-  Expression get expression => _expression;
-
-  /**
-   * Set the expression whose value will be yielded to the given [expression].
-   */
-  void set expression(Expression expression) {
-    _expression = _becomeParentOf(expression);
-  }
-
-  @override
-  accept(AstVisitor visitor) => visitor.visitYieldStatement(this);
-
-  @override
-  void visitChildren(AstVisitor visitor) {
-    _safelyVisitChild(_expression, visitor);
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index a561978..efb81e3 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -6,11 +6,13 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/utilities.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/engine.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisEngine, RecordingErrorListener;
@@ -157,6 +159,13 @@
   ConstantAstCloner() : super(true);
 
   @override
+  ConstructorName visitConstructorName(ConstructorName node) {
+    ConstructorName name = super.visitConstructorName(node);
+    name.staticElement = node.staticElement;
+    return name;
+  }
+
+  @override
   InstanceCreationExpression visitInstanceCreationExpression(
       InstanceCreationExpression node) {
     InstanceCreationExpression expression =
@@ -441,13 +450,6 @@
    * Determine which constant elements need to have their values computed
    * prior to computing the value of [constant], and report them using
    * [callback].
-   *
-   * Note that it's possible (in erroneous code) for a constant to depend on a
-   * non-constant.  When this happens, we report the dependency anyhow so that
-   * if the non-constant changes to a constant, we will know to recompute the
-   * thing that depends on it.  [computeDependencies] and
-   * [computeConstantValue] are responsible for ignoring the request if they
-   * are asked to act on a non-constant target.
    */
   void computeDependencies(
       ConstantEvaluationTarget constant, ReferenceFinderCallback callback) {
@@ -1616,7 +1618,9 @@
     DartObjectImpl rightResult = node.rightOperand.accept(this);
     TokenType operatorType = node.operator.type;
     // 'null' is almost never good operand
-    if (operatorType != TokenType.BANG_EQ && operatorType != TokenType.EQ_EQ) {
+    if (operatorType != TokenType.BANG_EQ &&
+        operatorType != TokenType.EQ_EQ &&
+        operatorType != TokenType.QUESTION_QUESTION) {
       if (leftResult != null && leftResult.isNull ||
           rightResult != null && rightResult.isNull) {
         _error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -1665,6 +1669,9 @@
         return _dartObjectComputer.divide(node, leftResult, rightResult);
       } else if (operatorType == TokenType.TILDE_SLASH) {
         return _dartObjectComputer.integerDivide(node, leftResult, rightResult);
+      } else if (operatorType == TokenType.QUESTION_QUESTION) {
+        return _dartObjectComputer.questionQuestion(
+            node, leftResult, rightResult);
       } else {
         // TODO(brianwilkerson) Figure out which error to report.
         _error(node, null);
@@ -2461,6 +2468,17 @@
     return null;
   }
 
+  DartObjectImpl questionQuestion(Expression node, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (leftOperand != null && rightOperand != null) {
+      if (leftOperand.isNull) {
+        return rightOperand;
+      }
+      return leftOperand;
+    }
+    return null;
+  }
+
   DartObjectImpl remainder(BinaryExpression node, DartObjectImpl leftOperand,
       DartObjectImpl rightOperand) {
     if (leftOperand != null && rightOperand != null) {
@@ -5232,7 +5250,7 @@
     if (element is PropertyAccessorElement) {
       element = (element as PropertyAccessorElement).variable;
     }
-    if (element is VariableElement) {
+    if (element is VariableElement && element.isConst) {
       _callback(element);
     }
     return null;
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 968d797..4ff96d5 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -9,7 +9,7 @@
  * * 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
+ * If your code is using APIs 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.
  */
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index 0a29cfb..03f9137 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -7,7 +7,7 @@
 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/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -754,6 +754,9 @@
   bool get isBrowserApplication => actualElement.isBrowserApplication;
 
   @override
+  bool get isDartAsync => actualElement.isDartAsync;
+
+  @override
   bool get isDartCore => actualElement.isDartCore;
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 368da2a..5bf9630 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -6,11 +6,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart'
+    show ChildEntities, IdentifierImpl;
 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/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -427,9 +430,9 @@
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     Expression function = node.function;
-    DartType staticInvokeType =
-        _resolveGenericMethod(function.staticType, node.typeArguments, node);
-    DartType propagatedInvokeType = _resolveGenericMethod(
+    DartType staticInvokeType = _instantiateGenericMethod(
+        function.staticType, node.typeArguments, node);
+    DartType propagatedInvokeType = _instantiateGenericMethod(
         function.propagatedType, node.typeArguments, node);
 
     node.staticInvokeType = staticInvokeType;
@@ -616,7 +619,9 @@
             [(target as SimpleIdentifier).name]);
       }
       LibraryElement importedLibrary = _getImportedLibrary(target);
-      methodName.staticElement = importedLibrary.loadLibraryFunction;
+      FunctionElement loadLibraryFunction = importedLibrary.loadLibraryFunction;
+      methodName.staticElement = loadLibraryFunction;
+      node.staticInvokeType = loadLibraryFunction.type;
       return null;
     } else {
       //
@@ -650,9 +655,23 @@
     staticElement = _convertSetterToGetter(staticElement);
     propagatedElement = _convertSetterToGetter(propagatedElement);
 
-    DartType staticInvokeType = _computeMethodInvokeType(node, staticElement);
-    DartType propagatedInvokeType =
-        _computeMethodInvokeType(node, propagatedElement);
+    //
+    // Given the elements, determine the type of the function we are invoking
+    //
+    DartType staticInvokeType = _getInvokeType(staticElement);
+    methodName.staticType = staticInvokeType;
+
+    DartType propagatedInvokeType = _getInvokeType(propagatedElement);
+    methodName.propagatedType =
+        _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
+
+    //
+    // Instantiate generic function or method if needed.
+    //
+    staticInvokeType = _instantiateGenericMethod(
+        staticInvokeType, node.typeArguments, node.methodName);
+    propagatedInvokeType = _instantiateGenericMethod(
+        propagatedInvokeType, node.typeArguments, node.methodName);
 
     //
     // Record the results.
@@ -1336,30 +1355,6 @@
     return null;
   }
 
-  DartType _computeMethodInvokeType(MethodInvocation node, Element element) {
-    if (element == null) {
-      // TODO(jmesserly): should we return `dynamic` in this case?
-      // Otherwise we have to guard against `null` every time we use
-      // `staticInvokeType`.
-      // If we do return `dynamic` we need to be careful that this doesn't
-      // adversely affect propagatedType code path. But it shouldn't because
-      // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter).
-      return null;
-    }
-
-    DartType invokeType;
-    if (element is PropertyAccessorElement) {
-      invokeType = element.returnType;
-    } else if (element is ExecutableElement) {
-      invokeType = element.type;
-    } else if (element is VariableElement) {
-      invokeType = _promoteManager.getStaticType(element);
-    }
-
-    return _resolveGenericMethod(
-        invokeType, node.typeArguments, node.methodName);
-  }
-
   /**
    * If the given [element] is a setter, return the getter associated with it.
    * Otherwise, return the element unchanged.
@@ -1437,6 +1432,28 @@
   }
 
   /**
+   * Given an element, computes the type of the invocation.
+   *
+   * For executable elements (like methods, functions) this is just their type.
+   *
+   * For variables it is their type taking into account any type promotion.
+   *
+   * For calls to getters in Dart, we invoke the function that is returned by
+   * the getter, so the invoke type is the getter's returnType.
+   */
+  DartType _getInvokeType(Element element) {
+    DartType invokeType;
+    if (element is PropertyAccessorElement) {
+      invokeType = element.returnType;
+    } else if (element is ExecutableElement) {
+      invokeType = element.type;
+    } else if (element is VariableElement) {
+      invokeType = _promoteManager.getStaticType(element);
+    }
+    return invokeType ?? DynamicTypeImpl.instance;
+  }
+
+  /**
    * Return the name of the method invoked by the given postfix [expression].
    */
   String _getPostfixOperator(PostfixExpression expression) =>
@@ -1497,6 +1514,36 @@
   }
 
   /**
+   * Check for a generic method & apply type arguments if any were passed.
+   */
+  DartType _instantiateGenericMethod(
+      DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
+    // TODO(jmesserly): support generic "call" methods on InterfaceType.
+    if (invokeType is FunctionType) {
+      FunctionType type = invokeType;
+      List<TypeParameterElement> parameters = type.typeFormals;
+
+      NodeList<TypeName> arguments = typeArguments?.arguments;
+      if (arguments != null && arguments.length != parameters.length) {
+        // Wrong number of type arguments. Ignore them
+        arguments = null;
+        _resolver.reportErrorForNode(
+            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+            node,
+            [type, parameters.length, arguments?.length ?? 0]);
+      }
+      if (parameters.isNotEmpty) {
+        if (arguments == null) {
+          invokeType = _resolver.typeSystem.instantiateToBounds(type);
+        } else {
+          invokeType = type.instantiate(arguments.map((n) => n.type).toList());
+        }
+      }
+    }
+    return invokeType;
+  }
+
+  /**
    * Return `true` if the given [expression] is a prefix for a deferred import.
    */
   bool _isDeferredPrefix(Expression expression) {
@@ -2081,36 +2128,6 @@
   }
 
   /**
-   * Check for a generic method & apply type arguments if any were passed.
-   */
-  DartType _resolveGenericMethod(
-      DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
-    // TODO(jmesserly): support generic "call" methods on InterfaceType.
-    if (invokeType is FunctionType) {
-      FunctionType type = invokeType;
-      List<TypeParameterElement> parameters = type.typeFormals;
-
-      NodeList<TypeName> arguments = typeArguments?.arguments;
-      if (arguments != null && arguments.length != parameters.length) {
-        // Wrong number of type arguments. Ignore them
-        arguments = null;
-        _resolver.reportErrorForNode(
-            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
-            node,
-            [type, parameters.length, arguments?.length ?? 0]);
-      }
-      if (parameters.isNotEmpty) {
-        if (arguments == null) {
-          invokeType = _resolver.typeSystem.instantiateToBounds(type);
-        } else {
-          invokeType = type.instantiate(arguments.map((n) => n.type).toList());
-        }
-      }
-    }
-    return invokeType;
-  }
-
-  /**
    * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
    * element being invoked. If the returned element is a method, then the method
    * will be invoked. If the returned element is a getter, the getter will be
@@ -2559,7 +2576,7 @@
  * AST when the parser could not distinguish between a method invocation and an
  * invocation of a top-level function imported with a prefix.
  */
-class SyntheticIdentifier extends Identifier {
+class SyntheticIdentifier extends IdentifierImpl {
   /**
    * The name of the synthetic identifier.
    */
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 4f8d664..b27c42e 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -7,13 +7,14 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/instrumentation/instrumentation.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/context/context.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -312,8 +313,8 @@
    * Perform work until the given [result] has been computed for the given
    * [target]. Return the computed value.
    */
-  Object /*=V*/ computeResult /*<V>*/ (
-      AnalysisTarget target, ResultDescriptor /*<V>*/ result);
+  Object/*=V*/ computeResult/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ result);
 
   /**
    * Notifies the context that the client is going to stop using this context.
@@ -474,8 +475,8 @@
    * If the corresponding [target] does not exist, or the [result] is not
    * computed yet, then the default value is returned.
    */
-  Object /*=V*/ getResult /*<V>*/ (
-      AnalysisTarget target, ResultDescriptor /*<V>*/ result);
+  Object/*=V*/ getResult/*<V>*/(
+      AnalysisTarget target, ResultDescriptor/*<V>*/ result);
 
   /**
    * Return a list of the sources being analyzed in this context whose full path
@@ -1589,6 +1590,7 @@
   /**
    * A list containing the sources that have been deleted.
    */
+  @deprecated
   final List<Source> deletedSources = new List<Source>();
 
   /**
@@ -1651,6 +1653,7 @@
   /**
    * Record that the specified [source] has been deleted.
    */
+  @deprecated
   void deletedSource(Source source) {
     deletedSources.add(source);
   }
@@ -1850,6 +1853,11 @@
  */
 abstract class InternalAnalysisContext implements AnalysisContext {
   /**
+   * The result provider for [aboutToComputeResult].
+   */
+  ResultProvider resultProvider;
+
+  /**
    * A table mapping the sources known to the context to the information known
    * about the source.
    */
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index aa43a7e..777e5bc 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -6,10 +6,10 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart' show AstNode;
 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/java_core.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/scanner.dart'
@@ -19,6 +19,8 @@
 import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
 
+import 'generated/shared_messages.dart' as shared_messages;
+
 /**
  * The descriptor used to associate error processors with analysis contexts in
  * configuration data.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index d644fcd..20462bb 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -7,13 +7,14 @@
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/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_resolver.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -23,7 +24,6 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart' as sc;
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
-import 'package:analyzer/src/generated/static_type_analyzer.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -1285,27 +1285,27 @@
         }
       }
     });
+
     if (notInitFinalFields.isNotEmpty) {
       foundError = true;
       AnalysisErrorWithProperties analysisError;
-      if (notInitFinalFields.length == 1) {
+      List<String> names = notInitFinalFields.map((item) => item.name).toList();
+      names.sort();
+      if (names.length == 1) {
         analysisError = _errorReporter.newErrorWithProperties(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
             constructor.returnType,
-            [notInitFinalFields[0].name]);
-      } else if (notInitFinalFields.length == 2) {
+            names);
+      } else if (names.length == 2) {
         analysisError = _errorReporter.newErrorWithProperties(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
             constructor.returnType,
-            [notInitFinalFields[0].name, notInitFinalFields[1].name]);
+            names);
       } else {
         analysisError = _errorReporter.newErrorWithProperties(
             StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
-            constructor.returnType, [
-          notInitFinalFields[0].name,
-          notInitFinalFields[1].name,
-          notInitFinalFields.length - 2
-        ]);
+            constructor.returnType,
+            [names[0], names[1], names.length - 2]);
       }
       analysisError.setProperty(
           ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields);
@@ -5771,9 +5771,8 @@
     }
     DartType staticReturnType = getStaticType(returnExpression);
     if (staticReturnType != null && _enclosingFunction.isAsynchronous) {
-      return _typeProvider.futureType.substitute4(<DartType>[
-        StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType)
-      ]);
+      return _typeProvider.futureType.substitute4(
+          <DartType>[staticReturnType.flattenFutures(_typeSystem)]);
     }
     return staticReturnType;
   }
diff --git a/pkg/analyzer/lib/src/generated/generated/shared_messages.dart b/pkg/analyzer/lib/src/generated/generated/shared_messages.dart
new file mode 100644
index 0000000..2c1465c
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/generated/shared_messages.dart
@@ -0,0 +1,17 @@
+// 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.
+/*
+DON'T EDIT. GENERATED. DON'T EDIT.
+This file has been generated by 'publish.dart' in the dart_messages package.
+
+Messages are maintained in `lib/shared_messages.dart` of that same package.
+After any change to that file, run `bin/publish.dart` to generate a new version
+of the json, dart2js and analyzer representations.
+*/
+import 'package:analyzer/src/generated/error.dart';
+
+const AnalysisOptionsErrorCode exampleMessage = const AnalysisOptionsErrorCode(
+    'exampleMessage',
+    "{2} {1} {0}",
+    "an explanation on how to fix things");  // Generated. Don't edit.
diff --git a/pkg/analyzer/lib/src/generated/incremental_logger.dart b/pkg/analyzer/lib/src/generated/incremental_logger.dart
index d942aba..1de2534 100644
--- a/pkg/analyzer/lib/src/generated/incremental_logger.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_logger.dart
@@ -40,6 +40,11 @@
   void log(Object obj);
 
   /**
+   * Logs the given [exception] and [stackTrace].
+   */
+  void logException(Object exception, [Object stackTrace]);
+
+  /**
    * Starts a new timer.
    */
   LoggingTimer startTimer();
@@ -102,6 +107,16 @@
   }
 
   @override
+  void logException(Object exception, [Object stackTrace]) {
+    if (exception != null) {
+      log(exception);
+    }
+    if (stackTrace != null) {
+      log(stackTrace);
+    }
+  }
+
+  @override
   LoggingTimer startTimer() {
     return new LoggingTimer(this);
   }
@@ -147,6 +162,9 @@
   void log(Object obj) {}
 
   @override
+  void logException(Object exception, [Object stackTrace]) {}
+
+  @override
   LoggingTimer startTimer() {
     return new LoggingTimer(this);
   }
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index 36d8784..f0f7a4c7 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -4,11 +4,11 @@
 
 library analyzer.src.generated.incremental_resolution_validator;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
-import 'package:analyzer/src/generated/ast.dart';
 
 /**
  * Validates that the [actual] and the [expected] units have the same structure
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index b67b905..542e721 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -7,12 +7,14 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -474,7 +476,8 @@
   void _assertCompatibleParameter(
       FormalParameter node, ParameterElement element) {
     _assertEquals(node.kind, element.parameterKind);
-    if (node.kind == ParameterKind.NAMED) {
+    if (node.kind == ParameterKind.NAMED ||
+        element.enclosingElement is ConstructorElement) {
       _assertEquals(node.identifier.name, element.name);
     }
     // check parameter type specific properties
@@ -597,12 +600,12 @@
   }
 
   void _assertSameAnnotations(AnnotatedNode node, Element element) {
-    List<Annotation> nodeAnnotaitons = node.metadata;
+    List<Annotation> nodeAnnotations = node.metadata;
     List<ElementAnnotation> elementAnnotations = element.metadata;
-    int length = nodeAnnotaitons.length;
+    int length = nodeAnnotations.length;
     _assertEquals(elementAnnotations.length, length);
     for (int i = 0; i < length; i++) {
-      _assertSameAnnotation(nodeAnnotaitons[i], elementAnnotations[i]);
+      _assertSameAnnotation(nodeAnnotations[i], elementAnnotations[i]);
     }
   }
 
@@ -1468,37 +1471,67 @@
         {
           List<AstNode> oldParents = _getParents(oldNode);
           List<AstNode> newParents = _getParents(newNode);
+          // fail if an initializer change
+          if (oldParents.any((n) => n is ConstructorInitializer) ||
+              newParents.any((n) => n is ConstructorInitializer)) {
+            logger.log('Failure: a change in a constructor initializer');
+            return false;
+          }
+          // find matching methods / bodies
           int length = math.min(oldParents.length, newParents.length);
           bool found = false;
           for (int i = 0; i < length; i++) {
             AstNode oldParent = oldParents[i];
             AstNode newParent = newParents[i];
-            if (oldParent is ConstructorInitializer ||
-                newParent is ConstructorInitializer) {
-              logger.log('Failure: changes in constant constructor initializers'
-                  ' may cause external changes in constant objects.');
-              return false;
-            }
-            if (oldParent is FunctionDeclaration &&
+            if (oldParent is CompilationUnit && newParent is CompilationUnit) {
+              int oldLength = oldParent.declarations.length;
+              int newLength = newParent.declarations.length;
+              if (oldLength != newLength) {
+                logger.log(
+                    'Failure: unit declarations mismatch $oldLength vs. $newLength');
+                return false;
+              }
+            } else if (oldParent is ClassDeclaration &&
+                newParent is ClassDeclaration) {
+              int oldLength = oldParent.members.length;
+              int newLength = newParent.members.length;
+              if (oldLength != newLength) {
+                logger.log(
+                    'Failure: class declarations mismatch $oldLength vs. $newLength');
+                return false;
+              }
+            } else if (oldParent is FunctionDeclaration &&
                     newParent is FunctionDeclaration ||
-                oldParent is MethodDeclaration &&
-                    newParent is MethodDeclaration ||
                 oldParent is ConstructorDeclaration &&
-                    newParent is ConstructorDeclaration) {
+                    newParent is ConstructorDeclaration ||
+                oldParent is MethodDeclaration &&
+                    newParent is MethodDeclaration) {
               Element oldElement = (oldParent as Declaration).element;
               if (new DeclarationMatcher().matches(newParent, oldElement) ==
                   DeclarationMatchKind.MATCH) {
                 oldNode = oldParent;
                 newNode = newParent;
                 found = true;
+              } else {
+                return false;
               }
-            }
-            if (oldParent is BlockFunctionBody &&
-                newParent is BlockFunctionBody) {
-              oldNode = oldParent;
-              newNode = newParent;
-              found = true;
-              break;
+            } else if (oldParent is FunctionBody && newParent is FunctionBody) {
+              if (oldParent is BlockFunctionBody &&
+                  newParent is BlockFunctionBody) {
+                oldNode = oldParent;
+                newNode = newParent;
+                found = true;
+                break;
+              }
+              logger.log('Failure: not a block function body.');
+              return false;
+            } else if (oldParent is FunctionExpression &&
+                newParent is FunctionExpression) {
+              // skip
+            } else {
+              logger.log('Failure: old and new parent mismatch'
+                  ' ${oldParent.runtimeType} vs. ${newParent.runtimeType}');
+              return false;
             }
           }
           if (!found) {
@@ -1555,9 +1588,12 @@
         return true;
       }
     } catch (e, st) {
-      logger.log(e);
-      logger.log(st);
+      logger.logException(e, st);
       logger.log('Failure: exception.');
+      // The incremental resolver log is usually turned off,
+      // so also log the exception to the instrumentation log.
+      AnalysisEngine.instance.logger.logError(
+          'Failure in incremental resolver', new CaughtException(e, st));
     } finally {
       logger.exit();
     }
@@ -1595,8 +1631,13 @@
     // find nodes
     int offset = oldComments.offset;
     logger.log('offset: $offset');
-    Comment oldComment = _findNodeCovering(_oldUnit, offset, offset);
-    Comment newComment = _findNodeCovering(newUnit, offset, offset);
+    AstNode oldNode = _findNodeCovering(_oldUnit, offset, offset);
+    AstNode newNode = _findNodeCovering(newUnit, offset, offset);
+    if (oldNode is! Comment || newNode is! Comment) {
+      return false;
+    }
+    Comment oldComment = oldNode;
+    Comment newComment = newNode;
     logger.log('oldComment.beginToken: ${oldComment.beginToken}');
     logger.log('newComment.beginToken: ${newComment.beginToken}');
     _updateOffset = oldToken.offset - 1;
@@ -1733,7 +1774,7 @@
         Token newComment = newToken.precedingComments;
         if (_compareToken(oldComment, newComment, 0, true) != null) {
           _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT;
-          if (oldComment is DocumentationCommentToken ||
+          if (oldComment is DocumentationCommentToken &&
               newComment is DocumentationCommentToken) {
             diffKind = _TokenDifferenceKind.COMMENT_DOC;
           }
@@ -1769,7 +1810,7 @@
         Token newComment = newToken.precedingComments;
         if (_compareToken(oldComment, newComment, delta, true) != null) {
           _TokenDifferenceKind diffKind = _TokenDifferenceKind.COMMENT;
-          if (oldComment is DocumentationCommentToken ||
+          if (oldComment is DocumentationCommentToken &&
               newComment is DocumentationCommentToken) {
             diffKind = _TokenDifferenceKind.COMMENT_DOC;
           }
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index de0306f..4f249be 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -7,7 +7,10 @@
 import 'dart:collection';
 import "dart:math" as math;
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisEngine, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/error.dart';
@@ -3798,8 +3801,7 @@
 
   /**
    * If the current token has the type [TokenType.GT], return it after advancing
-   * to the next token. Otherwise report an error and return the current token
-   * without advancing.
+   * to the next token. Otherwise report an error and create a synthetic token.
    */
   Token _expectGt() {
     if (_matchesGt()) {
@@ -3807,7 +3809,7 @@
     }
     _reportErrorForCurrentToken(
         ParserErrorCode.EXPECTED_TOKEN, [TokenType.GT.lexeme]);
-    return _currentToken;
+    return _createSyntheticToken(TokenType.GT);
   }
 
   /**
@@ -5369,12 +5371,13 @@
    */
   Expression _parseConstExpression() {
     Token keyword = _expectKeyword(Keyword.CONST);
-    if (_matches(TokenType.OPEN_SQUARE_BRACKET) || _matches(TokenType.INDEX)) {
+    if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
+      return _parseListOrMapLiteral(keyword);
+    } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
+        _matches(TokenType.INDEX)) {
       return _parseListLiteral(keyword, null);
     } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       return _parseMapLiteral(keyword, null);
-    } else if (_matches(TokenType.LT)) {
-      return _parseListOrMapLiteral(keyword);
     }
     return _parseInstanceCreationExpression(keyword);
   }
@@ -7394,11 +7397,6 @@
       return new IntegerLiteral(token, value);
     } else if (_matches(TokenType.STRING)) {
       return parseStringLiteral();
-    } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
-      return _parseMapLiteral(null, null);
-    } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
-        _matches(TokenType.INDEX)) {
-      return _parseListLiteral(null, null);
     } else if (_matchesIdentifier()) {
       // TODO(brianwilkerson) The code below was an attempt to recover from an
       // error case, but it needs to be applied as a recovery only after we
@@ -7431,8 +7429,13 @@
       } finally {
         _inInitializer = wasInInitializer;
       }
-    } else if (_matches(TokenType.LT)) {
+    } else if (_matches(TokenType.LT) || _injectGenericCommentTypeList()) {
       return _parseListOrMapLiteral(null);
+    } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+      return _parseMapLiteral(null, null);
+    } else if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
+        _matches(TokenType.INDEX)) {
+      return _parseListLiteral(null, null);
     } else if (_matches(TokenType.QUESTION) &&
         _tokenMatches(_peek(), TokenType.IDENTIFIER)) {
       _reportErrorForCurrentToken(
@@ -9381,9 +9384,9 @@
   /**
    * Some environments, such as Fletch, do not support async.
    */
-  static const CompileTimeErrorCode ASYNC_NOT_SUPPORTED =
-      const CompileTimeErrorCode('ASYNC_NOT_SUPPORTED',
-          "Async and sync are not supported in this environment.");
+  static const ParserErrorCode ASYNC_NOT_SUPPORTED = const ParserErrorCode(
+      'ASYNC_NOT_SUPPORTED',
+      "Async and sync are not supported in this environment.");
 
   static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'BREAK_OUTSIDE_OF_LOOP',
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0d856c8..4ed3deb 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -6,13 +6,15 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/ast/utilities.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_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -517,6 +519,8 @@
     }
     AstNode parent = identifier.parent;
     if ((parent is ConstructorName && identical(identifier, parent.name)) ||
+        (parent is ConstructorDeclaration &&
+            identical(identifier, parent.returnType)) ||
         (parent is SuperConstructorInvocation &&
             identical(identifier, parent.constructorName)) ||
         parent is HideCombinator) {
@@ -906,6 +910,63 @@
 }
 
 /**
+ * Utilities for [LibraryElementImpl] building.
+ */
+class BuildLibraryElementUtils {
+  /**
+   * Look through all of the compilation units defined for the given [library],
+   * looking for getters and setters that are defined in different compilation
+   * units but that have the same names. If any are found, make sure that they
+   * have the same variable element.
+   */
+  static void patchTopLevelAccessors(LibraryElementImpl library) {
+    // Without parts getters/setters already share the same variable element.
+    if (library.parts.isEmpty) {
+      return;
+    }
+    // Collect getters and setters.
+    HashMap<String, PropertyAccessorElement> getters =
+        new HashMap<String, PropertyAccessorElement>();
+    List<PropertyAccessorElement> setters = <PropertyAccessorElement>[];
+    _collectAccessors(getters, setters, library.definingCompilationUnit);
+    for (CompilationUnitElement unit in library.parts) {
+      _collectAccessors(getters, setters, unit);
+    }
+    // Move every setter to the corresponding getter's variable (if exists).
+    for (PropertyAccessorElement setter in setters) {
+      PropertyAccessorElement getter = getters[setter.displayName];
+      if (getter != null) {
+        TopLevelVariableElementImpl variable = getter.variable;
+        TopLevelVariableElementImpl setterVariable = setter.variable;
+        CompilationUnitElementImpl setterUnit = setterVariable.enclosingElement;
+        setterUnit.replaceTopLevelVariable(setterVariable, variable);
+        variable.setter = setter;
+        (setter as PropertyAccessorElementImpl).variable = variable;
+      }
+    }
+  }
+
+  /**
+   * Add all of the non-synthetic [getters] and [setters] defined in the given
+   * [unit] that have no corresponding accessor to one of the given collections.
+   */
+  static void _collectAccessors(Map<String, PropertyAccessorElement> getters,
+      List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
+    for (PropertyAccessorElement accessor in unit.accessors) {
+      if (accessor.isGetter) {
+        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
+          getters[accessor.displayName] = accessor;
+        }
+      } else {
+        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
+          setters.add(accessor);
+        }
+      }
+    }
+  }
+}
+
+/**
  * Instances of the class `ClassScope` implement the scope defined by a class.
  */
 class ClassScope extends EnclosedScope {
@@ -2610,11 +2671,6 @@
   bool _inFunction = false;
 
   /**
-   * A flag indicating whether the class currently being visited can be used as a mixin.
-   */
-  bool _isValidMixin = false;
-
-  /**
    * A collection holding the elements defined in a class that need to have
    * their function type fixed to take into account type parameters of the
    * enclosing class, or `null` if we are not currently processing nodes within
@@ -2676,7 +2732,6 @@
   @override
   Object visitClassDeclaration(ClassDeclaration node) {
     ElementHolder holder = new ElementHolder();
-    _isValidMixin = true;
     _functionTypesToFix = new List<ExecutableElementImpl>();
     //
     // Process field declarations before constructors and methods so that field
@@ -2714,7 +2769,6 @@
     element.constructors = constructors;
     element.fields = holder.fields;
     element.methods = holder.methods;
-    element.validMixin = _isValidMixin;
     // Function types must be initialized after the enclosing element has been
     // set, for them to pick up the type parameters.
     for (ExecutableElementImpl e in _functionTypesToFix) {
@@ -2764,7 +2818,6 @@
 
   @override
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    _isValidMixin = false;
     ElementHolder holder = new ElementHolder();
     bool wasInFunction = _inFunction;
     _inFunction = true;
@@ -3337,12 +3390,6 @@
   }
 
   @override
-  Object visitSuperExpression(SuperExpression node) {
-    _isValidMixin = false;
-    return super.visitSuperExpression(node);
-  }
-
-  @override
   Object visitSwitchCase(SwitchCase node) {
     for (Label label in node.labels) {
       SimpleIdentifier labelName = label.label;
@@ -6938,16 +6985,6 @@
 }
 
 /**
- * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
- * libraries within a single context.
- */
-
-/**
- * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
- * libraries within a single context.
- */
-
-/**
  * Instances of the class `LibraryScope` implement a scope containing all of the names defined
  * in a given library.
  */
@@ -8380,11 +8417,10 @@
   Object visitAwaitExpression(AwaitExpression node) {
     // TODO(leafp): Handle the implicit union type here
     // https://github.com/dart-lang/sdk/issues/25322
-    DartType contextType = StaticTypeAnalyzer.flattenFutures(
-        typeProvider, InferenceContext.getType(node));
+    DartType contextType = InferenceContext.getType(node);
     if (contextType != null) {
-      InterfaceType futureT =
-          typeProvider.futureType.substitute4([contextType]);
+      InterfaceType futureT = typeProvider.futureType
+          .substitute4([contextType.flattenFutures(typeSystem)]);
       InferenceContext.setType(node.expression, futureT);
     }
     return super.visitAwaitExpression(node);
@@ -9165,105 +9201,6 @@
     return null;
   }
 
-  /**
-   * Given an [argumentList] and the [parameters] related to the element that
-   * will be invoked using those arguments, compute the list of parameters that
-   * correspond to the list of arguments.
-   *
-   * An error will be reported to [onError] if any of the arguments cannot be
-   * matched to a parameter. onError can be null to ignore the error.
-   *
-   * The flag [reportAsError] should be `true` if a compile-time error should be
-   * reported; or `false` if a compile-time warning should be reported
-   *
-   * Returns the parameters that correspond to the arguments.
-   */
-  static List<ParameterElement> resolveArgumentsToParameters(
-      ArgumentList argumentList,
-      List<ParameterElement> parameters,
-      void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]),
-      {bool reportAsError: false}) {
-    List<ParameterElement> requiredParameters = new List<ParameterElement>();
-    List<ParameterElement> positionalParameters = new List<ParameterElement>();
-    HashMap<String, ParameterElement> namedParameters =
-        new HashMap<String, ParameterElement>();
-    for (ParameterElement parameter in parameters) {
-      ParameterKind kind = parameter.parameterKind;
-      if (kind == ParameterKind.REQUIRED) {
-        requiredParameters.add(parameter);
-      } else if (kind == ParameterKind.POSITIONAL) {
-        positionalParameters.add(parameter);
-      } else {
-        namedParameters[parameter.name] = parameter;
-      }
-    }
-    List<ParameterElement> unnamedParameters =
-        new List<ParameterElement>.from(requiredParameters);
-    unnamedParameters.addAll(positionalParameters);
-    int unnamedParameterCount = unnamedParameters.length;
-    int unnamedIndex = 0;
-    NodeList<Expression> arguments = argumentList.arguments;
-    int argumentCount = arguments.length;
-    List<ParameterElement> resolvedParameters =
-        new List<ParameterElement>(argumentCount);
-    int positionalArgumentCount = 0;
-    HashSet<String> usedNames = new HashSet<String>();
-    bool noBlankArguments = true;
-    for (int i = 0; i < argumentCount; i++) {
-      Expression argument = arguments[i];
-      if (argument is NamedExpression) {
-        SimpleIdentifier nameNode = argument.name.label;
-        String name = nameNode.name;
-        ParameterElement element = namedParameters[name];
-        if (element == null) {
-          ErrorCode errorCode = (reportAsError
-              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
-              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
-          if (onError != null) {
-            onError(errorCode, nameNode, [name]);
-          }
-        } else {
-          resolvedParameters[i] = element;
-          nameNode.staticElement = element;
-        }
-        if (!usedNames.add(name)) {
-          if (onError != null) {
-            onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode,
-                [name]);
-          }
-        }
-      } else {
-        if (argument is SimpleIdentifier && argument.name.isEmpty) {
-          noBlankArguments = false;
-        }
-        positionalArgumentCount++;
-        if (unnamedIndex < unnamedParameterCount) {
-          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
-        }
-      }
-    }
-    if (positionalArgumentCount < requiredParameters.length &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportAsError
-          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
-          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
-      if (onError != null) {
-        onError(errorCode, argumentList,
-            [requiredParameters.length, positionalArgumentCount]);
-      }
-    } else if (positionalArgumentCount > unnamedParameterCount &&
-        noBlankArguments) {
-      ErrorCode errorCode = (reportAsError
-          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
-          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
-      if (onError != null) {
-        onError(errorCode, argumentList,
-            [unnamedParameterCount, positionalArgumentCount]);
-      }
-    }
-    return resolvedParameters;
-  }
-
   @override
   Object visitNamedExpression(NamedExpression node) {
     InferenceContext.setType(node.expression, InferenceContext.getType(node));
@@ -9409,7 +9346,8 @@
     return null;
   }
 
-  @override visitVariableDeclarationList(VariableDeclarationList node) {
+  @override
+  visitVariableDeclarationList(VariableDeclarationList node) {
     for (VariableDeclaration decl in node.variables) {
       InferenceContext.setType(decl, node.type?.type);
     }
@@ -9525,7 +9463,7 @@
       return (typeArgs?.length == 1) ? typeArgs[0] : null;
     }
     // Must be asynchronous to reach here, so strip off any layers of Future
-    return StaticTypeAnalyzer.flattenFutures(typeProvider, declaredType);
+    return declaredType.flattenFutures(typeSystem);
   }
 
   /**
@@ -9775,24 +9713,17 @@
         return;
       }
       // prepare current variable type
-      DartType type = _promoteManager.getType(element);
-      if (type == null) {
-        type = expression.staticType;
+      DartType type = _promoteManager.getType(element) ??
+          expression.staticType ??
+          DynamicTypeImpl.instance;
+
+      potentialType ??= DynamicTypeImpl.instance;
+
+      // Check if we can promote to potentialType from type.
+      if (typeSystem.canPromoteToType(potentialType, type)) {
+        // Do promote type of variable.
+        _promoteManager.setType(element, potentialType);
       }
-      // Declared type should not be "dynamic".
-      if (type == null || type.isDynamic) {
-        return;
-      }
-      // Promoted type should not be "dynamic".
-      if (potentialType == null || potentialType.isDynamic) {
-        return;
-      }
-      // Promoted type should be more specific than declared.
-      if (!potentialType.isMoreSpecificThan(type)) {
-        return;
-      }
-      // Do promote type of variable.
-      _promoteManager.setType(element, potentialType);
     }
   }
 
@@ -9890,6 +9821,106 @@
       _propagateTrueState(condition.expression);
     }
   }
+
+  /**
+   * Given an [argumentList] and the [parameters] related to the element that
+   * will be invoked using those arguments, compute the list of parameters that
+   * correspond to the list of arguments.
+   *
+   * An error will be reported to [onError] if any of the arguments cannot be
+   * matched to a parameter. onError can be null to ignore the error.
+   *
+   * The flag [reportAsError] should be `true` if a compile-time error should be
+   * reported; or `false` if a compile-time warning should be reported.
+   *
+   * Returns the parameters that correspond to the arguments. If no parameter
+   * matched an argument, that position will be `null` in the list.
+   */
+  static List<ParameterElement> resolveArgumentsToParameters(
+      ArgumentList argumentList,
+      List<ParameterElement> parameters,
+      void onError(ErrorCode errorCode, AstNode node, [List<Object> arguments]),
+      {bool reportAsError: false}) {
+    List<ParameterElement> requiredParameters = new List<ParameterElement>();
+    List<ParameterElement> positionalParameters = new List<ParameterElement>();
+    HashMap<String, ParameterElement> namedParameters =
+        new HashMap<String, ParameterElement>();
+    for (ParameterElement parameter in parameters) {
+      ParameterKind kind = parameter.parameterKind;
+      if (kind == ParameterKind.REQUIRED) {
+        requiredParameters.add(parameter);
+      } else if (kind == ParameterKind.POSITIONAL) {
+        positionalParameters.add(parameter);
+      } else {
+        namedParameters[parameter.name] = parameter;
+      }
+    }
+    List<ParameterElement> unnamedParameters =
+        new List<ParameterElement>.from(requiredParameters);
+    unnamedParameters.addAll(positionalParameters);
+    int unnamedParameterCount = unnamedParameters.length;
+    int unnamedIndex = 0;
+    NodeList<Expression> arguments = argumentList.arguments;
+    int argumentCount = arguments.length;
+    List<ParameterElement> resolvedParameters =
+        new List<ParameterElement>(argumentCount);
+    int positionalArgumentCount = 0;
+    HashSet<String> usedNames = new HashSet<String>();
+    bool noBlankArguments = true;
+    for (int i = 0; i < argumentCount; i++) {
+      Expression argument = arguments[i];
+      if (argument is NamedExpression) {
+        SimpleIdentifier nameNode = argument.name.label;
+        String name = nameNode.name;
+        ParameterElement element = namedParameters[name];
+        if (element == null) {
+          ErrorCode errorCode = (reportAsError
+              ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
+              : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
+          if (onError != null) {
+            onError(errorCode, nameNode, [name]);
+          }
+        } else {
+          resolvedParameters[i] = element;
+          nameNode.staticElement = element;
+        }
+        if (!usedNames.add(name)) {
+          if (onError != null) {
+            onError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode,
+                [name]);
+          }
+        }
+      } else {
+        if (argument is SimpleIdentifier && argument.name.isEmpty) {
+          noBlankArguments = false;
+        }
+        positionalArgumentCount++;
+        if (unnamedIndex < unnamedParameterCount) {
+          resolvedParameters[i] = unnamedParameters[unnamedIndex++];
+        }
+      }
+    }
+    if (positionalArgumentCount < requiredParameters.length &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
+          : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [requiredParameters.length, positionalArgumentCount]);
+      }
+    } else if (positionalArgumentCount > unnamedParameterCount &&
+        noBlankArguments) {
+      ErrorCode errorCode = (reportAsError
+          ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
+          : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
+      if (onError != null) {
+        onError(errorCode, argumentList,
+            [unnamedParameterCount, positionalArgumentCount]);
+      }
+    }
+    return resolvedParameters;
+  }
 }
 
 /**
@@ -11981,9 +12012,6 @@
           : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS);
       superclassType = _resolveType(extendsClause.superclass, errorCode,
           CompileTimeErrorCode.EXTENDS_ENUM, errorCode);
-      if (!identical(superclassType, typeProvider.objectType)) {
-        classElement.validMixin = false;
-      }
     }
     if (classElement != null) {
       if (superclassType == null) {
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 4c756e2..a2b6325 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -6,7 +6,8 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/source.dart'
     show ContentCache, Source, UriKind;
@@ -184,16 +185,20 @@
    */
   LibraryMap get librariesMap => _librariesMap;
 
-
   // To be backwards-compatible the new categories field is translated to
   // an old approximation.
   String convertCategories(String categories) {
     switch (categories) {
-      case "": return "Internal";
-      case "Client": return "Client";
-      case "Server": return "Server";
-      case "Client,Server": return "Shared";
-      case "Client,Server,Embedded": return "Shared";
+      case "":
+        return "Internal";
+      case "Client":
+        return "Client";
+      case "Server":
+        return "Server";
+      case "Client,Server":
+        return "Shared";
+      case "Client,Server,Embedded":
+        return "Shared";
     }
     return "Shared";
   }
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 863a3d4..a50eb95 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -7,8 +7,8 @@
 import 'dart:collection';
 import 'dart:io';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -255,20 +255,15 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      SdkBundle sdkBundle = _getSummarySdkBundle();
-      if (sdkBundle != null) {
-        _analysisContext = new SummarySdkAnalysisContext(sdkBundle);
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
-      List<String> uris = this.uris;
-      ChangeSet changeSet = new ChangeSet();
-      for (String uri in uris) {
-        changeSet.addedSource(factory.forUri(uri));
+      // Try to use summaries.
+      SdkBundle sdkBundle = _getSummarySdkBundle();
+      if (sdkBundle != null) {
+        _analysisContext.resultProvider =
+            new SdkSummaryResultProvider(_analysisContext, sdkBundle);
       }
-      _analysisContext.applyChanges(changeSet);
     }
     return _analysisContext;
   }
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 950f36e0..a3662f9 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -178,12 +178,12 @@
 }
 
 /**
- * Instances of the class `LineInfo` encapsulate information about line and column information
- * within a source file.
+ * Information about line and column information within a source file.
  */
 class LineInfo {
   /**
-   * An array containing the offsets of the first character of each line in the source code.
+   * A list containing the offsets of the first character of each line in the
+   * source code.
    */
   final List<int> _lineStarts;
 
@@ -194,12 +194,23 @@
   int _previousLine = 0;
 
   /**
-   * Initialize a newly created set of line information to represent the data encoded in the given
-   * array.
-   *
-   * @param lineStarts the offsets of the first character of each line in the source code
+   * Initialize a newly created set of line information to represent the data
+   * encoded in the given list of [_lineStarts].
    */
-  LineInfo(this._lineStarts) {
+  factory LineInfo(List<int> _lineStarts) => new LineInfoWithCount(_lineStarts);
+
+  /**
+   * Initialize a newly created set of line information corresponding to the
+   * given file [content].
+   */
+  factory LineInfo.fromContent(String content) =>
+      new LineInfoWithCount(StringUtilities.computeLineStarts(content));
+
+  /**
+   * Initialize a newly created set of line information to represent the data
+   * encoded in the given list of [_lineStarts].
+   */
+  LineInfo._(this._lineStarts) {
     if (_lineStarts == null) {
       throw new IllegalArgumentException("lineStarts must be non-null");
     } else if (_lineStarts.length < 1) {
@@ -208,10 +219,7 @@
   }
 
   /**
-   * Return the location information for the character at the given offset.
-   *
-   * @param offset the offset of the character for which location information is to be returned
-   * @return the location information for the character at the given offset
+   * Return the location information for the character at the given [offset].
    */
   LineInfo_Location getLocation(int offset) {
     var min = 0;
@@ -288,6 +296,26 @@
 }
 
 /**
+ * Information about line and column information within a source file,
+ * including a count of the total number of lines.
+ *
+ * TODO(paulberry): in the next major version roll of analyzer, merge this
+ * class into [LineInfo].
+ */
+class LineInfoWithCount extends LineInfo {
+  /**
+   * Initialize a newly created set of line information to represent the data
+   * encoded in the given list of [_lineStarts].
+   */
+  LineInfoWithCount(List<int> _lineStarts) : super._(_lineStarts);
+
+  /**
+   * Return the number of lines in the file.
+   */
+  int get lineCount => _lineStarts.length;
+}
+
+/**
  * Instances of interface `LocalSourcePredicate` are used to determine if the given
  * [Source] is "local" in some sense, so can be updated.
  */
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 28f42f7..e67d096 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -6,11 +6,12 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -281,11 +282,11 @@
       // TODO(brianwilkerson) Determine whether this can still happen.
       staticExpressionType = _dynamicType;
     }
-    DartType staticType = flattenFutures(_typeProvider, staticExpressionType);
+    DartType staticType = staticExpressionType.flattenFutures(_typeSystem);
     _recordStaticType(node, staticType);
     DartType propagatedExpressionType = node.expression.propagatedType;
     DartType propagatedType =
-        flattenFutures(_typeProvider, propagatedExpressionType);
+        propagatedExpressionType?.flattenFutures(_typeSystem);
     _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
     return null;
   }
@@ -495,6 +496,9 @@
    */
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
+    if (_strongMode) {
+      _inferFunctionInvocationGeneric(node);
+    }
     DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticType);
     DartType functionPropagatedType = node.propagatedInvokeType;
@@ -713,12 +717,12 @@
   Object visitMethodInvocation(MethodInvocation node) {
     SimpleIdentifier methodNameNode = node.methodName;
     Element staticMethodElement = methodNameNode.staticElement;
+    if (_strongMode) {
+      _inferMethodInvocation(node);
+    }
     // Record types of the variable invoked as a function.
     if (staticMethodElement is VariableElement) {
-      VariableElement variable = staticMethodElement;
-      DartType staticType = variable.type;
-      _recordStaticType(methodNameNode, staticType);
-      DartType propagatedType = _overrideManager.getType(variable);
+      DartType propagatedType = _overrideManager.getType(staticMethodElement);
       _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType);
     }
     // Record static return type of the static element.
@@ -731,10 +735,7 @@
     // Check for special cases.
     bool needPropagatedType = true;
     String methodName = methodNameNode.name;
-    if (_strongMode) {
-      _inferMethodInvocation(node);
-    }
-    if (methodName == "then") {
+    if (!_strongMode && methodName == "then") {
       Expression target = node.realTarget;
       if (target != null) {
         DartType targetType = target.bestType;
@@ -753,16 +754,10 @@
                   _computePropagatedReturnType(closureExpr.element);
               if (returnType != null) {
                 // prepare the type of the returned Future
-                InterfaceTypeImpl newFutureType;
-                if (_isAsyncFutureType(returnType)) {
-                  newFutureType = returnType as InterfaceTypeImpl;
-                } else {
-                  InterfaceType futureType = targetType as InterfaceType;
-                  newFutureType = new InterfaceTypeImpl(futureType.element);
-                  newFutureType.typeArguments = <DartType>[returnType];
-                }
+                InterfaceType newFutureType = _typeProvider.futureType
+                    .substitute4([returnType.flattenFutures(_typeSystem)]);
                 // set the 'then' invocation type
-                _recordPropagatedType(node, newFutureType);
+                _resolver.recordPropagatedTypeIfBetter(node, newFutureType);
                 needPropagatedType = false;
                 return null;
               }
@@ -873,16 +868,21 @@
     }
     if (needPropagatedType) {
       Element propagatedElement = methodNameNode.propagatedElement;
+      DartType propagatedInvokeType = node.propagatedInvokeType;
       // HACK: special case for object methods ([toString]) on dynamic
       // expressions. More special cases in [visitPrefixedIdentfier].
       if (propagatedElement == null) {
-        propagatedElement =
+        MethodElement objMethod =
             _typeProvider.objectType.getMethod(methodNameNode.name);
+        if (objMethod != null) {
+          propagatedElement = objMethod;
+          propagatedInvokeType = objMethod.type;
+        }
       }
       if (!identical(propagatedElement, staticMethodElement)) {
         // Record static return type of the propagated element.
         DartType propagatedStaticType =
-            _computeStaticReturnType(propagatedElement);
+            _computeInvokeReturnType(propagatedInvokeType);
         _resolver.recordPropagatedTypeIfBetter(
             node, propagatedStaticType, true);
         // Record propagated return type of the propagated element.
@@ -1379,6 +1379,21 @@
   }
 
   /**
+   * Compute the return type of the method or function represented by the given
+   * type that is being invoked.
+   */
+  DartType _computeInvokeReturnType(DartType type) {
+    if (type is InterfaceType) {
+      MethodElement callMethod = type.lookUpMethod(
+          FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
+      return callMethod?.type?.returnType ?? _dynamicType;
+    } else if (type is FunctionType) {
+      return type.returnType ?? _dynamicType;
+    }
+    return _dynamicType;
+  }
+
+  /**
    * Compute the propagated return type of the method or function represented by the given element.
    *
    * @param element the element representing the method or function invoked by the given node
@@ -1440,21 +1455,6 @@
   }
 
   /**
-   * Compute the return type of the method or function represented by the given
-   * type that is being invoked.
-   */
-  DartType _computeInvokeReturnType(DartType type) {
-    if (type is InterfaceType) {
-      MethodElement callMethod = type.lookUpMethod(
-          FunctionElement.CALL_METHOD_NAME, _resolver.definingLibrary);
-      return callMethod?.type?.returnType ?? _dynamicType;
-    } else if (type is FunctionType) {
-      return type.returnType ?? _dynamicType;
-    }
-    return _dynamicType;
-  }
-
-  /**
    * Given a function declaration, compute the return static type of the function. The return type
    * of functions with a block body is `dynamicType`, with an expression body it is the type
    * of the expression.
@@ -1497,7 +1497,7 @@
     }
     if (body.isAsynchronous) {
       return _typeProvider.futureType
-          .substitute4(<DartType>[flattenFutures(_typeProvider, type)]);
+          .substitute4(<DartType>[type.flattenFutures(_typeSystem)]);
     } else {
       return type;
     }
@@ -1769,6 +1769,63 @@
   }
 
   /**
+   * Similar to [_inferMethodInvocationGeneric] but for function expression
+   * invocations.
+   */
+  // TODO(jmesserly): if we had a common AST interface between these two nodes,
+  // we could remove this duplicated code.
+  bool _inferFunctionInvocationGeneric(FunctionExpressionInvocation node) {
+    DartType instantiatedType = node.staticInvokeType;
+    DartType originalType = node.function.staticType;
+    if (instantiatedType is FunctionType && originalType is FunctionType) {
+      FunctionType inferred = _inferGenericInvoke(instantiatedType,
+          originalType, node.typeArguments, node.argumentList);
+      if (inferred != null) {
+        node.staticInvokeType = inferred;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  FunctionType _inferGenericInvoke(FunctionType invokeType, FunctionType fnType,
+      TypeArgumentList typeArguments, ArgumentList argumentList) {
+    TypeSystem ts = _typeSystem;
+    if (typeArguments == null && ts is StrongTypeSystemImpl) {
+      if (fnType.typeFormals.isNotEmpty &&
+          ts.instantiateToBounds(fnType) == invokeType) {
+        // Get the parameters that correspond to the uninstantiated generic.
+        List<ParameterElement> rawParameters =
+            ResolverVisitor.resolveArgumentsToParameters(
+                argumentList, fnType.parameters, null);
+
+        List<DartType> paramTypes = <DartType>[];
+        List<DartType> argTypes = <DartType>[];
+        for (int i = 0, length = rawParameters.length; i < length; i++) {
+          ParameterElement parameter = rawParameters[i];
+          if (parameter != null) {
+            paramTypes.add(parameter.type);
+            argTypes.add(argumentList.arguments[i].staticType);
+          }
+        }
+
+        FunctionType inferred = ts.inferCallFromArguments(
+            _typeProvider, fnType, paramTypes, argTypes);
+
+        if (inferred != fnType) {
+          // Fix up the parameter elements based on inferred method.
+          List<ParameterElement> inferredParameters =
+              ResolverVisitor.resolveArgumentsToParameters(
+                  argumentList, inferred.parameters, null);
+          argumentList.correspondingStaticParameters = inferredParameters;
+          return inferred;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
    * Given a local variable declaration and its initializer, attempt to infer
    * a type for the local variable declaration based on the initializer.
    * Inference is only done if an explicit type is not present, and if
@@ -1802,42 +1859,17 @@
    * type variables, using the actual types of the arguments.
    */
   bool _inferMethodInvocationGeneric(MethodInvocation node) {
-    Element element = node.methodName.staticElement;
-    DartType invokeType = node.staticInvokeType;
-
-    TypeSystem ts = _typeSystem;
-    if (node.typeArguments == null &&
-        element is ExecutableElement &&
-        ts is StrongTypeSystemImpl) {
-      FunctionType fnType = element.type;
-      if (fnType.typeFormals.isNotEmpty &&
-          ts.instantiateToBounds(fnType) == invokeType) {
-        // Get the parameters that correspond to the uninstantiated generic.
-        List<ParameterElement> genericParameters =
-            ResolverVisitor.resolveArgumentsToParameters(
-                node.argumentList, fnType.parameters, null);
-
-        int length = genericParameters.length;
-        List<DartType> argTypes = new List<DartType>(length);
-        List<DartType> paramTypes = new List<DartType>(length);
-        for (int i = 0; i < length; i++) {
-          argTypes[i] = node.argumentList.arguments[i].staticType;
-          paramTypes[i] = genericParameters[i].type;
-        }
-
-        FunctionType inferred = ts.inferCallFromArguments(
-            _typeProvider, fnType, paramTypes, argTypes);
-
-        if (inferred != fnType) {
-          // Fix up the parameter elements based on inferred method.
-          List<ParameterElement> inferredParameters =
-              ResolverVisitor.resolveArgumentsToParameters(
-                  node.argumentList, inferred.parameters, null);
-          node.argumentList.correspondingStaticParameters = inferredParameters;
-          node.staticInvokeType = inferred;
-          _recordStaticType(node, inferred.returnType);
-          return true;
-        }
+    DartType instantiatedType = node.staticInvokeType;
+    DartType originalType = node.methodName.staticType;
+    // TODO(jmesserly): support generic `call` methods.
+    // Perhaps we should always record a FunctionType in staticInvokeType
+    // and the methodName's staticType.
+    if (instantiatedType is FunctionType && originalType is FunctionType) {
+      FunctionType inferred = _inferGenericInvoke(instantiatedType,
+          originalType, node.typeArguments, node.argumentList);
+      if (inferred != null) {
+        node.staticInvokeType = inferred;
+        return true;
       }
     }
     return false;
@@ -1890,7 +1922,7 @@
       return false;
     }
     DartType inferredType = inferredElement.type;
-    DartType nodeType = node.staticType;
+    DartType nodeType = node.staticInvokeType;
     if (nodeType != null &&
         nodeType.isDynamic &&
         inferredType is FunctionType &&
@@ -2082,47 +2114,6 @@
   }
 
   /**
-   * Implements the function "flatten" defined in the spec:
-   *
-   *   If T = Future<S> then flatten(T) = flatten(S).
-   *
-   *   Otherwise if T <: Future then let S be a type such that T << Future<S>
-   *   and for all R, if T << Future<R> then S << R.  Then flatten(T) = S.
-   *
-   *   In any other circumstance, flatten(T) = T.
-   */
-  static DartType flattenFutures(TypeProvider typeProvider, DartType type) {
-    if (type is InterfaceType) {
-      // Implement the case: "If T = Future<S> then flatten(T) = flatten(S)."
-      if (type.element == typeProvider.futureType.element &&
-          type.typeArguments.length > 0) {
-        return flattenFutures(typeProvider, type.typeArguments[0]);
-      }
-
-      // Implement the case: "Otherwise if T <: Future then let S be a type
-      // such that T << Future<S> and for all R, if T << Future<R> then S << R.
-      // Then flatten(T) = S."
-      //
-      // In other words, given the set of all types R such that T << Future<R>,
-      // let S be the most specific of those types, if any such S exists.
-      //
-      // Since we only care about the most specific type, it is sufficent to
-      // look at the types appearing as a parameter to Future in the type
-      // hierarchy of T.  We don't need to consider the supertypes of those
-      // types, since they are by definition less specific.
-      List<DartType> candidateTypes =
-          _searchTypeHierarchyForFutureParameters(typeProvider, type);
-      DartType flattenResult = _findMostSpecificType(candidateTypes);
-      if (flattenResult != null) {
-        return flattenResult;
-      }
-    }
-
-    // Implement the case: "In any other circumstance, flatten(T) = T."
-    return type;
-  }
-
-  /**
    * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
    * implement those tags.
    *
@@ -2190,88 +2181,6 @@
     map["video"] = "VideoElement";
     return map;
   }
-
-  /**
-   * If there is a single type which is at least as specific as all of the
-   * types in [types], return it.  Otherwise return `null`.
-   */
-  static DartType _findMostSpecificType(List<DartType> types) {
-    // The << relation ("more specific than") is a partial ordering on types,
-    // so to find the most specific type of a set, we keep a bucket of the most
-    // specific types seen so far such that no type in the bucket is more
-    // specific than any other type in the bucket.
-    List<DartType> bucket = <DartType>[];
-
-    // Then we consider each type in turn.
-    for (DartType type in types) {
-      // If any existing type in the bucket is more specific than this type,
-      // then we can ignore this type.
-      if (bucket.any((DartType t) => t.isMoreSpecificThan(type))) {
-        continue;
-      }
-      // Otherwise, we need to add this type to the bucket and remove any types
-      // that are less specific than it.
-      bool added = false;
-      int i = 0;
-      while (i < bucket.length) {
-        if (type.isMoreSpecificThan(bucket[i])) {
-          if (added) {
-            if (i < bucket.length - 1) {
-              bucket[i] = bucket.removeLast();
-            } else {
-              bucket.removeLast();
-            }
-          } else {
-            bucket[i] = type;
-            i++;
-            added = true;
-          }
-        } else {
-          i++;
-        }
-      }
-      if (!added) {
-        bucket.add(type);
-      }
-    }
-
-    // Now that we are finished, if there is exactly one type left in the
-    // bucket, it is the most specific type.
-    if (bucket.length == 1) {
-      return bucket[0];
-    }
-
-    // Otherwise, there is no single type that is more specific than the
-    // others.
-    return null;
-  }
-
-  /**
-   * Given a seed type [type], search its class hierarchy for types of the form
-   * Future<R>, and return a list of the resulting R's.
-   */
-  static List<DartType> _searchTypeHierarchyForFutureParameters(
-      TypeProvider typeProvider, InterfaceType type) {
-    List<DartType> result = <DartType>[];
-    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
-    void recurse(InterfaceType type) {
-      if (type.element == typeProvider.futureType.element &&
-          type.typeArguments.length > 0) {
-        result.add(type.typeArguments[0]);
-      }
-      if (visitedClasses.add(type.element)) {
-        if (type.superclass != null) {
-          recurse(type.superclass);
-        }
-        for (InterfaceType interface in type.interfaces) {
-          recurse(interface);
-        }
-        visitedClasses.remove(type.element);
-      }
-    }
-    recurse(type);
-    return result;
-  }
 }
 
 class _StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index c6892c2..c77192c 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -4,8 +4,9 @@
 
 library analyzer.src.generated.testing.ast_factory;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/ast.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 0dc3c7b..38c322e 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -6,11 +6,11 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 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/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -100,6 +100,7 @@
     ConstructorElementImpl constructor = name == null
         ? new ConstructorElementImpl("", -1)
         : new ConstructorElementImpl(name, 0);
+    constructor.synthetic = name == null;
     constructor.const2 = isConst;
     if (argumentTypes != null) {
       int count = argumentTypes.length;
@@ -405,11 +406,12 @@
     field.type = type;
     field.final2 = true;
     PropertyAccessorElementImpl getter =
-        new PropertyAccessorElementImpl.forVariable(field);
+        new PropertyAccessorElementImpl(name, 0);
     getter.synthetic = false;
     getter.getter = true;
     getter.variable = field;
     getter.returnType = type;
+    getter.static = isStatic;
     field.getter = getter;
     FunctionTypeImpl getterType = new FunctionTypeImpl(getter);
     getter.type = getterType;
@@ -559,8 +561,14 @@
     if (isConst) {
       ConstTopLevelVariableElementImpl constant =
           new ConstTopLevelVariableElementImpl(AstFactory.identifier3(name));
-      constant.constantInitializer = AstFactory.instanceCreationExpression2(
+      InstanceCreationExpression initializer = AstFactory.instanceCreationExpression2(
           Keyword.CONST, AstFactory.typeName(type.element));
+      if (type is InterfaceType) {
+        ConstructorElement element = type.element.unnamedConstructor;
+        initializer.staticElement = element;
+        initializer.constructorName.staticElement = element;
+      }
+      constant.constantInitializer = initializer;
       variable = constant;
     } else {
       variable = new TopLevelVariableElementImpl(name, -1);
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 5f1a49b..4bf5cc9 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -4,14 +4,17 @@
 
 library analyzer.src.generated.testing.test_type_provider;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 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/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source.dart' show Source;
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 
@@ -150,6 +153,14 @@
    */
   DartType _undefinedType;
 
+  /**
+   * The analysis context, if any. Used to create an appropriate 'dart:async'
+   * library to back `Future<T>`.
+   */
+  AnalysisContext _context;
+
+  TestTypeProvider([this._context]);
+
   @override
   InterfaceType get boolType {
     if (_boolType == null) {
@@ -181,8 +192,8 @@
     if (_deprecatedType == null) {
       ClassElementImpl deprecatedElement =
           ElementFactory.classElement2("Deprecated");
-      ConstructorElementImpl constructor = ElementFactory.constructorElement(
-          deprecatedElement, null, true, [stringType]);
+      ConstructorElementImpl constructor = ElementFactory
+          .constructorElement(deprecatedElement, '', true, [stringType]);
       constructor.constantInitializers = <ConstructorInitializer>[
         AstFactory.constructorFieldInitializer(
             true, 'expires', AstFactory.identifier3('expires'))
@@ -240,7 +251,18 @@
   @override
   InterfaceType get futureType {
     if (_futureType == null) {
-      _futureType = ElementFactory.classElement2("Future", ["T"]).type;
+      Source asyncSource = _context.sourceFactory.forUri(DartSdk.DART_ASYNC);
+      _context.setContents(asyncSource, "");
+      CompilationUnitElementImpl asyncUnit =
+          new CompilationUnitElementImpl("async.dart");
+      LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
+          _context, AstFactory.libraryIdentifier2(["dart.async"]));
+      asyncLibrary.definingCompilationUnit = asyncUnit;
+      asyncUnit.librarySource = asyncUnit.source = asyncSource;
+
+      ClassElementImpl future = ElementFactory.classElement2("Future", ["T"]);
+      _futureType = future.type;
+      asyncUnit.types = <ClassElement>[future];
     }
     return _futureType;
   }
@@ -274,7 +296,7 @@
         ElementFactory.getterElement("last", false, eType)
       ]);
       iterableElement.constructors = <ConstructorElement>[
-        ElementFactory.constructorElement(iterableElement, null, true)
+        ElementFactory.constructorElement(iterableElement, '', true)
           ..isCycleFree = true
       ];
       _propagateTypeArguments(iterableElement);
@@ -317,8 +339,8 @@
       ]);
       listElement.methods = <MethodElement>[
         ElementFactory.methodElement("[]", eType, [intType]),
-        ElementFactory.methodElement(
-            "[]=", VoidTypeImpl.instance, [intType, eType]),
+        ElementFactory
+            .methodElement("[]=", VoidTypeImpl.instance, [intType, eType]),
         ElementFactory.methodElement("add", VoidTypeImpl.instance, [eType])
       ];
       _propagateTypeArguments(listElement);
@@ -339,11 +361,11 @@
       ]);
       mapElement.methods = <MethodElement>[
         ElementFactory.methodElement("[]", vType, [objectType]),
-        ElementFactory.methodElement(
-            "[]=", VoidTypeImpl.instance, [kType, vType])
+        ElementFactory
+            .methodElement("[]=", VoidTypeImpl.instance, [kType, vType])
       ];
       mapElement.constructors = <ConstructorElement>[
-        ElementFactory.constructorElement(mapElement, null, false)
+        ElementFactory.constructorElement(mapElement, '', false)
           ..external = true
           ..factory = true
       ];
@@ -397,7 +419,7 @@
       ClassElementImpl objectElement = ElementFactory.object;
       _objectType = objectElement.type;
       ConstructorElementImpl constructor =
-          ElementFactory.constructorElement(objectElement, null, true);
+          ElementFactory.constructorElement(objectElement, '', true);
       constructor.constantInitializers = <ConstructorInitializer>[];
       objectElement.constructors = <ConstructorElement>[constructor];
       objectElement.methods = <MethodElement>[
@@ -475,8 +497,8 @@
   InterfaceType get symbolType {
     if (_symbolType == null) {
       ClassElementImpl symbolClass = ElementFactory.classElement2("Symbol");
-      ConstructorElementImpl constructor = ElementFactory.constructorElement(
-          symbolClass, null, true, [stringType]);
+      ConstructorElementImpl constructor = ElementFactory
+          .constructorElement(symbolClass, '', true, [stringType]);
       constructor.factory = true;
       constructor.isCycleFree = true;
       symbolClass.constructors = <ConstructorElement>[constructor];
@@ -555,10 +577,10 @@
       ElementFactory.methodElement("toInt", _intType),
       ElementFactory.methodElement("toDouble", _doubleType),
       ElementFactory.methodElement("toStringAsFixed", _stringType, [_intType]),
-      ElementFactory.methodElement(
-          "toStringAsExponential", _stringType, [_intType]),
-      ElementFactory.methodElement(
-          "toStringAsPrecision", _stringType, [_intType]),
+      ElementFactory
+          .methodElement("toStringAsExponential", _stringType, [_intType]),
+      ElementFactory
+          .methodElement("toStringAsPrecision", _stringType, [_intType]),
       ElementFactory.methodElement("toRadixString", _stringType, [_intType])
     ];
     intElement.methods = <MethodElement>[
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 911dfa9..b85205c 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -29,6 +29,12 @@
     return ft.parameters.any((p) => predicate(p.type));
   }
 
+  @override
+  bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from);
+
+  @override
+  bool isMoreSpecificThan(DartType t1, DartType t2) => isSubtypeOf(t1, t2);
+
   /**
    * Given a type t, if t is an interface type with a call method
    * defined, return the function type for the call method, otherwise
@@ -563,6 +569,25 @@
  */
 abstract class TypeSystem {
   /**
+   * Returns `true` if we can promote to the first type from the second type.
+   *
+   * In the standard Dart type system, it is not possible to promote from or to
+   * `dynamic`, and we must be promoting to a more specific type, see
+   * [isMoreSpecificThan].
+   *
+   * In strong mode, this is equivalent to [isSubtypeOf].
+   */
+  bool canPromoteToType(DartType to, DartType from);
+
+  /**
+   * Return `true` if the [leftType] is more specific than the [rightType]
+   * (that is, if leftType << rightType), as defined in the Dart language spec.
+   *
+   * In strong mode, this is equivalent to [isSubtypeOf].
+   */
+  bool isMoreSpecificThan(DartType leftType, DartType rightType);
+
+  /**
    * Compute the least upper bound of two types.
    */
   DartType getLeastUpperBound(
@@ -606,6 +631,18 @@
   TypeSystemImpl();
 
   @override
+  bool isMoreSpecificThan(DartType t1, DartType t2) =>
+      t1.isMoreSpecificThan(t2);
+
+  @override
+  bool canPromoteToType(DartType to, DartType from) {
+    // Declared type should not be "dynamic".
+    // Promoted type should not be "dynamic".
+    // Promoted type should be more specific than declared.
+    return !from.isDynamic && !to.isDynamic && to.isMoreSpecificThan(from);
+  }
+
+  @override
   DartType getLeastUpperBound(
       TypeProvider typeProvider, DartType type1, DartType type2) {
     // The least upper bound relation is reflexive.
diff --git a/pkg/analyzer/lib/src/generated/visitors.dart b/pkg/analyzer/lib/src/generated/visitors.dart
index 46e2a41..31e5ddc 100644
--- a/pkg/analyzer/lib/src/generated/visitors.dart
+++ b/pkg/analyzer/lib/src/generated/visitors.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.generated.visitors;
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 
 /// An [AstVisitor] that delegates calls to visit methods to all [delegates]
 /// before calling [visitChildren].
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index 07b0def..c2ad576 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/html_work_manager.dart';
 import 'package:analyzer/src/task/options_work_manager.dart';
+import 'package:analyzer/src/task/yaml.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:plugin/plugin.dart';
 
@@ -240,6 +241,10 @@
     registerExtension(taskId, DartScriptsTask.DESCRIPTOR);
     registerExtension(taskId, HtmlErrorsTask.DESCRIPTOR);
     registerExtension(taskId, ParseHtmlTask.DESCRIPTOR);
+    //
+    // Register YAML tasks.
+    //
+    registerExtension(taskId, ParseYamlTask.DESCRIPTOR);
   }
 
   void _registerWorkManagerFactoryExtensions(
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index 91d72a2..953741b 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.services.lint;
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index 3c7de13..c56b298 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -49,6 +49,9 @@
     return new BufferPointer._(_buffer, _offset + delta);
   }
 
+  double _getFloat64([int delta = 0]) =>
+      _buffer.getFloat64(_offset + delta, Endianness.LITTLE_ENDIAN);
+
   int _getInt32([int delta = 0]) =>
       _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN);
 
@@ -175,6 +178,22 @@
   }
 
   /**
+   * Add the [field] with the given 32-bit unsigned integer [value].  The field
+   * is not added if the [value] is equal to [def].
+   */
+  void addUint32(int field, int value, [int def]) {
+    if (_currentVTable == null) {
+      throw new StateError('Start a table before adding values.');
+    }
+    if (value != null && value != def) {
+      int size = 4;
+      _prepare(size, 1);
+      _trackField(field);
+      _setUint32AtTail(_buf, _tail, value);
+    }
+  }
+
+  /**
    * End the current table and return its offset.
    */
   Offset endTable() {
@@ -299,6 +318,26 @@
   }
 
   /**
+   * Write the given list of 64-bit float [values].
+   */
+  Offset writeListFloat64(List<double> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(8, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 8;
+    for (double value in values) {
+      _setFloat64AtTail(_buf, tail, value);
+      tail -= 8;
+    }
+    return result;
+  }
+
+  /**
    * Write the given list of signed 32-bit integer [values].
    */
   Offset writeListInt32(List<int> values) {
@@ -319,6 +358,26 @@
   }
 
   /**
+   * Write the given list of unsigned 32-bit integer [values].
+   */
+  Offset writeListUint32(List<int> values) {
+    if (_currentVTable != null) {
+      throw new StateError(
+          'Cannot write a non-scalar value while writing a table.');
+    }
+    _prepare(4, 1 + values.length);
+    Offset result = new Offset(_tail);
+    int tail = _tail;
+    _setUint32AtTail(_buf, tail, values.length);
+    tail -= 4;
+    for (int value in values) {
+      _setUint32AtTail(_buf, tail, value);
+      tail -= 4;
+    }
+    return result;
+  }
+
+  /**
    * Write the given string [value] and return its [Offset], or `null` if
    * the [value] is equal to [def].
    */
@@ -383,6 +442,10 @@
     _currentVTable.addField(field, _tail);
   }
 
+  static void _setFloat64AtTail(ByteData _buf, int tail, double x) {
+    _buf.setFloat64(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
+  }
+
   static void _setInt32AtTail(ByteData _buf, int tail, int x) {
     _buf.setInt32(_buf.lengthInBytes - tail, x, Endianness.LITTLE_ENDIAN);
   }
@@ -393,7 +456,22 @@
 }
 
 /**
- * The reader of 32-bit signed integers.
+ * The reader of lists of 64-bit float values.
+ *
+ * The returned unmodifiable lists lazily read values on access.
+ */
+class Float64ListReader extends Reader<List<double>> {
+  const Float64ListReader();
+
+  @override
+  int get size => 4;
+
+  @override
+  List<double> read(BufferPointer bp) => new _FbFloat64List(bp.derefObject());
+}
+
+/**
+ * The reader of signed 32-bit integers.
  */
 class Int32Reader extends Reader<int> {
   const Int32Reader() : super();
@@ -433,7 +511,7 @@
 
   @override
   List<E> read(BufferPointer bp) =>
-      new _FbList<E>(_elementReader, bp.derefObject());
+      new _FbInt32List<E>(_elementReader, bp.derefObject());
 }
 
 /**
@@ -519,14 +597,29 @@
   }
 }
 
-class _FbList<E> extends Object with ListMixin<E> implements List<E> {
-  final Reader<E> elementReader;
+/**
+ * The reader of unsigned 32-bit integers.
+ */
+class Uint32Reader extends Reader<int> {
+  const Uint32Reader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  int read(BufferPointer bp) => bp._getUint32();
+}
+
+/**
+ * The list backed by 64-bit values - Uint64 length and Float64.
+ */
+class _FbFloat64List extends _FbList<double> {
   final BufferPointer bp;
 
   int _length;
-  List<E> _items;
+  List<double> _items;
 
-  _FbList(this.elementReader, this.bp);
+  _FbFloat64List(this.bp);
 
   @override
   int get length {
@@ -535,20 +628,56 @@
   }
 
   @override
-  void set length(int i) =>
-      throw new StateError('Attempt to modify immutable list');
+  double operator [](int i) {
+    _items ??= new List<double>(length);
+    double item = _items[i];
+    if (item == null) {
+      BufferPointer ref = bp._advance(8 + 8 * i);
+      item = ref._getFloat64();
+      _items[i] = item;
+    }
+    return item;
+  }
+}
+
+/**
+ * The list backed by 32-bit values - offsets or integers.
+ */
+class _FbInt32List<E> extends _FbList<E> {
+  final Reader<E> elementReader;
+  final BufferPointer bp;
+
+  int _length;
+  List<E> _items;
+
+  _FbInt32List(this.elementReader, this.bp);
+
+  @override
+  int get length {
+    _length ??= bp._getUint32();
+    return _length;
+  }
 
   @override
   E operator [](int i) {
     _items ??= new List<E>(length);
     E item = _items[i];
     if (item == null) {
-      BufferPointer ref = bp._advance(4 + elementReader.size * i);
+      BufferPointer ref = bp._advance(4 + 4 * i);
       item = elementReader.read(ref);
       _items[i] = item;
     }
     return item;
   }
+}
+
+/**
+ * The base class for immutable lists read from flat buffers.
+ */
+abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
+  @override
+  void set length(int i) =>
+      throw new StateError('Attempt to modify immutable list');
 
   @override
   void operator []=(int i, E e) =>
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 97f9db6..4a0424b 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -12,42 +12,661 @@
 
 /**
  * Enum used to indicate the kind of entity referred to by a
- * [PrelinkedReference].
+ * [LinkedReference].
  */
-enum PrelinkedReferenceKind {
+enum ReferenceKind {
+  /**
+   * The entity is a class or enum.
+   */
   classOrEnum,
+
+  /**
+   * The entity is a constructor.
+   */
+  constructor,
+
+  /**
+   * The entity is a static const field.
+   */
+  constField,
+
+  /**
+   * The entity is a static method.
+   */
+  staticMethod,
+
+  /**
+   * The `length` property access.
+   */
+  length,
+
+  /**
+   * The entity is a typedef.
+   */
   typedef,
-  other,
+
+  /**
+   * The entity is a top level function.
+   */
+  topLevelFunction,
+
+  /**
+   * The entity is a top level getter or setter.
+   */
+  topLevelPropertyAccessor,
+
+  /**
+   * The entity is a prefix.
+   */
   prefix,
-  unresolved,
+
+  /**
+   * The entity being referred to does not exist.
+   */
+  unresolved
+}
+
+class _ReferenceKindReader extends fb.Reader<ReferenceKind> {
+  const _ReferenceKindReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  ReferenceKind read(fb.BufferPointer bp) {
+    int index = const fb.Uint32Reader().read(bp);
+    return ReferenceKind.values[index];
+  }
+}
+
+/**
+ * Enum representing the various kinds of operations which may be performed to
+ * produce a constant value.  These options are assumed to execute in the
+ * context of a stack which is initially empty.
+ */
+enum UnlinkedConstOperation {
+  /**
+   * Push the value of the n-th constructor argument (where n is obtained from
+   * [UnlinkedConst.ints]) onto the stack.
+   */
+  pushArgument,
+
+  /**
+   * Push the next value from [UnlinkedConst.ints] (a 32-bit unsigned integer)
+   * onto the stack.
+   *
+   * Note that Dart supports integers larger than 32 bits; these are
+   * represented by composing 32 bit values using the [shiftOr] operation.
+   */
+  pushInt,
+
+  /**
+   * Pop the top value off the stack, which should be an integer.  Multiply it
+   * by 2^32, "or" in the next value from [UnlinkedConst.ints] (which is
+   * interpreted as a 32-bit unsigned integer), and push the result back onto
+   * the stack.
+   */
+  shiftOr,
+
+  /**
+   * Push the next value from [UnlinkedConst.doubles] (a double precision
+   * floating point value) onto the stack.
+   */
+  pushDouble,
+
+  /**
+   * Push the constant `true` onto the stack.
+   */
+  pushTrue,
+
+  /**
+   * Push the constant `false` onto the stack.
+   */
+  pushFalse,
+
+  /**
+   * Push the next value from [UnlinkedConst.strings] onto the stack.
+   */
+  pushString,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), convert them to strings (if they aren't already),
+   * concatenate them into a single string, and push it back onto the stack.
+   *
+   * This operation is used to represent constants whose value is a literal
+   * string containing string interpolations.
+   */
+  concatenate,
+
+  /**
+   * Pop the top value from the stack which should be string, convert it to
+   * a symbol, and push it back onto the stack.
+   */
+  makeSymbol,
+
+  /**
+   * Push the constant `null` onto the stack.
+   */
+  pushNull,
+
+  /**
+   * Evaluate a (potentially qualified) identifier expression and push the
+   * resulting value onto the stack.  The identifier to be evaluated is
+   * obtained from [UnlinkedConst.references].
+   *
+   * This operation is used to represent the following kinds of constants
+   * (which are indistinguishable from an unresolved AST alone):
+   *
+   * - A qualified reference to a static constant variable (e.g. `C.v`, where
+   *   C is a class and `v` is a constant static variable in `C`).
+   * - An identifier expression referring to a constant variable.
+   * - A simple or qualified identifier denoting a class or type alias.
+   * - A simple or qualified identifier denoting a top-level function or a
+   *   static method.
+   */
+  pushReference,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke a constant constructor obtained
+   * from [UnlinkedConst.references], and push the resulting value back onto the
+   * stack.
+   *
+   * Note that for an invocation of the form `const a.b(...)` (where no type
+   * arguments are specified), it is impossible to tell from the unresolved AST
+   * alone whether `a` is a class name and `b` is a constructor name, or `a` is
+   * a prefix name and `b` is a class name.  For consistency between AST based
+   * and elements based summaries, references to default constructors are always
+   * recorded as references to corresponding classes.
+   */
+  invokeConstructor,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), place them in a [List], and push the result back
+   * onto the stack.  The type parameter for the [List] is implicitly `dynamic`.
+   */
+  makeUntypedList,
+
+  /**
+   * Pop the top 2*n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), interpret them as key/value pairs, place them in a
+   * [Map], and push the result back onto the stack.  The two type parameters
+   * for the [Map] are implicitly `dynamic`.
+   */
+  makeUntypedMap,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), place them in a [List], and push the result back
+   * onto the stack.  The type parameter for the [List] is obtained from
+   * [UnlinkedConst.references].
+   */
+  makeTypedList,
+
+  /**
+   * Pop the top 2*n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), interpret them as key/value pairs, place them in a
+   * [Map], and push the result back onto the stack.  The two type parameters for
+   * the [Map] are obtained from [UnlinkedConst.references].
+   */
+  makeTypedMap,
+
+  /**
+   * Pop the top 2 values from the stack, pass them to the predefined Dart
+   * function `identical`, and push the result back onto the stack.
+   */
+  identical,
+
+  /**
+   * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
+   * result back onto the stack.
+   *
+   * This is also used to represent `v1 != v2`, by composition with [not].
+   */
+  equal,
+
+  /**
+   * Pop the top value from the stack, compute its boolean negation, and push
+   * the result back onto the stack.
+   */
+  not,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 && v2`, and push the
+   * result back onto the stack.
+   */
+  and,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 || v2`, and push the
+   * result back onto the stack.
+   */
+  or,
+
+  /**
+   * Pop the top value from the stack, compute its integer complement, and push
+   * the result back onto the stack.
+   */
+  complement,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 ^ v2`, and push the
+   * result back onto the stack.
+   */
+  bitXor,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 & v2`, and push the
+   * result back onto the stack.
+   */
+  bitAnd,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 | v2`, and push the
+   * result back onto the stack.
+   */
+  bitOr,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 >> v2`, and push the
+   * result back onto the stack.
+   */
+  bitShiftRight,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 << v2`, and push the
+   * result back onto the stack.
+   */
+  bitShiftLeft,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 + v2`, and push the
+   * result back onto the stack.
+   */
+  add,
+
+  /**
+   * Pop the top value from the stack, compute its integer negation, and push
+   * the result back onto the stack.
+   */
+  negate,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 - v2`, and push the
+   * result back onto the stack.
+   */
+  subtract,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 * v2`, and push the
+   * result back onto the stack.
+   */
+  multiply,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 / v2`, and push the
+   * result back onto the stack.
+   */
+  divide,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 ~/ v2`, and push the
+   * result back onto the stack.
+   */
+  floorDivide,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 > v2`, and push the
+   * result back onto the stack.
+   */
+  greater,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 < v2`, and push the
+   * result back onto the stack.
+   */
+  less,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 >= v2`, and push the
+   * result back onto the stack.
+   */
+  greaterEqual,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 <= v2`, and push the
+   * result back onto the stack.
+   */
+  lessEqual,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 % v2`, and push the
+   * result back onto the stack.
+   */
+  modulo,
+
+  /**
+   * Pop the top 3 values from the stack, compute `v1 ? v2 : v3`, and push the
+   * result back onto the stack.
+   */
+  conditional,
+
+  /**
+   * Pop the top value from the stack, evaluate `v.length`, and push the result
+   * back onto the stack.
+   */
+  length
+}
+
+class _UnlinkedConstOperationReader extends fb.Reader<UnlinkedConstOperation> {
+  const _UnlinkedConstOperationReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  UnlinkedConstOperation read(fb.BufferPointer bp) {
+    int index = const fb.Uint32Reader().read(bp);
+    return UnlinkedConstOperation.values[index];
+  }
 }
 
 /**
  * Enum used to indicate the kind of an executable.
  */
 enum UnlinkedExecutableKind {
+  /**
+   * Executable is a function or method.
+   */
   functionOrMethod,
+
+  /**
+   * Executable is a getter.
+   */
   getter,
+
+  /**
+   * Executable is a setter.
+   */
   setter,
-  constructor,
+
+  /**
+   * Executable is a constructor.
+   */
+  constructor
+}
+
+class _UnlinkedExecutableKindReader extends fb.Reader<UnlinkedExecutableKind> {
+  const _UnlinkedExecutableKindReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  UnlinkedExecutableKind read(fb.BufferPointer bp) {
+    int index = const fb.Uint32Reader().read(bp);
+    return UnlinkedExecutableKind.values[index];
+  }
 }
 
 /**
  * Enum used to indicate the kind of a parameter.
  */
 enum UnlinkedParamKind {
+  /**
+   * Parameter is required.
+   */
   required,
+
+  /**
+   * Parameter is positional optional (enclosed in `[]`)
+   */
   positional,
-  named,
+
+  /**
+   * Parameter is named optional (enclosed in `{}`)
+   */
+  named
 }
 
-class PrelinkedDependencyBuilder {
+class _UnlinkedParamKindReader extends fb.Reader<UnlinkedParamKind> {
+  const _UnlinkedParamKindReader() : super();
+
+  @override
+  int get size => 4;
+
+  @override
+  UnlinkedParamKind read(fb.BufferPointer bp) {
+    int index = const fb.Uint32Reader().read(bp);
+    return UnlinkedParamKind.values[index];
+  }
+}
+
+class EntityRefBuilder extends Object with _EntityRefMixin implements EntityRef {
+  bool _finished = false;
+
+  int _slot;
+  int _reference;
+  int _paramReference;
+  List<EntityRefBuilder> _typeArguments;
+
+  @override
+  int get slot => _slot ??= 0;
+
+  /**
+   * If this [EntityRef] is contained within [LinkedUnit.types], slot id (which
+   * is unique within the compilation unit) identifying the target of type
+   * propagation or type inference with which this [EntityRef] is associated.
+   *
+   * Otherwise zero.
+   */
+  void set slot(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _slot = _value;
+  }
+
+  @override
+  int get reference => _reference ??= 0;
+
+  /**
+   * Index into [UnlinkedUnit.references] for the entity being referred to, or
+   * zero if this is a reference to a type parameter.
+   */
+  void set reference(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _reference = _value;
+  }
+
+  @override
+  int get paramReference => _paramReference ??= 0;
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  void set paramReference(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _paramReference = _value;
+  }
+
+  @override
+  List<EntityRefBuilder> get typeArguments => _typeArguments ??= <EntityRefBuilder>[];
+
+  /**
+   * If this is an instantiation of a generic type or generic executable, the
+   * type arguments used to instantiate it.  Trailing type arguments of type
+   * `dynamic` are omitted.
+   */
+  void set typeArguments(List<EntityRefBuilder> _value) {
+    assert(!_finished);
+    _typeArguments = _value;
+  }
+
+  EntityRefBuilder({int slot, int reference, int paramReference, List<EntityRefBuilder> typeArguments})
+    : _slot = slot,
+      _reference = reference,
+      _paramReference = paramReference,
+      _typeArguments = typeArguments;
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_typeArguments;
+    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
+      offset_typeArguments = fbBuilder.writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (_slot != null && _slot != 0) {
+      fbBuilder.addUint32(0, _slot);
+    }
+    if (_reference != null && _reference != 0) {
+      fbBuilder.addUint32(1, _reference);
+    }
+    if (_paramReference != null && _paramReference != 0) {
+      fbBuilder.addUint32(2, _paramReference);
+    }
+    if (offset_typeArguments != null) {
+      fbBuilder.addOffset(3, offset_typeArguments);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+/**
+ * Summary information about a reference to a an entity such as a type, top
+ * level executable, or executable within a class.
+ */
+abstract class EntityRef extends base.SummaryClass {
+
+  /**
+   * If this [EntityRef] is contained within [LinkedUnit.types], slot id (which
+   * is unique within the compilation unit) identifying the target of type
+   * propagation or type inference with which this [EntityRef] is associated.
+   *
+   * Otherwise zero.
+   */
+  int get slot;
+
+  /**
+   * Index into [UnlinkedUnit.references] for the entity being referred to, or
+   * zero if this is a reference to a type parameter.
+   */
+  int get reference;
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  int get paramReference;
+
+  /**
+   * If this is an instantiation of a generic type or generic executable, the
+   * type arguments used to instantiate it.  Trailing type arguments of type
+   * `dynamic` are omitted.
+   */
+  List<EntityRef> get typeArguments;
+}
+
+class _EntityRefReader extends fb.TableReader<_EntityRefImpl> {
+  const _EntityRefReader();
+
+  @override
+  _EntityRefImpl createObject(fb.BufferPointer bp) => new _EntityRefImpl(bp);
+}
+
+class _EntityRefImpl extends Object with _EntityRefMixin implements EntityRef {
+  final fb.BufferPointer _bp;
+
+  _EntityRefImpl(this._bp);
+
+  int _slot;
+  int _reference;
+  int _paramReference;
+  List<EntityRef> _typeArguments;
+
+  @override
+  int get slot {
+    _slot ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    return _slot;
+  }
+
+  @override
+  int get reference {
+    _reference ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    return _reference;
+  }
+
+  @override
+  int get paramReference {
+    _paramReference ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    return _paramReference;
+  }
+
+  @override
+  List<EntityRef> get typeArguments {
+    _typeArguments ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 3, const <EntityRef>[]);
+    return _typeArguments;
+  }
+}
+
+abstract class _EntityRefMixin implements EntityRef {
+  @override
+  Map<String, Object> toMap() => {
+    "slot": slot,
+    "reference": reference,
+    "paramReference": paramReference,
+    "typeArguments": typeArguments,
+  };
+}
+
+class LinkedDependencyBuilder extends Object with _LinkedDependencyMixin implements LinkedDependency {
   bool _finished = false;
 
   String _uri;
   List<String> _parts;
 
-  PrelinkedDependencyBuilder();
+  @override
+  String get uri => _uri ??= '';
 
   /**
    * The relative URI of the dependent library.  This URI is relative to the
@@ -61,6 +680,9 @@
     _uri = _value;
   }
 
+  @override
+  List<String> get parts => _parts ??= <String>[];
+
   /**
    * URI for the compilation units listed in the library's `part` declarations.
    * These URIs are relative to the importing library.
@@ -70,6 +692,10 @@
     _parts = _value;
   }
 
+  LinkedDependencyBuilder({String uri, List<String> parts})
+    : _uri = uri,
+      _parts = parts;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -92,18 +718,11 @@
   }
 }
 
-PrelinkedDependencyBuilder encodePrelinkedDependency({String uri, List<String> parts}) {
-  PrelinkedDependencyBuilder builder = new PrelinkedDependencyBuilder();
-  builder.uri = uri;
-  builder.parts = parts;
-  return builder;
-}
-
 /**
  * Information about a dependency that exists between one library and another
  * due to an "import" declaration.
  */
-abstract class PrelinkedDependency extends base.SummaryClass {
+abstract class LinkedDependency extends base.SummaryClass {
 
   /**
    * The relative URI of the dependent library.  This URI is relative to the
@@ -121,28 +740,22 @@
   List<String> get parts;
 }
 
-class _PrelinkedDependencyReader extends fb.TableReader<_PrelinkedDependencyImpl> {
-  const _PrelinkedDependencyReader();
+class _LinkedDependencyReader extends fb.TableReader<_LinkedDependencyImpl> {
+  const _LinkedDependencyReader();
 
   @override
-  _PrelinkedDependencyImpl createObject(fb.BufferPointer bp) => new _PrelinkedDependencyImpl(bp);
+  _LinkedDependencyImpl createObject(fb.BufferPointer bp) => new _LinkedDependencyImpl(bp);
 }
 
-class _PrelinkedDependencyImpl implements PrelinkedDependency {
+class _LinkedDependencyImpl extends Object with _LinkedDependencyMixin implements LinkedDependency {
   final fb.BufferPointer _bp;
 
-  _PrelinkedDependencyImpl(this._bp);
+  _LinkedDependencyImpl(this._bp);
 
   String _uri;
   List<String> _parts;
 
   @override
-  Map<String, Object> toMap() => {
-    "uri": uri,
-    "parts": parts,
-  };
-
-  @override
   String get uri {
     _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _uri;
@@ -155,52 +768,283 @@
   }
 }
 
-class PrelinkedLibraryBuilder {
+abstract class _LinkedDependencyMixin implements LinkedDependency {
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "parts": parts,
+  };
+}
+
+class LinkedExportNameBuilder extends Object with _LinkedExportNameMixin implements LinkedExportName {
   bool _finished = false;
 
-  List<PrelinkedUnitBuilder> _units;
-  List<PrelinkedDependencyBuilder> _dependencies;
-  List<int> _importDependencies;
+  String _name;
+  int _dependency;
+  int _unit;
+  ReferenceKind _kind;
 
-  PrelinkedLibraryBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
-   * The pre-linked summary of all the compilation units constituting the
+   * Name of the exported entity.  TODO(paulberry): do we include the trailing
+   * '=' for a setter?
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  @override
+  int get dependency => _dependency ??= 0;
+
+  /**
+   * Index into [LinkedLibrary.dependencies] for the library in which the
+   * entity is defined.
+   */
+  void set dependency(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _dependency = _value;
+  }
+
+  @override
+  int get unit => _unit ??= 0;
+
+  /**
+   * Integer index indicating which unit in the exported library contains the
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  void set unit(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _unit = _value;
+  }
+
+  @override
+  ReferenceKind get kind => _kind ??= ReferenceKind.classOrEnum;
+
+  /**
+   * The kind of the entity being referred to.
+   */
+  void set kind(ReferenceKind _value) {
+    assert(!_finished);
+    _kind = _value;
+  }
+
+  LinkedExportNameBuilder({String name, int dependency, int unit, ReferenceKind kind})
+    : _name = name,
+      _dependency = dependency,
+      _unit = unit,
+      _kind = kind;
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_dependency != null && _dependency != 0) {
+      fbBuilder.addUint32(1, _dependency);
+    }
+    if (_unit != null && _unit != 0) {
+      fbBuilder.addUint32(2, _unit);
+    }
+    if (_kind != null && _kind != ReferenceKind.classOrEnum) {
+      fbBuilder.addUint32(3, _kind.index);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+/**
+ * Information about a single name in the export namespace of the library that
+ * is not in the public namespace.
+ */
+abstract class LinkedExportName extends base.SummaryClass {
+
+  /**
+   * Name of the exported entity.  TODO(paulberry): do we include the trailing
+   * '=' for a setter?
+   */
+  String get name;
+
+  /**
+   * Index into [LinkedLibrary.dependencies] for the library in which the
+   * entity is defined.
+   */
+  int get dependency;
+
+  /**
+   * Integer index indicating which unit in the exported library contains the
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  int get unit;
+
+  /**
+   * The kind of the entity being referred to.
+   */
+  ReferenceKind get kind;
+}
+
+class _LinkedExportNameReader extends fb.TableReader<_LinkedExportNameImpl> {
+  const _LinkedExportNameReader();
+
+  @override
+  _LinkedExportNameImpl createObject(fb.BufferPointer bp) => new _LinkedExportNameImpl(bp);
+}
+
+class _LinkedExportNameImpl extends Object with _LinkedExportNameMixin implements LinkedExportName {
+  final fb.BufferPointer _bp;
+
+  _LinkedExportNameImpl(this._bp);
+
+  String _name;
+  int _dependency;
+  int _unit;
+  ReferenceKind _kind;
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get dependency {
+    _dependency ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    return _dependency;
+  }
+
+  @override
+  int get unit {
+    _unit ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    return _unit;
+  }
+
+  @override
+  ReferenceKind get kind {
+    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 3, ReferenceKind.classOrEnum);
+    return _kind;
+  }
+}
+
+abstract class _LinkedExportNameMixin implements LinkedExportName {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "dependency": dependency,
+    "unit": unit,
+    "kind": kind,
+  };
+}
+
+class LinkedLibraryBuilder extends Object with _LinkedLibraryMixin implements LinkedLibrary {
+  bool _finished = false;
+
+  List<LinkedUnitBuilder> _units;
+  List<LinkedDependencyBuilder> _dependencies;
+  List<int> _importDependencies;
+  List<LinkedExportNameBuilder> _exportNames;
+  int _numPrelinkedDependencies;
+
+  @override
+  List<LinkedUnitBuilder> get units => _units ??= <LinkedUnitBuilder>[];
+
+  /**
+   * The 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.
    */
-  void set units(List<PrelinkedUnitBuilder> _value) {
+  void set units(List<LinkedUnitBuilder> _value) {
     assert(!_finished);
     _units = _value;
   }
 
+  @override
+  List<LinkedDependencyBuilder> get dependencies => _dependencies ??= <LinkedDependencyBuilder>[];
+
   /**
    * The libraries that this library depends on (either via an explicit import
    * statement or via the implicit dependencies on `dart:core` and
    * `dart:async`).  The first element of this array is a pseudo-dependency
-   * representing the library itself (it is also used for "dynamic").
+   * representing the library itself (it is also used for `dynamic` and
+   * `void`).  This is followed by elements representing "prelinked"
+   * dependencies (direct imports and the transitive closure of exports).
+   * After the prelinked dependencies are elements representing "linked"
+   * dependencies.
    *
-   * TODO(paulberry): consider removing this entirely and just using
-   * [UnlinkedLibrary.imports].
+   * A library is only included as a "linked" dependency if it is a true
+   * dependency (e.g. a propagated or inferred type or constant value
+   * implicitly refers to an element declared in the library) or
+   * anti-dependency (e.g. the result of type propagation or type inference
+   * depends on the lack of a certain declaration in the library).
    */
-  void set dependencies(List<PrelinkedDependencyBuilder> _value) {
+  void set dependencies(List<LinkedDependencyBuilder> _value) {
     assert(!_finished);
     _dependencies = _value;
   }
 
+  @override
+  List<int> get importDependencies => _importDependencies ??= <int>[];
+
   /**
    * For each import in [UnlinkedUnit.imports], an index into [dependencies]
    * of the library being imported.
-   *
-   * TODO(paulberry): if [dependencies] is removed, this can be removed as
-   * well, since there will effectively be a one-to-one mapping.
    */
   void set importDependencies(List<int> _value) {
     assert(!_finished);
+    assert(_value == null || _value.every((e) => e >= 0));
     _importDependencies = _value;
   }
 
+  @override
+  List<LinkedExportNameBuilder> get exportNames => _exportNames ??= <LinkedExportNameBuilder>[];
+
+  /**
+   * Information about entities in the export namespace of the library that are
+   * not in the public namespace of the library (that is, entities that are
+   * brought into the namespace via `export` directives).
+   *
+   * Sorted by name.
+   */
+  void set exportNames(List<LinkedExportNameBuilder> _value) {
+    assert(!_finished);
+    _exportNames = _value;
+  }
+
+  @override
+  int get numPrelinkedDependencies => _numPrelinkedDependencies ??= 0;
+
+  /**
+   * The number of elements in [dependencies] which are not "linked"
+   * dependencies (that is, the number of libraries in the direct imports plus
+   * the transitive closure of exports, plus the library itself).
+   */
+  void set numPrelinkedDependencies(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _numPrelinkedDependencies = _value;
+  }
+
+  LinkedLibraryBuilder({List<LinkedUnitBuilder> units, List<LinkedDependencyBuilder> dependencies, List<int> importDependencies, List<LinkedExportNameBuilder> exportNames, int numPrelinkedDependencies})
+    : _units = units,
+      _dependencies = dependencies,
+      _importDependencies = importDependencies,
+      _exportNames = exportNames,
+      _numPrelinkedDependencies = numPrelinkedDependencies;
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder));
@@ -212,6 +1056,7 @@
     fb.Offset offset_units;
     fb.Offset offset_dependencies;
     fb.Offset offset_importDependencies;
+    fb.Offset offset_exportNames;
     if (!(_units == null || _units.isEmpty)) {
       offset_units = fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -219,7 +1064,10 @@
       offset_dependencies = fbBuilder.writeList(_dependencies.map((b) => b.finish(fbBuilder)).toList());
     }
     if (!(_importDependencies == null || _importDependencies.isEmpty)) {
-      offset_importDependencies = fbBuilder.writeListInt32(_importDependencies);
+      offset_importDependencies = fbBuilder.writeListUint32(_importDependencies);
+    }
+    if (!(_exportNames == null || _exportNames.isEmpty)) {
+      offset_exportNames = fbBuilder.writeList(_exportNames.map((b) => b.finish(fbBuilder)).toList());
     }
     fbBuilder.startTable();
     if (offset_units != null) {
@@ -231,195 +1079,263 @@
     if (offset_importDependencies != null) {
       fbBuilder.addOffset(2, offset_importDependencies);
     }
+    if (offset_exportNames != null) {
+      fbBuilder.addOffset(3, offset_exportNames);
+    }
+    if (_numPrelinkedDependencies != null && _numPrelinkedDependencies != 0) {
+      fbBuilder.addUint32(4, _numPrelinkedDependencies);
+    }
     return fbBuilder.endTable();
   }
 }
 
-PrelinkedLibraryBuilder encodePrelinkedLibrary({List<PrelinkedUnitBuilder> units, List<PrelinkedDependencyBuilder> dependencies, List<int> importDependencies}) {
-  PrelinkedLibraryBuilder builder = new PrelinkedLibraryBuilder();
-  builder.units = units;
-  builder.dependencies = dependencies;
-  builder.importDependencies = importDependencies;
-  return builder;
-}
-
 /**
- * Pre-linked summary of a library.
+ * Linked summary of a library.
  */
-abstract class PrelinkedLibrary extends base.SummaryClass {
-  factory PrelinkedLibrary.fromBuffer(List<int> buffer) {
+abstract class LinkedLibrary extends base.SummaryClass {
+  factory LinkedLibrary.fromBuffer(List<int> buffer) {
     fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-    return const _PrelinkedLibraryReader().read(rootRef);
+    return const _LinkedLibraryReader().read(rootRef);
   }
 
   /**
-   * The pre-linked summary of all the compilation units constituting the
+   * The 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.
    */
-  List<PrelinkedUnit> get units;
+  List<LinkedUnit> get units;
 
   /**
    * The libraries that this library depends on (either via an explicit import
    * statement or via the implicit dependencies on `dart:core` and
    * `dart:async`).  The first element of this array is a pseudo-dependency
-   * representing the library itself (it is also used for "dynamic").
+   * representing the library itself (it is also used for `dynamic` and
+   * `void`).  This is followed by elements representing "prelinked"
+   * dependencies (direct imports and the transitive closure of exports).
+   * After the prelinked dependencies are elements representing "linked"
+   * dependencies.
    *
-   * TODO(paulberry): consider removing this entirely and just using
-   * [UnlinkedLibrary.imports].
+   * A library is only included as a "linked" dependency if it is a true
+   * dependency (e.g. a propagated or inferred type or constant value
+   * implicitly refers to an element declared in the library) or
+   * anti-dependency (e.g. the result of type propagation or type inference
+   * depends on the lack of a certain declaration in the library).
    */
-  List<PrelinkedDependency> get dependencies;
+  List<LinkedDependency> get dependencies;
 
   /**
    * For each import in [UnlinkedUnit.imports], an index into [dependencies]
    * of the library being imported.
-   *
-   * TODO(paulberry): if [dependencies] is removed, this can be removed as
-   * well, since there will effectively be a one-to-one mapping.
    */
   List<int> get importDependencies;
+
+  /**
+   * Information about entities in the export namespace of the library that are
+   * not in the public namespace of the library (that is, entities that are
+   * brought into the namespace via `export` directives).
+   *
+   * Sorted by name.
+   */
+  List<LinkedExportName> get exportNames;
+
+  /**
+   * The number of elements in [dependencies] which are not "linked"
+   * dependencies (that is, the number of libraries in the direct imports plus
+   * the transitive closure of exports, plus the library itself).
+   */
+  int get numPrelinkedDependencies;
 }
 
-class _PrelinkedLibraryReader extends fb.TableReader<_PrelinkedLibraryImpl> {
-  const _PrelinkedLibraryReader();
+class _LinkedLibraryReader extends fb.TableReader<_LinkedLibraryImpl> {
+  const _LinkedLibraryReader();
 
   @override
-  _PrelinkedLibraryImpl createObject(fb.BufferPointer bp) => new _PrelinkedLibraryImpl(bp);
+  _LinkedLibraryImpl createObject(fb.BufferPointer bp) => new _LinkedLibraryImpl(bp);
 }
 
-class _PrelinkedLibraryImpl implements PrelinkedLibrary {
+class _LinkedLibraryImpl extends Object with _LinkedLibraryMixin implements LinkedLibrary {
   final fb.BufferPointer _bp;
 
-  _PrelinkedLibraryImpl(this._bp);
+  _LinkedLibraryImpl(this._bp);
 
-  List<PrelinkedUnit> _units;
-  List<PrelinkedDependency> _dependencies;
+  List<LinkedUnit> _units;
+  List<LinkedDependency> _dependencies;
   List<int> _importDependencies;
+  List<LinkedExportName> _exportNames;
+  int _numPrelinkedDependencies;
 
   @override
-  Map<String, Object> toMap() => {
-    "units": units,
-    "dependencies": dependencies,
-    "importDependencies": importDependencies,
-  };
-
-  @override
-  List<PrelinkedUnit> get units {
-    _units ??= const fb.ListReader<PrelinkedUnit>(const _PrelinkedUnitReader()).vTableGet(_bp, 0, const <PrelinkedUnit>[]);
+  List<LinkedUnit> get units {
+    _units ??= const fb.ListReader<LinkedUnit>(const _LinkedUnitReader()).vTableGet(_bp, 0, const <LinkedUnit>[]);
     return _units;
   }
 
   @override
-  List<PrelinkedDependency> get dependencies {
-    _dependencies ??= const fb.ListReader<PrelinkedDependency>(const _PrelinkedDependencyReader()).vTableGet(_bp, 1, const <PrelinkedDependency>[]);
+  List<LinkedDependency> get dependencies {
+    _dependencies ??= const fb.ListReader<LinkedDependency>(const _LinkedDependencyReader()).vTableGet(_bp, 1, const <LinkedDependency>[]);
     return _dependencies;
   }
 
   @override
   List<int> get importDependencies {
-    _importDependencies ??= const fb.ListReader<int>(const fb.Int32Reader()).vTableGet(_bp, 2, const <int>[]);
+    _importDependencies ??= const fb.ListReader<int>(const fb.Uint32Reader()).vTableGet(_bp, 2, const <int>[]);
     return _importDependencies;
   }
+
+  @override
+  List<LinkedExportName> get exportNames {
+    _exportNames ??= const fb.ListReader<LinkedExportName>(const _LinkedExportNameReader()).vTableGet(_bp, 3, const <LinkedExportName>[]);
+    return _exportNames;
+  }
+
+  @override
+  int get numPrelinkedDependencies {
+    _numPrelinkedDependencies ??= const fb.Uint32Reader().vTableGet(_bp, 4, 0);
+    return _numPrelinkedDependencies;
+  }
 }
 
-class PrelinkedReferenceBuilder {
+abstract class _LinkedLibraryMixin implements LinkedLibrary {
+  @override
+  Map<String, Object> toMap() => {
+    "units": units,
+    "dependencies": dependencies,
+    "importDependencies": importDependencies,
+    "exportNames": exportNames,
+    "numPrelinkedDependencies": numPrelinkedDependencies,
+  };
+}
+
+class LinkedReferenceBuilder extends Object with _LinkedReferenceMixin implements LinkedReference {
   bool _finished = false;
 
   int _dependency;
-  PrelinkedReferenceKind _kind;
+  ReferenceKind _kind;
   int _unit;
   int _numTypeParameters;
+  String _name;
 
-  PrelinkedReferenceBuilder();
+  @override
+  int get dependency => _dependency ??= 0;
 
   /**
-   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * Index into [LinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
    */
   void set dependency(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _dependency = _value;
   }
 
+  @override
+  ReferenceKind get kind => _kind ??= ReferenceKind.classOrEnum;
+
   /**
-   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
-   * the kind is [PrelinkedReferenceKind.classOrEnum].
+   * The kind of the entity being referred to.  For the pseudo-types `dynamic`
+   * and `void`, the kind is [ReferenceKind.classOrEnum].
    */
-  void set kind(PrelinkedReferenceKind _value) {
+  void set kind(ReferenceKind _value) {
     assert(!_finished);
     _kind = _value;
   }
 
+  @override
+  int get unit => _unit ??= 0;
+
   /**
    * Integer index indicating which unit in the imported library contains the
-   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
    */
   void set unit(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _unit = _value;
   }
 
+  @override
+  int get numTypeParameters => _numTypeParameters ??= 0;
+
   /**
    * If the entity being referred to is generic, the number of type parameters
    * it accepts.  Otherwise zero.
    */
   void set numTypeParameters(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _numTypeParameters = _value;
   }
 
+  @override
+  String get name => _name ??= '';
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  LinkedReferenceBuilder({int dependency, ReferenceKind kind, int unit, int numTypeParameters, String name})
+    : _dependency = dependency,
+      _kind = kind,
+      _unit = unit,
+      _numTypeParameters = numTypeParameters,
+      _name = name;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
     fbBuilder.startTable();
     if (_dependency != null && _dependency != 0) {
-      fbBuilder.addInt32(0, _dependency);
+      fbBuilder.addUint32(0, _dependency);
     }
-    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
-      fbBuilder.addInt32(1, _kind.index);
+    if (_kind != null && _kind != ReferenceKind.classOrEnum) {
+      fbBuilder.addUint32(1, _kind.index);
     }
     if (_unit != null && _unit != 0) {
-      fbBuilder.addInt32(2, _unit);
+      fbBuilder.addUint32(2, _unit);
     }
     if (_numTypeParameters != null && _numTypeParameters != 0) {
-      fbBuilder.addInt32(3, _numTypeParameters);
+      fbBuilder.addUint32(3, _numTypeParameters);
+    }
+    if (offset_name != null) {
+      fbBuilder.addOffset(4, offset_name);
     }
     return fbBuilder.endTable();
   }
 }
 
-PrelinkedReferenceBuilder encodePrelinkedReference({int dependency, PrelinkedReferenceKind kind, int unit, int numTypeParameters}) {
-  PrelinkedReferenceBuilder builder = new PrelinkedReferenceBuilder();
-  builder.dependency = dependency;
-  builder.kind = kind;
-  builder.unit = unit;
-  builder.numTypeParameters = numTypeParameters;
-  return builder;
-}
-
 /**
  * Information about the resolution of an [UnlinkedReference].
  */
-abstract class PrelinkedReference extends base.SummaryClass {
+abstract class LinkedReference extends base.SummaryClass {
 
   /**
-   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * Index into [LinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
    */
   int get dependency;
 
   /**
-   * The kind of the entity being referred to.  For the pseudo-type `dynamic`,
-   * the kind is [PrelinkedReferenceKind.classOrEnum].
+   * The kind of the entity being referred to.  For the pseudo-types `dynamic`
+   * and `void`, the kind is [ReferenceKind.classOrEnum].
    */
-  PrelinkedReferenceKind get kind;
+  ReferenceKind get kind;
 
   /**
    * Integer index indicating which unit in the imported library contains the
-   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
    */
@@ -430,159 +1346,226 @@
    * it accepts.  Otherwise zero.
    */
   int get numTypeParameters;
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
+   */
+  String get name;
 }
 
-class _PrelinkedReferenceReader extends fb.TableReader<_PrelinkedReferenceImpl> {
-  const _PrelinkedReferenceReader();
+class _LinkedReferenceReader extends fb.TableReader<_LinkedReferenceImpl> {
+  const _LinkedReferenceReader();
 
   @override
-  _PrelinkedReferenceImpl createObject(fb.BufferPointer bp) => new _PrelinkedReferenceImpl(bp);
+  _LinkedReferenceImpl createObject(fb.BufferPointer bp) => new _LinkedReferenceImpl(bp);
 }
 
-class _PrelinkedReferenceImpl implements PrelinkedReference {
+class _LinkedReferenceImpl extends Object with _LinkedReferenceMixin implements LinkedReference {
   final fb.BufferPointer _bp;
 
-  _PrelinkedReferenceImpl(this._bp);
+  _LinkedReferenceImpl(this._bp);
 
   int _dependency;
-  PrelinkedReferenceKind _kind;
+  ReferenceKind _kind;
   int _unit;
   int _numTypeParameters;
+  String _name;
 
   @override
+  int get dependency {
+    _dependency ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    return _dependency;
+  }
+
+  @override
+  ReferenceKind get kind {
+    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 1, ReferenceKind.classOrEnum);
+    return _kind;
+  }
+
+  @override
+  int get unit {
+    _unit ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    return _unit;
+  }
+
+  @override
+  int get numTypeParameters {
+    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    return _numTypeParameters;
+  }
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 4, '');
+    return _name;
+  }
+}
+
+abstract class _LinkedReferenceMixin implements LinkedReference {
+  @override
   Map<String, Object> toMap() => {
     "dependency": dependency,
     "kind": kind,
     "unit": unit,
     "numTypeParameters": numTypeParameters,
+    "name": name,
   };
-
-  @override
-  int get dependency {
-    _dependency ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
-    return _dependency;
-  }
-
-  @override
-  PrelinkedReferenceKind get kind {
-    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
-    return _kind;
-  }
-
-  @override
-  int get unit {
-    _unit ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
-    return _unit;
-  }
-
-  @override
-  int get numTypeParameters {
-    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 3, 0);
-    return _numTypeParameters;
-  }
 }
 
-class PrelinkedUnitBuilder {
+class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements LinkedUnit {
   bool _finished = false;
 
-  List<PrelinkedReferenceBuilder> _references;
+  List<LinkedReferenceBuilder> _references;
+  List<EntityRefBuilder> _types;
 
-  PrelinkedUnitBuilder();
+  @override
+  List<LinkedReferenceBuilder> get references => _references ??= <LinkedReferenceBuilder>[];
 
   /**
-   * For each reference in [UnlinkedUnit.references], information about how
-   * that reference is resolved.
+   * Information about the resolution of references within the compilation
+   * unit.  Each element of [UnlinkedUnit.references] has a corresponding
+   * element in this list (at the same index).  If this list has additional
+   * elements beyond the number of elements in [UnlinkedUnit.references], those
+   * additional elements are references that are only referred to implicitly
+   * (e.g. elements involved in inferred or propagated types).
    */
-  void set references(List<PrelinkedReferenceBuilder> _value) {
+  void set references(List<LinkedReferenceBuilder> _value) {
     assert(!_finished);
     _references = _value;
   }
 
+  @override
+  List<EntityRefBuilder> get types => _types ??= <EntityRefBuilder>[];
+
+  /**
+   * List associating slot ids found inside the unlinked summary for the
+   * compilation unit with propagated and inferred types.
+   */
+  void set types(List<EntityRefBuilder> _value) {
+    assert(!_finished);
+    _types = _value;
+  }
+
+  LinkedUnitBuilder({List<LinkedReferenceBuilder> references, List<EntityRefBuilder> types})
+    : _references = references,
+      _types = types;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
     fb.Offset offset_references;
+    fb.Offset offset_types;
     if (!(_references == null || _references.isEmpty)) {
       offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (!(_types == null || _types.isEmpty)) {
+      offset_types = fbBuilder.writeList(_types.map((b) => b.finish(fbBuilder)).toList());
+    }
     fbBuilder.startTable();
     if (offset_references != null) {
       fbBuilder.addOffset(0, offset_references);
     }
+    if (offset_types != null) {
+      fbBuilder.addOffset(1, offset_types);
+    }
     return fbBuilder.endTable();
   }
 }
 
-PrelinkedUnitBuilder encodePrelinkedUnit({List<PrelinkedReferenceBuilder> references}) {
-  PrelinkedUnitBuilder builder = new PrelinkedUnitBuilder();
-  builder.references = references;
-  return builder;
-}
-
 /**
- * Pre-linked summary of a compilation unit.
+ * Linked summary of a compilation unit.
  */
-abstract class PrelinkedUnit extends base.SummaryClass {
+abstract class LinkedUnit extends base.SummaryClass {
 
   /**
-   * For each reference in [UnlinkedUnit.references], information about how
-   * that reference is resolved.
+   * Information about the resolution of references within the compilation
+   * unit.  Each element of [UnlinkedUnit.references] has a corresponding
+   * element in this list (at the same index).  If this list has additional
+   * elements beyond the number of elements in [UnlinkedUnit.references], those
+   * additional elements are references that are only referred to implicitly
+   * (e.g. elements involved in inferred or propagated types).
    */
-  List<PrelinkedReference> get references;
+  List<LinkedReference> get references;
+
+  /**
+   * List associating slot ids found inside the unlinked summary for the
+   * compilation unit with propagated and inferred types.
+   */
+  List<EntityRef> get types;
 }
 
-class _PrelinkedUnitReader extends fb.TableReader<_PrelinkedUnitImpl> {
-  const _PrelinkedUnitReader();
+class _LinkedUnitReader extends fb.TableReader<_LinkedUnitImpl> {
+  const _LinkedUnitReader();
 
   @override
-  _PrelinkedUnitImpl createObject(fb.BufferPointer bp) => new _PrelinkedUnitImpl(bp);
+  _LinkedUnitImpl createObject(fb.BufferPointer bp) => new _LinkedUnitImpl(bp);
 }
 
-class _PrelinkedUnitImpl implements PrelinkedUnit {
+class _LinkedUnitImpl extends Object with _LinkedUnitMixin implements LinkedUnit {
   final fb.BufferPointer _bp;
 
-  _PrelinkedUnitImpl(this._bp);
+  _LinkedUnitImpl(this._bp);
 
-  List<PrelinkedReference> _references;
+  List<LinkedReference> _references;
+  List<EntityRef> _types;
 
   @override
+  List<LinkedReference> get references {
+    _references ??= const fb.ListReader<LinkedReference>(const _LinkedReferenceReader()).vTableGet(_bp, 0, const <LinkedReference>[]);
+    return _references;
+  }
+
+  @override
+  List<EntityRef> get types {
+    _types ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 1, const <EntityRef>[]);
+    return _types;
+  }
+}
+
+abstract class _LinkedUnitMixin implements LinkedUnit {
+  @override
   Map<String, Object> toMap() => {
     "references": references,
+    "types": types,
   };
-
-  @override
-  List<PrelinkedReference> get references {
-    _references ??= const fb.ListReader<PrelinkedReference>(const _PrelinkedReferenceReader()).vTableGet(_bp, 0, const <PrelinkedReference>[]);
-    return _references;
-  }
 }
 
-class SdkBundleBuilder {
+class SdkBundleBuilder extends Object with _SdkBundleMixin implements SdkBundle {
   bool _finished = false;
 
-  List<String> _prelinkedLibraryUris;
-  List<PrelinkedLibraryBuilder> _prelinkedLibraries;
+  List<String> _linkedLibraryUris;
+  List<LinkedLibraryBuilder> _linkedLibraries;
   List<String> _unlinkedUnitUris;
   List<UnlinkedUnitBuilder> _unlinkedUnits;
 
-  SdkBundleBuilder();
+  @override
+  List<String> get linkedLibraryUris => _linkedLibraryUris ??= <String>[];
 
   /**
-   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   * The list of URIs of items in [linkedLibraries], e.g. `dart:core`.
    */
-  void set prelinkedLibraryUris(List<String> _value) {
+  void set linkedLibraryUris(List<String> _value) {
     assert(!_finished);
-    _prelinkedLibraryUris = _value;
+    _linkedLibraryUris = _value;
   }
 
+  @override
+  List<LinkedLibraryBuilder> get linkedLibraries => _linkedLibraries ??= <LinkedLibraryBuilder>[];
+
   /**
-   * Pre-linked libraries.
+   * Linked libraries.
    */
-  void set prelinkedLibraries(List<PrelinkedLibraryBuilder> _value) {
+  void set linkedLibraries(List<LinkedLibraryBuilder> _value) {
     assert(!_finished);
-    _prelinkedLibraries = _value;
+    _linkedLibraries = _value;
   }
 
+  @override
+  List<String> get unlinkedUnitUris => _unlinkedUnitUris ??= <String>[];
+
   /**
    * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
    */
@@ -591,6 +1574,9 @@
     _unlinkedUnitUris = _value;
   }
 
+  @override
+  List<UnlinkedUnitBuilder> get unlinkedUnits => _unlinkedUnits ??= <UnlinkedUnitBuilder>[];
+
   /**
    * Unlinked information for the compilation units constituting the SDK.
    */
@@ -599,6 +1585,12 @@
     _unlinkedUnits = _value;
   }
 
+  SdkBundleBuilder({List<String> linkedLibraryUris, List<LinkedLibraryBuilder> linkedLibraries, List<String> unlinkedUnitUris, List<UnlinkedUnitBuilder> unlinkedUnits})
+    : _linkedLibraryUris = linkedLibraryUris,
+      _linkedLibraries = linkedLibraries,
+      _unlinkedUnitUris = unlinkedUnitUris,
+      _unlinkedUnits = unlinkedUnits;
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder));
@@ -607,15 +1599,15 @@
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    fb.Offset offset_prelinkedLibraryUris;
-    fb.Offset offset_prelinkedLibraries;
+    fb.Offset offset_linkedLibraryUris;
+    fb.Offset offset_linkedLibraries;
     fb.Offset offset_unlinkedUnitUris;
     fb.Offset offset_unlinkedUnits;
-    if (!(_prelinkedLibraryUris == null || _prelinkedLibraryUris.isEmpty)) {
-      offset_prelinkedLibraryUris = fbBuilder.writeList(_prelinkedLibraryUris.map((b) => fbBuilder.writeString(b)).toList());
+    if (!(_linkedLibraryUris == null || _linkedLibraryUris.isEmpty)) {
+      offset_linkedLibraryUris = fbBuilder.writeList(_linkedLibraryUris.map((b) => fbBuilder.writeString(b)).toList());
     }
-    if (!(_prelinkedLibraries == null || _prelinkedLibraries.isEmpty)) {
-      offset_prelinkedLibraries = fbBuilder.writeList(_prelinkedLibraries.map((b) => b.finish(fbBuilder)).toList());
+    if (!(_linkedLibraries == null || _linkedLibraries.isEmpty)) {
+      offset_linkedLibraries = fbBuilder.writeList(_linkedLibraries.map((b) => b.finish(fbBuilder)).toList());
     }
     if (!(_unlinkedUnitUris == null || _unlinkedUnitUris.isEmpty)) {
       offset_unlinkedUnitUris = fbBuilder.writeList(_unlinkedUnitUris.map((b) => fbBuilder.writeString(b)).toList());
@@ -624,11 +1616,11 @@
       offset_unlinkedUnits = fbBuilder.writeList(_unlinkedUnits.map((b) => b.finish(fbBuilder)).toList());
     }
     fbBuilder.startTable();
-    if (offset_prelinkedLibraryUris != null) {
-      fbBuilder.addOffset(0, offset_prelinkedLibraryUris);
+    if (offset_linkedLibraryUris != null) {
+      fbBuilder.addOffset(0, offset_linkedLibraryUris);
     }
-    if (offset_prelinkedLibraries != null) {
-      fbBuilder.addOffset(1, offset_prelinkedLibraries);
+    if (offset_linkedLibraries != null) {
+      fbBuilder.addOffset(1, offset_linkedLibraries);
     }
     if (offset_unlinkedUnitUris != null) {
       fbBuilder.addOffset(2, offset_unlinkedUnitUris);
@@ -640,15 +1632,6 @@
   }
 }
 
-SdkBundleBuilder encodeSdkBundle({List<String> prelinkedLibraryUris, List<PrelinkedLibraryBuilder> prelinkedLibraries, List<String> unlinkedUnitUris, List<UnlinkedUnitBuilder> unlinkedUnits}) {
-  SdkBundleBuilder builder = new SdkBundleBuilder();
-  builder.prelinkedLibraryUris = prelinkedLibraryUris;
-  builder.prelinkedLibraries = prelinkedLibraries;
-  builder.unlinkedUnitUris = unlinkedUnitUris;
-  builder.unlinkedUnits = unlinkedUnits;
-  return builder;
-}
-
 /**
  * Information about SDK.
  */
@@ -659,14 +1642,14 @@
   }
 
   /**
-   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   * The list of URIs of items in [linkedLibraries], e.g. `dart:core`.
    */
-  List<String> get prelinkedLibraryUris;
+  List<String> get linkedLibraryUris;
 
   /**
-   * Pre-linked libraries.
+   * Linked libraries.
    */
-  List<PrelinkedLibrary> get prelinkedLibraries;
+  List<LinkedLibrary> get linkedLibraries;
 
   /**
    * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
@@ -686,34 +1669,26 @@
   _SdkBundleImpl createObject(fb.BufferPointer bp) => new _SdkBundleImpl(bp);
 }
 
-class _SdkBundleImpl implements SdkBundle {
+class _SdkBundleImpl extends Object with _SdkBundleMixin implements SdkBundle {
   final fb.BufferPointer _bp;
 
   _SdkBundleImpl(this._bp);
 
-  List<String> _prelinkedLibraryUris;
-  List<PrelinkedLibrary> _prelinkedLibraries;
+  List<String> _linkedLibraryUris;
+  List<LinkedLibrary> _linkedLibraries;
   List<String> _unlinkedUnitUris;
   List<UnlinkedUnit> _unlinkedUnits;
 
   @override
-  Map<String, Object> toMap() => {
-    "prelinkedLibraryUris": prelinkedLibraryUris,
-    "prelinkedLibraries": prelinkedLibraries,
-    "unlinkedUnitUris": unlinkedUnitUris,
-    "unlinkedUnits": unlinkedUnits,
-  };
-
-  @override
-  List<String> get prelinkedLibraryUris {
-    _prelinkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
-    return _prelinkedLibraryUris;
+  List<String> get linkedLibraryUris {
+    _linkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    return _linkedLibraryUris;
   }
 
   @override
-  List<PrelinkedLibrary> get prelinkedLibraries {
-    _prelinkedLibraries ??= const fb.ListReader<PrelinkedLibrary>(const _PrelinkedLibraryReader()).vTableGet(_bp, 1, const <PrelinkedLibrary>[]);
-    return _prelinkedLibraries;
+  List<LinkedLibrary> get linkedLibraries {
+    _linkedLibraries ??= const fb.ListReader<LinkedLibrary>(const _LinkedLibraryReader()).vTableGet(_bp, 1, const <LinkedLibrary>[]);
+    return _linkedLibraries;
   }
 
   @override
@@ -729,23 +1704,34 @@
   }
 }
 
-class UnlinkedClassBuilder {
+abstract class _SdkBundleMixin implements SdkBundle {
+  @override
+  Map<String, Object> toMap() => {
+    "linkedLibraryUris": linkedLibraryUris,
+    "linkedLibraries": linkedLibraries,
+    "unlinkedUnitUris": unlinkedUnitUris,
+    "unlinkedUnits": unlinkedUnits,
+  };
+}
+
+class UnlinkedClassBuilder extends Object with _UnlinkedClassMixin implements UnlinkedClass {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
   UnlinkedDocumentationCommentBuilder _documentationComment;
   List<UnlinkedTypeParamBuilder> _typeParameters;
-  UnlinkedTypeRefBuilder _supertype;
-  List<UnlinkedTypeRefBuilder> _mixins;
-  List<UnlinkedTypeRefBuilder> _interfaces;
+  EntityRefBuilder _supertype;
+  List<EntityRefBuilder> _mixins;
+  List<EntityRefBuilder> _interfaces;
   List<UnlinkedVariableBuilder> _fields;
   List<UnlinkedExecutableBuilder> _executables;
   bool _isAbstract;
   bool _isMixinApplication;
   bool _hasNoSupertype;
 
-  UnlinkedClassBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the class.
@@ -755,14 +1741,21 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the class name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the class, or `null` if there is no
    * documentation comment.
@@ -772,6 +1765,9 @@
     _documentationComment = _value;
   }
 
+  @override
+  List<UnlinkedTypeParamBuilder> get typeParameters => _typeParameters ??= <UnlinkedTypeParamBuilder>[];
+
   /**
    * Type parameters of the class, if any.
    */
@@ -780,32 +1776,44 @@
     _typeParameters = _value;
   }
 
+  @override
+  EntityRefBuilder get supertype => _supertype;
+
   /**
    * Supertype of the class, or `null` if either (a) the class doesn't
    * explicitly declare a supertype (and hence has supertype `Object`), or (b)
    * the class *is* `Object` (and hence has no supertype).
    */
-  void set supertype(UnlinkedTypeRefBuilder _value) {
+  void set supertype(EntityRefBuilder _value) {
     assert(!_finished);
     _supertype = _value;
   }
 
+  @override
+  List<EntityRefBuilder> get mixins => _mixins ??= <EntityRefBuilder>[];
+
   /**
    * Mixins appearing in a `with` clause, if any.
    */
-  void set mixins(List<UnlinkedTypeRefBuilder> _value) {
+  void set mixins(List<EntityRefBuilder> _value) {
     assert(!_finished);
     _mixins = _value;
   }
 
+  @override
+  List<EntityRefBuilder> get interfaces => _interfaces ??= <EntityRefBuilder>[];
+
   /**
    * Interfaces appearing in an `implements` clause, if any.
    */
-  void set interfaces(List<UnlinkedTypeRefBuilder> _value) {
+  void set interfaces(List<EntityRefBuilder> _value) {
     assert(!_finished);
     _interfaces = _value;
   }
 
+  @override
+  List<UnlinkedVariableBuilder> get fields => _fields ??= <UnlinkedVariableBuilder>[];
+
   /**
    * Field declarations contained in the class.
    */
@@ -814,6 +1822,9 @@
     _fields = _value;
   }
 
+  @override
+  List<UnlinkedExecutableBuilder> get executables => _executables ??= <UnlinkedExecutableBuilder>[];
+
   /**
    * Executable objects (methods, getters, and setters) contained in the class.
    */
@@ -822,6 +1833,9 @@
     _executables = _value;
   }
 
+  @override
+  bool get isAbstract => _isAbstract ??= false;
+
   /**
    * Indicates whether the class is declared with the `abstract` keyword.
    */
@@ -830,6 +1844,9 @@
     _isAbstract = _value;
   }
 
+  @override
+  bool get isMixinApplication => _isMixinApplication ??= false;
+
   /**
    * Indicates whether the class is declared using mixin application syntax.
    */
@@ -838,6 +1855,9 @@
     _isMixinApplication = _value;
   }
 
+  @override
+  bool get hasNoSupertype => _hasNoSupertype ??= false;
+
   /**
    * Indicates whether this class is the core "Object" class (and hence has no
    * supertype)
@@ -847,6 +1867,20 @@
     _hasNoSupertype = _value;
   }
 
+  UnlinkedClassBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, EntityRefBuilder supertype, List<EntityRefBuilder> mixins, List<EntityRefBuilder> interfaces, List<UnlinkedVariableBuilder> fields, List<UnlinkedExecutableBuilder> executables, bool isAbstract, bool isMixinApplication, bool hasNoSupertype})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment,
+      _typeParameters = typeParameters,
+      _supertype = supertype,
+      _mixins = mixins,
+      _interfaces = interfaces,
+      _fields = fields,
+      _executables = executables,
+      _isAbstract = isAbstract,
+      _isMixinApplication = isMixinApplication,
+      _hasNoSupertype = hasNoSupertype;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -887,7 +1921,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -923,23 +1957,6 @@
   }
 }
 
-UnlinkedClassBuilder encodeUnlinkedClass({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, 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();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  builder.typeParameters = typeParameters;
-  builder.supertype = supertype;
-  builder.mixins = mixins;
-  builder.interfaces = interfaces;
-  builder.fields = fields;
-  builder.executables = executables;
-  builder.isAbstract = isAbstract;
-  builder.isMixinApplication = isMixinApplication;
-  builder.hasNoSupertype = hasNoSupertype;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a class declaration.
  */
@@ -971,17 +1988,17 @@
    * explicitly declare a supertype (and hence has supertype `Object`), or (b)
    * the class *is* `Object` (and hence has no supertype).
    */
-  UnlinkedTypeRef get supertype;
+  EntityRef get supertype;
 
   /**
    * Mixins appearing in a `with` clause, if any.
    */
-  List<UnlinkedTypeRef> get mixins;
+  List<EntityRef> get mixins;
 
   /**
    * Interfaces appearing in an `implements` clause, if any.
    */
-  List<UnlinkedTypeRef> get interfaces;
+  List<EntityRef> get interfaces;
 
   /**
    * Field declarations contained in the class.
@@ -1017,7 +2034,7 @@
   _UnlinkedClassImpl createObject(fb.BufferPointer bp) => new _UnlinkedClassImpl(bp);
 }
 
-class _UnlinkedClassImpl implements UnlinkedClass {
+class _UnlinkedClassImpl extends Object with _UnlinkedClassMixin implements UnlinkedClass {
   final fb.BufferPointer _bp;
 
   _UnlinkedClassImpl(this._bp);
@@ -1026,9 +2043,9 @@
   int _nameOffset;
   UnlinkedDocumentationComment _documentationComment;
   List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _supertype;
-  List<UnlinkedTypeRef> _mixins;
-  List<UnlinkedTypeRef> _interfaces;
+  EntityRef _supertype;
+  List<EntityRef> _mixins;
+  List<EntityRef> _interfaces;
   List<UnlinkedVariable> _fields;
   List<UnlinkedExecutable> _executables;
   bool _isAbstract;
@@ -1036,22 +2053,6 @@
   bool _hasNoSupertype;
 
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-    "typeParameters": typeParameters,
-    "supertype": supertype,
-    "mixins": mixins,
-    "interfaces": interfaces,
-    "fields": fields,
-    "executables": executables,
-    "isAbstract": isAbstract,
-    "isMixinApplication": isMixinApplication,
-    "hasNoSupertype": hasNoSupertype,
-  };
-
-  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _name;
@@ -1059,7 +2060,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -1076,20 +2077,20 @@
   }
 
   @override
-  UnlinkedTypeRef get supertype {
-    _supertype ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+  EntityRef get supertype {
+    _supertype ??= const _EntityRefReader().vTableGet(_bp, 4, null);
     return _supertype;
   }
 
   @override
-  List<UnlinkedTypeRef> get mixins {
-    _mixins ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 5, const <UnlinkedTypeRef>[]);
+  List<EntityRef> get mixins {
+    _mixins ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 5, const <EntityRef>[]);
     return _mixins;
   }
 
   @override
-  List<UnlinkedTypeRef> get interfaces {
-    _interfaces ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 6, const <UnlinkedTypeRef>[]);
+  List<EntityRef> get interfaces {
+    _interfaces ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 6, const <EntityRef>[]);
     return _interfaces;
   }
 
@@ -1124,13 +2125,32 @@
   }
 }
 
-class UnlinkedCombinatorBuilder {
+abstract class _UnlinkedClassMixin implements UnlinkedClass {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "supertype": supertype,
+    "mixins": mixins,
+    "interfaces": interfaces,
+    "fields": fields,
+    "executables": executables,
+    "isAbstract": isAbstract,
+    "isMixinApplication": isMixinApplication,
+    "hasNoSupertype": hasNoSupertype,
+  };
+}
+
+class UnlinkedCombinatorBuilder extends Object with _UnlinkedCombinatorMixin implements UnlinkedCombinator {
   bool _finished = false;
 
   List<String> _shows;
   List<String> _hides;
 
-  UnlinkedCombinatorBuilder();
+  @override
+  List<String> get shows => _shows ??= <String>[];
 
   /**
    * List of names which are shown.  Empty if this is a `hide` combinator.
@@ -1140,6 +2160,9 @@
     _shows = _value;
   }
 
+  @override
+  List<String> get hides => _hides ??= <String>[];
+
   /**
    * List of names which are hidden.  Empty if this is a `show` combinator.
    */
@@ -1148,6 +2171,10 @@
     _hides = _value;
   }
 
+  UnlinkedCombinatorBuilder({List<String> shows, List<String> hides})
+    : _shows = shows,
+      _hides = hides;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -1170,13 +2197,6 @@
   }
 }
 
-UnlinkedCombinatorBuilder encodeUnlinkedCombinator({List<String> shows, List<String> hides}) {
-  UnlinkedCombinatorBuilder builder = new UnlinkedCombinatorBuilder();
-  builder.shows = shows;
-  builder.hides = hides;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a `show` or `hide` combinator in an
  * import or export declaration.
@@ -1201,7 +2221,7 @@
   _UnlinkedCombinatorImpl createObject(fb.BufferPointer bp) => new _UnlinkedCombinatorImpl(bp);
 }
 
-class _UnlinkedCombinatorImpl implements UnlinkedCombinator {
+class _UnlinkedCombinatorImpl extends Object with _UnlinkedCombinatorMixin implements UnlinkedCombinator {
   final fb.BufferPointer _bp;
 
   _UnlinkedCombinatorImpl(this._bp);
@@ -1210,12 +2230,6 @@
   List<String> _hides;
 
   @override
-  Map<String, Object> toMap() => {
-    "shows": shows,
-    "hides": hides,
-  };
-
-  @override
   List<String> get shows {
     _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
     return _shows;
@@ -1228,14 +2242,250 @@
   }
 }
 
-class UnlinkedDocumentationCommentBuilder {
+abstract class _UnlinkedCombinatorMixin implements UnlinkedCombinator {
+  @override
+  Map<String, Object> toMap() => {
+    "shows": shows,
+    "hides": hides,
+  };
+}
+
+class UnlinkedConstBuilder extends Object with _UnlinkedConstMixin implements UnlinkedConst {
+  bool _finished = false;
+
+  List<UnlinkedConstOperation> _operations;
+  List<int> _ints;
+  List<double> _doubles;
+  List<String> _strings;
+  List<EntityRefBuilder> _references;
+
+  @override
+  List<UnlinkedConstOperation> get operations => _operations ??= <UnlinkedConstOperation>[];
+
+  /**
+   * Sequence of operations to execute (starting with an empty stack) to form
+   * the constant value.
+   */
+  void set operations(List<UnlinkedConstOperation> _value) {
+    assert(!_finished);
+    _operations = _value;
+  }
+
+  @override
+  List<int> get ints => _ints ??= <int>[];
+
+  /**
+   * Sequence of unsigned 32-bit integers consumed by the operations
+   * `pushArgument`, `pushInt`, `shiftOr`, `concatenate`, `invokeConstructor`,
+   * `makeList`, and `makeMap`.
+   */
+  void set ints(List<int> _value) {
+    assert(!_finished);
+    assert(_value == null || _value.every((e) => e >= 0));
+    _ints = _value;
+  }
+
+  @override
+  List<double> get doubles => _doubles ??= <double>[];
+
+  /**
+   * Sequence of 64-bit doubles consumed by the operation `pushDouble`.
+   */
+  void set doubles(List<double> _value) {
+    assert(!_finished);
+    _doubles = _value;
+  }
+
+  @override
+  List<String> get strings => _strings ??= <String>[];
+
+  /**
+   * Sequence of strings consumed by the operations `pushString` and
+   * `invokeConstructor`.
+   */
+  void set strings(List<String> _value) {
+    assert(!_finished);
+    _strings = _value;
+  }
+
+  @override
+  List<EntityRefBuilder> get references => _references ??= <EntityRefBuilder>[];
+
+  /**
+   * Sequence of language constructs consumed by the operations
+   * `pushReference`, `invokeConstructor`, `makeList`, and `makeMap`.  Note
+   * that in the case of `pushReference` (and sometimes `invokeConstructor` the
+   * actual entity being referred to may be something other than a type.
+   */
+  void set references(List<EntityRefBuilder> _value) {
+    assert(!_finished);
+    _references = _value;
+  }
+
+  UnlinkedConstBuilder({List<UnlinkedConstOperation> operations, List<int> ints, List<double> doubles, List<String> strings, List<EntityRefBuilder> references})
+    : _operations = operations,
+      _ints = ints,
+      _doubles = doubles,
+      _strings = strings,
+      _references = references;
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_operations;
+    fb.Offset offset_ints;
+    fb.Offset offset_doubles;
+    fb.Offset offset_strings;
+    fb.Offset offset_references;
+    if (!(_operations == null || _operations.isEmpty)) {
+      offset_operations = fbBuilder.writeListUint32(_operations.map((b) => b.index).toList());
+    }
+    if (!(_ints == null || _ints.isEmpty)) {
+      offset_ints = fbBuilder.writeListUint32(_ints);
+    }
+    if (!(_doubles == null || _doubles.isEmpty)) {
+      offset_doubles = fbBuilder.writeListFloat64(_doubles);
+    }
+    if (!(_strings == null || _strings.isEmpty)) {
+      offset_strings = fbBuilder.writeList(_strings.map((b) => fbBuilder.writeString(b)).toList());
+    }
+    if (!(_references == null || _references.isEmpty)) {
+      offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
+    }
+    fbBuilder.startTable();
+    if (offset_operations != null) {
+      fbBuilder.addOffset(0, offset_operations);
+    }
+    if (offset_ints != null) {
+      fbBuilder.addOffset(1, offset_ints);
+    }
+    if (offset_doubles != null) {
+      fbBuilder.addOffset(2, offset_doubles);
+    }
+    if (offset_strings != null) {
+      fbBuilder.addOffset(3, offset_strings);
+    }
+    if (offset_references != null) {
+      fbBuilder.addOffset(4, offset_references);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+/**
+ * Unlinked summary information about a compile-time constant expression, or a
+ * potentially constant expression.
+ *
+ * Constant expressions are represented using a simple stack-based language
+ * where [operations] is a sequence of operations to execute starting with an
+ * empty stack.  Once all operations have been executed, the stack should
+ * contain a single value which is the value of the constant.  Note that some
+ * operations consume additional data from the other fields of this class.
+ */
+abstract class UnlinkedConst extends base.SummaryClass {
+
+  /**
+   * Sequence of operations to execute (starting with an empty stack) to form
+   * the constant value.
+   */
+  List<UnlinkedConstOperation> get operations;
+
+  /**
+   * Sequence of unsigned 32-bit integers consumed by the operations
+   * `pushArgument`, `pushInt`, `shiftOr`, `concatenate`, `invokeConstructor`,
+   * `makeList`, and `makeMap`.
+   */
+  List<int> get ints;
+
+  /**
+   * Sequence of 64-bit doubles consumed by the operation `pushDouble`.
+   */
+  List<double> get doubles;
+
+  /**
+   * Sequence of strings consumed by the operations `pushString` and
+   * `invokeConstructor`.
+   */
+  List<String> get strings;
+
+  /**
+   * Sequence of language constructs consumed by the operations
+   * `pushReference`, `invokeConstructor`, `makeList`, and `makeMap`.  Note
+   * that in the case of `pushReference` (and sometimes `invokeConstructor` the
+   * actual entity being referred to may be something other than a type.
+   */
+  List<EntityRef> get references;
+}
+
+class _UnlinkedConstReader extends fb.TableReader<_UnlinkedConstImpl> {
+  const _UnlinkedConstReader();
+
+  @override
+  _UnlinkedConstImpl createObject(fb.BufferPointer bp) => new _UnlinkedConstImpl(bp);
+}
+
+class _UnlinkedConstImpl extends Object with _UnlinkedConstMixin implements UnlinkedConst {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedConstImpl(this._bp);
+
+  List<UnlinkedConstOperation> _operations;
+  List<int> _ints;
+  List<double> _doubles;
+  List<String> _strings;
+  List<EntityRef> _references;
+
+  @override
+  List<UnlinkedConstOperation> get operations {
+    _operations ??= const fb.ListReader<UnlinkedConstOperation>(const _UnlinkedConstOperationReader()).vTableGet(_bp, 0, const <UnlinkedConstOperation>[]);
+    return _operations;
+  }
+
+  @override
+  List<int> get ints {
+    _ints ??= const fb.ListReader<int>(const fb.Uint32Reader()).vTableGet(_bp, 1, const <int>[]);
+    return _ints;
+  }
+
+  @override
+  List<double> get doubles {
+    _doubles ??= const fb.Float64ListReader().vTableGet(_bp, 2, const <double>[]);
+    return _doubles;
+  }
+
+  @override
+  List<String> get strings {
+    _strings ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 3, const <String>[]);
+    return _strings;
+  }
+
+  @override
+  List<EntityRef> get references {
+    _references ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 4, const <EntityRef>[]);
+    return _references;
+  }
+}
+
+abstract class _UnlinkedConstMixin implements UnlinkedConst {
+  @override
+  Map<String, Object> toMap() => {
+    "operations": operations,
+    "ints": ints,
+    "doubles": doubles,
+    "strings": strings,
+    "references": references,
+  };
+}
+
+class UnlinkedDocumentationCommentBuilder extends Object with _UnlinkedDocumentationCommentMixin implements UnlinkedDocumentationComment {
   bool _finished = false;
 
   String _text;
   int _offset;
   int _length;
 
-  UnlinkedDocumentationCommentBuilder();
+  @override
+  String get text => _text ??= '';
 
   /**
    * Text of the documentation comment, with '\r\n' replaced by '\n'.
@@ -1248,23 +2498,36 @@
     _text = _value;
   }
 
+  @override
+  int get offset => _offset ??= 0;
+
   /**
    * Offset of the beginning of the documentation comment relative to the
    * beginning of the file.
    */
   void set offset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _offset = _value;
   }
 
+  @override
+  int get length => _length ??= 0;
+
   /**
    * Length of the documentation comment (prior to replacing '\r\n' with '\n').
    */
   void set length(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _length = _value;
   }
 
+  UnlinkedDocumentationCommentBuilder({String text, int offset, int length})
+    : _text = text,
+      _offset = offset,
+      _length = length;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -1277,23 +2540,15 @@
       fbBuilder.addOffset(0, offset_text);
     }
     if (_offset != null && _offset != 0) {
-      fbBuilder.addInt32(1, _offset);
+      fbBuilder.addUint32(1, _offset);
     }
     if (_length != null && _length != 0) {
-      fbBuilder.addInt32(2, _length);
+      fbBuilder.addUint32(2, _length);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedDocumentationCommentBuilder encodeUnlinkedDocumentationComment({String text, int offset, int length}) {
-  UnlinkedDocumentationCommentBuilder builder = new UnlinkedDocumentationCommentBuilder();
-  builder.text = text;
-  builder.offset = offset;
-  builder.length = length;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a documentation comment.
  */
@@ -1326,7 +2581,7 @@
   _UnlinkedDocumentationCommentImpl createObject(fb.BufferPointer bp) => new _UnlinkedDocumentationCommentImpl(bp);
 }
 
-class _UnlinkedDocumentationCommentImpl implements UnlinkedDocumentationComment {
+class _UnlinkedDocumentationCommentImpl extends Object with _UnlinkedDocumentationCommentMixin implements UnlinkedDocumentationComment {
   final fb.BufferPointer _bp;
 
   _UnlinkedDocumentationCommentImpl(this._bp);
@@ -1336,13 +2591,6 @@
   int _length;
 
   @override
-  Map<String, Object> toMap() => {
-    "text": text,
-    "offset": offset,
-    "length": length,
-  };
-
-  @override
   String get text {
     _text ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _text;
@@ -1350,18 +2598,27 @@
 
   @override
   int get offset {
-    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _offset;
   }
 
   @override
   int get length {
-    _length ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    _length ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _length;
   }
 }
 
-class UnlinkedEnumBuilder {
+abstract class _UnlinkedDocumentationCommentMixin implements UnlinkedDocumentationComment {
+  @override
+  Map<String, Object> toMap() => {
+    "text": text,
+    "offset": offset,
+    "length": length,
+  };
+}
+
+class UnlinkedEnumBuilder extends Object with _UnlinkedEnumMixin implements UnlinkedEnum {
   bool _finished = false;
 
   String _name;
@@ -1369,7 +2626,8 @@
   UnlinkedDocumentationCommentBuilder _documentationComment;
   List<UnlinkedEnumValueBuilder> _values;
 
-  UnlinkedEnumBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the enum type.
@@ -1379,14 +2637,21 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the enum name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the enum, or `null` if there is no documentation
    * comment.
@@ -1396,6 +2661,9 @@
     _documentationComment = _value;
   }
 
+  @override
+  List<UnlinkedEnumValueBuilder> get values => _values ??= <UnlinkedEnumValueBuilder>[];
+
   /**
    * Values listed in the enum declaration, in declaration order.
    */
@@ -1404,6 +2672,12 @@
     _values = _value;
   }
 
+  UnlinkedEnumBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedEnumValueBuilder> values})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment,
+      _values = values;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -1424,7 +2698,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -1436,15 +2710,6 @@
   }
 }
 
-UnlinkedEnumBuilder encodeUnlinkedEnum({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedEnumValueBuilder> values}) {
-  UnlinkedEnumBuilder builder = new UnlinkedEnumBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  builder.values = values;
-  return builder;
-}
-
 /**
  * Unlinked summary information about an enum declaration.
  */
@@ -1479,7 +2744,7 @@
   _UnlinkedEnumImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumImpl(bp);
 }
 
-class _UnlinkedEnumImpl implements UnlinkedEnum {
+class _UnlinkedEnumImpl extends Object with _UnlinkedEnumMixin implements UnlinkedEnum {
   final fb.BufferPointer _bp;
 
   _UnlinkedEnumImpl(this._bp);
@@ -1490,14 +2755,6 @@
   List<UnlinkedEnumValue> _values;
 
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-    "values": values,
-  };
-
-  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _name;
@@ -1505,7 +2762,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -1522,14 +2779,25 @@
   }
 }
 
-class UnlinkedEnumValueBuilder {
+abstract class _UnlinkedEnumMixin implements UnlinkedEnum {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "values": values,
+  };
+}
+
+class UnlinkedEnumValueBuilder extends Object with _UnlinkedEnumValueMixin implements UnlinkedEnumValue {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
   UnlinkedDocumentationCommentBuilder _documentationComment;
 
-  UnlinkedEnumValueBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the enumerated value.
@@ -1539,14 +2807,21 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the enum value name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the enum value, or `null` if there is no
    * documentation comment.
@@ -1556,6 +2831,11 @@
     _documentationComment = _value;
   }
 
+  UnlinkedEnumValueBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -1572,7 +2852,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -1581,14 +2861,6 @@
   }
 }
 
-UnlinkedEnumValueBuilder encodeUnlinkedEnumValue({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment}) {
-  UnlinkedEnumValueBuilder builder = new UnlinkedEnumValueBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a single enumerated value in an enum
  * declaration.
@@ -1619,7 +2891,7 @@
   _UnlinkedEnumValueImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumValueImpl(bp);
 }
 
-class _UnlinkedEnumValueImpl implements UnlinkedEnumValue {
+class _UnlinkedEnumValueImpl extends Object with _UnlinkedEnumValueMixin implements UnlinkedEnumValue {
   final fb.BufferPointer _bp;
 
   _UnlinkedEnumValueImpl(this._bp);
@@ -1629,13 +2901,6 @@
   UnlinkedDocumentationComment _documentationComment;
 
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-  };
-
-  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _name;
@@ -1643,7 +2908,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -1654,24 +2919,34 @@
   }
 }
 
-class UnlinkedExecutableBuilder {
+abstract class _UnlinkedEnumValueMixin implements UnlinkedEnumValue {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+  };
+}
+
+class UnlinkedExecutableBuilder extends Object with _UnlinkedExecutableMixin implements UnlinkedExecutable {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
   UnlinkedDocumentationCommentBuilder _documentationComment;
   List<UnlinkedTypeParamBuilder> _typeParameters;
-  UnlinkedTypeRefBuilder _returnType;
+  EntityRefBuilder _returnType;
   List<UnlinkedParamBuilder> _parameters;
   UnlinkedExecutableKind _kind;
   bool _isAbstract;
   bool _isStatic;
   bool _isConst;
   bool _isFactory;
-  bool _hasImplicitReturnType;
   bool _isExternal;
+  int _inferredReturnTypeSlot;
 
-  UnlinkedExecutableBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the executable.  For setters, this includes the trailing "=".  For
@@ -1683,6 +2958,9 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the executable name relative to the beginning of the file.  For
    * named constructors, this excludes the class name and excludes the ".".
@@ -1691,9 +2969,13 @@
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the executable, or `null` if there is no
    * documentation comment.
@@ -1703,6 +2985,9 @@
     _documentationComment = _value;
   }
 
+  @override
+  List<UnlinkedTypeParamBuilder> get typeParameters => _typeParameters ??= <UnlinkedTypeParamBuilder>[];
+
   /**
    * Type parameters of the executable, if any.  Empty if support for generic
    * method syntax is disabled.
@@ -1712,16 +2997,21 @@
     _typeParameters = _value;
   }
 
+  @override
+  EntityRefBuilder get returnType => _returnType;
+
   /**
-   * Declared return type of the executable.  Absent if the return type is
-   * `void` or the executable is a constructor.  Note that when strong mode is
-   * enabled, the actual return type may be different due to type inference.
+   * Declared return type of the executable.  Absent if the executable is a
+   * constructor or the return type is implicit.
    */
-  void set returnType(UnlinkedTypeRefBuilder _value) {
+  void set returnType(EntityRefBuilder _value) {
     assert(!_finished);
     _returnType = _value;
   }
 
+  @override
+  List<UnlinkedParamBuilder> get parameters => _parameters ??= <UnlinkedParamBuilder>[];
+
   /**
    * Parameters of the executable, if any.  Note that getters have no
    * parameters (hence this will be the empty list), and setters have a single
@@ -1732,6 +3022,9 @@
     _parameters = _value;
   }
 
+  @override
+  UnlinkedExecutableKind get kind => _kind ??= UnlinkedExecutableKind.functionOrMethod;
+
   /**
    * The kind of the executable (function/method, getter, setter, or
    * constructor).
@@ -1741,6 +3034,9 @@
     _kind = _value;
   }
 
+  @override
+  bool get isAbstract => _isAbstract ??= false;
+
   /**
    * Indicates whether the executable is declared using the `abstract` keyword.
    */
@@ -1749,6 +3045,9 @@
     _isAbstract = _value;
   }
 
+  @override
+  bool get isStatic => _isStatic ??= false;
+
   /**
    * Indicates whether the executable is declared using the `static` keyword.
    *
@@ -1761,6 +3060,9 @@
     _isStatic = _value;
   }
 
+  @override
+  bool get isConst => _isConst ??= false;
+
   /**
    * Indicates whether the executable is declared using the `const` keyword.
    */
@@ -1769,6 +3071,9 @@
     _isConst = _value;
   }
 
+  @override
+  bool get isFactory => _isFactory ??= false;
+
   /**
    * Indicates whether the executable is declared using the `factory` keyword.
    */
@@ -1777,14 +3082,8 @@
     _isFactory = _value;
   }
 
-  /**
-   * Indicates whether the executable lacks an explicit return type
-   * declaration.  False for constructors and setters.
-   */
-  void set hasImplicitReturnType(bool _value) {
-    assert(!_finished);
-    _hasImplicitReturnType = _value;
-  }
+  @override
+  bool get isExternal => _isExternal ??= false;
 
   /**
    * Indicates whether the executable is declared using the `external` keyword.
@@ -1794,6 +3093,37 @@
     _isExternal = _value;
   }
 
+  @override
+  int get inferredReturnTypeSlot => _inferredReturnTypeSlot ??= 0;
+
+  /**
+   * If this executable's return type is inferrable, nonzero slot id
+   * identifying which entry in [LinkedLibrary.types] contains the inferred
+   * return type.  If there is no matching entry in [LinkedLibrary.types], then
+   * no return type was inferred for this variable, so its static type is
+   * `dynamic`.
+   */
+  void set inferredReturnTypeSlot(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _inferredReturnTypeSlot = _value;
+  }
+
+  UnlinkedExecutableBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, EntityRefBuilder returnType, List<UnlinkedParamBuilder> parameters, UnlinkedExecutableKind kind, bool isAbstract, bool isStatic, bool isConst, bool isFactory, bool isExternal, int inferredReturnTypeSlot})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment,
+      _typeParameters = typeParameters,
+      _returnType = returnType,
+      _parameters = parameters,
+      _kind = kind,
+      _isAbstract = isAbstract,
+      _isStatic = isStatic,
+      _isConst = isConst,
+      _isFactory = isFactory,
+      _isExternal = isExternal,
+      _inferredReturnTypeSlot = inferredReturnTypeSlot;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -1822,7 +3152,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -1837,7 +3167,7 @@
       fbBuilder.addOffset(5, offset_parameters);
     }
     if (_kind != null && _kind != UnlinkedExecutableKind.functionOrMethod) {
-      fbBuilder.addInt32(6, _kind.index);
+      fbBuilder.addUint32(6, _kind.index);
     }
     if (_isAbstract == true) {
       fbBuilder.addBool(7, true);
@@ -1851,34 +3181,16 @@
     if (_isFactory == true) {
       fbBuilder.addBool(10, true);
     }
-    if (_hasImplicitReturnType == true) {
+    if (_isExternal == true) {
       fbBuilder.addBool(11, true);
     }
-    if (_isExternal == true) {
-      fbBuilder.addBool(12, true);
+    if (_inferredReturnTypeSlot != null && _inferredReturnTypeSlot != 0) {
+      fbBuilder.addUint32(12, _inferredReturnTypeSlot);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedExecutableBuilder encodeUnlinkedExecutable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, 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();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  builder.typeParameters = typeParameters;
-  builder.returnType = returnType;
-  builder.parameters = parameters;
-  builder.kind = kind;
-  builder.isAbstract = isAbstract;
-  builder.isStatic = isStatic;
-  builder.isConst = isConst;
-  builder.isFactory = isFactory;
-  builder.hasImplicitReturnType = hasImplicitReturnType;
-  builder.isExternal = isExternal;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a function, method, getter, or setter
  * declaration.
@@ -1913,11 +3225,10 @@
   List<UnlinkedTypeParam> get typeParameters;
 
   /**
-   * Declared return type of the executable.  Absent if the return type is
-   * `void` or the executable is a constructor.  Note that when strong mode is
-   * enabled, the actual return type may be different due to type inference.
+   * Declared return type of the executable.  Absent if the executable is a
+   * constructor or the return type is implicit.
    */
-  UnlinkedTypeRef get returnType;
+  EntityRef get returnType;
 
   /**
    * Parameters of the executable, if any.  Note that getters have no
@@ -1957,15 +3268,18 @@
   bool get isFactory;
 
   /**
-   * Indicates whether the executable lacks an explicit return type
-   * declaration.  False for constructors and setters.
-   */
-  bool get hasImplicitReturnType;
-
-  /**
    * Indicates whether the executable is declared using the `external` keyword.
    */
   bool get isExternal;
+
+  /**
+   * If this executable's return type is inferrable, nonzero slot id
+   * identifying which entry in [LinkedLibrary.types] contains the inferred
+   * return type.  If there is no matching entry in [LinkedLibrary.types], then
+   * no return type was inferred for this variable, so its static type is
+   * `dynamic`.
+   */
+  int get inferredReturnTypeSlot;
 }
 
 class _UnlinkedExecutableReader extends fb.TableReader<_UnlinkedExecutableImpl> {
@@ -1975,7 +3289,7 @@
   _UnlinkedExecutableImpl createObject(fb.BufferPointer bp) => new _UnlinkedExecutableImpl(bp);
 }
 
-class _UnlinkedExecutableImpl implements UnlinkedExecutable {
+class _UnlinkedExecutableImpl extends Object with _UnlinkedExecutableMixin implements UnlinkedExecutable {
   final fb.BufferPointer _bp;
 
   _UnlinkedExecutableImpl(this._bp);
@@ -1984,32 +3298,15 @@
   int _nameOffset;
   UnlinkedDocumentationComment _documentationComment;
   List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _returnType;
+  EntityRef _returnType;
   List<UnlinkedParam> _parameters;
   UnlinkedExecutableKind _kind;
   bool _isAbstract;
   bool _isStatic;
   bool _isConst;
   bool _isFactory;
-  bool _hasImplicitReturnType;
   bool _isExternal;
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-    "typeParameters": typeParameters,
-    "returnType": returnType,
-    "parameters": parameters,
-    "kind": kind,
-    "isAbstract": isAbstract,
-    "isStatic": isStatic,
-    "isConst": isConst,
-    "isFactory": isFactory,
-    "hasImplicitReturnType": hasImplicitReturnType,
-    "isExternal": isExternal,
-  };
+  int _inferredReturnTypeSlot;
 
   @override
   String get name {
@@ -2019,7 +3316,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -2036,8 +3333,8 @@
   }
 
   @override
-  UnlinkedTypeRef get returnType {
-    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+  EntityRef get returnType {
+    _returnType ??= const _EntityRefReader().vTableGet(_bp, 4, null);
     return _returnType;
   }
 
@@ -2049,7 +3346,7 @@
 
   @override
   UnlinkedExecutableKind get kind {
-    _kind ??= UnlinkedExecutableKind.values[const fb.Int32Reader().vTableGet(_bp, 6, 0)];
+    _kind ??= const _UnlinkedExecutableKindReader().vTableGet(_bp, 6, UnlinkedExecutableKind.functionOrMethod);
     return _kind;
   }
 
@@ -2078,78 +3375,104 @@
   }
 
   @override
-  bool get hasImplicitReturnType {
-    _hasImplicitReturnType ??= const fb.BoolReader().vTableGet(_bp, 11, false);
-    return _hasImplicitReturnType;
+  bool get isExternal {
+    _isExternal ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    return _isExternal;
   }
 
   @override
-  bool get isExternal {
-    _isExternal ??= const fb.BoolReader().vTableGet(_bp, 12, false);
-    return _isExternal;
+  int get inferredReturnTypeSlot {
+    _inferredReturnTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 12, 0);
+    return _inferredReturnTypeSlot;
   }
 }
 
-class UnlinkedExportNonPublicBuilder {
+abstract class _UnlinkedExecutableMixin implements UnlinkedExecutable {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
+    "kind": kind,
+    "isAbstract": isAbstract,
+    "isStatic": isStatic,
+    "isConst": isConst,
+    "isFactory": isFactory,
+    "isExternal": isExternal,
+    "inferredReturnTypeSlot": inferredReturnTypeSlot,
+  };
+}
+
+class UnlinkedExportNonPublicBuilder extends Object with _UnlinkedExportNonPublicMixin implements UnlinkedExportNonPublic {
   bool _finished = false;
 
   int _offset;
   int _uriOffset;
   int _uriEnd;
 
-  UnlinkedExportNonPublicBuilder();
+  @override
+  int get offset => _offset ??= 0;
 
   /**
    * Offset of the "export" keyword.
    */
   void set offset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _offset = _value;
   }
 
+  @override
+  int get uriOffset => _uriOffset ??= 0;
+
   /**
    * Offset of the URI string (including quotes) relative to the beginning of
    * the file.
    */
   void set uriOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriOffset = _value;
   }
 
+  @override
+  int get uriEnd => _uriEnd ??= 0;
+
   /**
    * End of the URI string (including quotes) relative to the beginning of the
    * file.
    */
   void set uriEnd(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriEnd = _value;
   }
 
+  UnlinkedExportNonPublicBuilder({int offset, int uriOffset, int uriEnd})
+    : _offset = offset,
+      _uriOffset = uriOffset,
+      _uriEnd = uriEnd;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
     fbBuilder.startTable();
     if (_offset != null && _offset != 0) {
-      fbBuilder.addInt32(0, _offset);
+      fbBuilder.addUint32(0, _offset);
     }
     if (_uriOffset != null && _uriOffset != 0) {
-      fbBuilder.addInt32(1, _uriOffset);
+      fbBuilder.addUint32(1, _uriOffset);
     }
     if (_uriEnd != null && _uriEnd != 0) {
-      fbBuilder.addInt32(2, _uriEnd);
+      fbBuilder.addUint32(2, _uriEnd);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedExportNonPublicBuilder encodeUnlinkedExportNonPublic({int offset, int uriOffset, int uriEnd}) {
-  UnlinkedExportNonPublicBuilder builder = new UnlinkedExportNonPublicBuilder();
-  builder.offset = offset;
-  builder.uriOffset = uriOffset;
-  builder.uriEnd = uriEnd;
-  return builder;
-}
-
 /**
  * Unlinked summary information about an export declaration (stored outside
  * [UnlinkedPublicNamespace]).
@@ -2181,7 +3504,7 @@
   _UnlinkedExportNonPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportNonPublicImpl(bp);
 }
 
-class _UnlinkedExportNonPublicImpl implements UnlinkedExportNonPublic {
+class _UnlinkedExportNonPublicImpl extends Object with _UnlinkedExportNonPublicMixin implements UnlinkedExportNonPublic {
   final fb.BufferPointer _bp;
 
   _UnlinkedExportNonPublicImpl(this._bp);
@@ -2191,38 +3514,41 @@
   int _uriEnd;
 
   @override
-  Map<String, Object> toMap() => {
-    "offset": offset,
-    "uriOffset": uriOffset,
-    "uriEnd": uriEnd,
-  };
-
-  @override
   int get offset {
-    _offset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
     return _offset;
   }
 
   @override
   int get uriOffset {
-    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _uriOffset;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _uriEnd;
   }
 }
 
-class UnlinkedExportPublicBuilder {
+abstract class _UnlinkedExportNonPublicMixin implements UnlinkedExportNonPublic {
+  @override
+  Map<String, Object> toMap() => {
+    "offset": offset,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+}
+
+class UnlinkedExportPublicBuilder extends Object with _UnlinkedExportPublicMixin implements UnlinkedExportPublic {
   bool _finished = false;
 
   String _uri;
   List<UnlinkedCombinatorBuilder> _combinators;
 
-  UnlinkedExportPublicBuilder();
+  @override
+  String get uri => _uri ??= '';
 
   /**
    * URI used in the source code to reference the exported library.
@@ -2232,6 +3558,9 @@
     _uri = _value;
   }
 
+  @override
+  List<UnlinkedCombinatorBuilder> get combinators => _combinators ??= <UnlinkedCombinatorBuilder>[];
+
   /**
    * Combinators contained in this import declaration.
    */
@@ -2240,6 +3569,10 @@
     _combinators = _value;
   }
 
+  UnlinkedExportPublicBuilder({String uri, List<UnlinkedCombinatorBuilder> combinators})
+    : _uri = uri,
+      _combinators = combinators;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -2262,13 +3595,6 @@
   }
 }
 
-UnlinkedExportPublicBuilder encodeUnlinkedExportPublic({String uri, List<UnlinkedCombinatorBuilder> combinators}) {
-  UnlinkedExportPublicBuilder builder = new UnlinkedExportPublicBuilder();
-  builder.uri = uri;
-  builder.combinators = combinators;
-  return builder;
-}
-
 /**
  * Unlinked summary information about an export declaration (stored inside
  * [UnlinkedPublicNamespace]).
@@ -2293,7 +3619,7 @@
   _UnlinkedExportPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportPublicImpl(bp);
 }
 
-class _UnlinkedExportPublicImpl implements UnlinkedExportPublic {
+class _UnlinkedExportPublicImpl extends Object with _UnlinkedExportPublicMixin implements UnlinkedExportPublic {
   final fb.BufferPointer _bp;
 
   _UnlinkedExportPublicImpl(this._bp);
@@ -2302,12 +3628,6 @@
   List<UnlinkedCombinator> _combinators;
 
   @override
-  Map<String, Object> toMap() => {
-    "uri": uri,
-    "combinators": combinators,
-  };
-
-  @override
   String get uri {
     _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _uri;
@@ -2320,7 +3640,15 @@
   }
 }
 
-class UnlinkedImportBuilder {
+abstract class _UnlinkedExportPublicMixin implements UnlinkedExportPublic {
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "combinators": combinators,
+  };
+}
+
+class UnlinkedImportBuilder extends Object with _UnlinkedImportMixin implements UnlinkedImport {
   bool _finished = false;
 
   String _uri;
@@ -2333,7 +3661,8 @@
   int _uriEnd;
   int _prefixOffset;
 
-  UnlinkedImportBuilder();
+  @override
+  String get uri => _uri ??= '';
 
   /**
    * URI used in the source code to reference the imported library.
@@ -2343,15 +3672,22 @@
     _uri = _value;
   }
 
+  @override
+  int get offset => _offset ??= 0;
+
   /**
    * If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
    * is true, zero.
    */
   void set offset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _offset = _value;
   }
 
+  @override
+  int get prefixReference => _prefixReference ??= 0;
+
   /**
    * Index into [UnlinkedUnit.references] of the prefix declared by this
    * import declaration, or zero if this import declaration declares no prefix.
@@ -2360,9 +3696,13 @@
    */
   void set prefixReference(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _prefixReference = _value;
   }
 
+  @override
+  List<UnlinkedCombinatorBuilder> get combinators => _combinators ??= <UnlinkedCombinatorBuilder>[];
+
   /**
    * Combinators contained in this import declaration.
    */
@@ -2371,6 +3711,9 @@
     _combinators = _value;
   }
 
+  @override
+  bool get isDeferred => _isDeferred ??= false;
+
   /**
    * Indicates whether the import declaration uses the `deferred` keyword.
    */
@@ -2379,6 +3722,9 @@
     _isDeferred = _value;
   }
 
+  @override
+  bool get isImplicit => _isImplicit ??= false;
+
   /**
    * Indicates whether the import declaration is implicit.
    */
@@ -2387,33 +3733,56 @@
     _isImplicit = _value;
   }
 
+  @override
+  int get uriOffset => _uriOffset ??= 0;
+
   /**
    * Offset of the URI string (including quotes) relative to the beginning of
    * the file.  If [isImplicit] is true, zero.
    */
   void set uriOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriOffset = _value;
   }
 
+  @override
+  int get uriEnd => _uriEnd ??= 0;
+
   /**
    * End of the URI string (including quotes) relative to the beginning of the
    * file.  If [isImplicit] is true, zero.
    */
   void set uriEnd(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriEnd = _value;
   }
 
+  @override
+  int get prefixOffset => _prefixOffset ??= 0;
+
   /**
    * Offset of the prefix name relative to the beginning of the file, or zero
    * if there is no prefix.
    */
   void set prefixOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _prefixOffset = _value;
   }
 
+  UnlinkedImportBuilder({String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit, int uriOffset, int uriEnd, int prefixOffset})
+    : _uri = uri,
+      _offset = offset,
+      _prefixReference = prefixReference,
+      _combinators = combinators,
+      _isDeferred = isDeferred,
+      _isImplicit = isImplicit,
+      _uriOffset = uriOffset,
+      _uriEnd = uriEnd,
+      _prefixOffset = prefixOffset;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -2430,10 +3799,10 @@
       fbBuilder.addOffset(0, offset_uri);
     }
     if (_offset != null && _offset != 0) {
-      fbBuilder.addInt32(1, _offset);
+      fbBuilder.addUint32(1, _offset);
     }
     if (_prefixReference != null && _prefixReference != 0) {
-      fbBuilder.addInt32(2, _prefixReference);
+      fbBuilder.addUint32(2, _prefixReference);
     }
     if (offset_combinators != null) {
       fbBuilder.addOffset(3, offset_combinators);
@@ -2445,32 +3814,18 @@
       fbBuilder.addBool(5, true);
     }
     if (_uriOffset != null && _uriOffset != 0) {
-      fbBuilder.addInt32(6, _uriOffset);
+      fbBuilder.addUint32(6, _uriOffset);
     }
     if (_uriEnd != null && _uriEnd != 0) {
-      fbBuilder.addInt32(7, _uriEnd);
+      fbBuilder.addUint32(7, _uriEnd);
     }
     if (_prefixOffset != null && _prefixOffset != 0) {
-      fbBuilder.addInt32(8, _prefixOffset);
+      fbBuilder.addUint32(8, _prefixOffset);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedImportBuilder encodeUnlinkedImport({String uri, int offset, int prefixReference, List<UnlinkedCombinatorBuilder> combinators, bool isDeferred, bool isImplicit, int uriOffset, int uriEnd, int prefixOffset}) {
-  UnlinkedImportBuilder builder = new UnlinkedImportBuilder();
-  builder.uri = uri;
-  builder.offset = offset;
-  builder.prefixReference = prefixReference;
-  builder.combinators = combinators;
-  builder.isDeferred = isDeferred;
-  builder.isImplicit = isImplicit;
-  builder.uriOffset = uriOffset;
-  builder.uriEnd = uriEnd;
-  builder.prefixOffset = prefixOffset;
-  return builder;
-}
-
 /**
  * Unlinked summary information about an import declaration.
  */
@@ -2536,7 +3891,7 @@
   _UnlinkedImportImpl createObject(fb.BufferPointer bp) => new _UnlinkedImportImpl(bp);
 }
 
-class _UnlinkedImportImpl implements UnlinkedImport {
+class _UnlinkedImportImpl extends Object with _UnlinkedImportMixin implements UnlinkedImport {
   final fb.BufferPointer _bp;
 
   _UnlinkedImportImpl(this._bp);
@@ -2552,19 +3907,6 @@
   int _prefixOffset;
 
   @override
-  Map<String, Object> toMap() => {
-    "uri": uri,
-    "offset": offset,
-    "prefixReference": prefixReference,
-    "combinators": combinators,
-    "isDeferred": isDeferred,
-    "isImplicit": isImplicit,
-    "uriOffset": uriOffset,
-    "uriEnd": uriEnd,
-    "prefixOffset": prefixOffset,
-  };
-
-  @override
   String get uri {
     _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _uri;
@@ -2572,13 +3914,13 @@
 
   @override
   int get offset {
-    _offset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _offset;
   }
 
   @override
   int get prefixReference {
-    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _prefixReference;
   }
 
@@ -2602,36 +3944,52 @@
 
   @override
   int get uriOffset {
-    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 6, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 6, 0);
     return _uriOffset;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 7, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 7, 0);
     return _uriEnd;
   }
 
   @override
   int get prefixOffset {
-    _prefixOffset ??= const fb.Int32Reader().vTableGet(_bp, 8, 0);
+    _prefixOffset ??= const fb.Uint32Reader().vTableGet(_bp, 8, 0);
     return _prefixOffset;
   }
 }
 
-class UnlinkedParamBuilder {
+abstract class _UnlinkedImportMixin implements UnlinkedImport {
+  @override
+  Map<String, Object> toMap() => {
+    "uri": uri,
+    "offset": offset,
+    "prefixReference": prefixReference,
+    "combinators": combinators,
+    "isDeferred": isDeferred,
+    "isImplicit": isImplicit,
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+    "prefixOffset": prefixOffset,
+  };
+}
+
+class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements UnlinkedParam {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
-  UnlinkedTypeRefBuilder _type;
+  EntityRefBuilder _type;
   List<UnlinkedParamBuilder> _parameters;
   UnlinkedParamKind _kind;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
-  bool _hasImplicitType;
+  int _inferredTypeSlot;
 
-  UnlinkedParamBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the parameter.
@@ -2641,26 +3999,34 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the parameter name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  EntityRefBuilder get type => _type;
+
   /**
    * If [isFunctionTyped] is `true`, the declared return type.  If
-   * [isFunctionTyped] is `false`, the declared type.  Absent if
-   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
-   * that when strong mode is enabled, the actual type may be different due to
-   * type inference.
+   * [isFunctionTyped] is `false`, the declared type.  Absent if the type is
+   * implicit.
    */
-  void set type(UnlinkedTypeRefBuilder _value) {
+  void set type(EntityRefBuilder _value) {
     assert(!_finished);
     _type = _value;
   }
 
+  @override
+  List<UnlinkedParamBuilder> get parameters => _parameters ??= <UnlinkedParamBuilder>[];
+
   /**
    * If [isFunctionTyped] is `true`, the parameters of the function type.
    */
@@ -2669,6 +4035,9 @@
     _parameters = _value;
   }
 
+  @override
+  UnlinkedParamKind get kind => _kind ??= UnlinkedParamKind.required;
+
   /**
    * Kind of the parameter.
    */
@@ -2677,6 +4046,9 @@
     _kind = _value;
   }
 
+  @override
+  bool get isFunctionTyped => _isFunctionTyped ??= false;
+
   /**
    * Indicates whether this is a function-typed parameter.
    */
@@ -2685,6 +4057,9 @@
     _isFunctionTyped = _value;
   }
 
+  @override
+  bool get isInitializingFormal => _isInitializingFormal ??= false;
+
   /**
    * Indicates whether this is an initializing formal parameter (i.e. it is
    * declared using `this.` syntax).
@@ -2694,15 +4069,36 @@
     _isInitializingFormal = _value;
   }
 
+  @override
+  int get inferredTypeSlot => _inferredTypeSlot ??= 0;
+
   /**
-   * Indicates whether this parameter lacks an explicit type declaration.
-   * Always false for a function-typed parameter.
+   * If this parameter's type is inferrable, nonzero slot id identifying which
+   * entry in [LinkedLibrary.types] contains the inferred type.  If there is no
+   * matching entry in [LinkedLibrary.types], then no type was inferred for
+   * this variable, so its static type is `dynamic`.
+   *
+   * Note that although strong mode considers initializing formals to be
+   * inferrable, they are not marked as such in the summary; if their type is
+   * not specified, they always inherit the static type of the corresponding
+   * field.
    */
-  void set hasImplicitType(bool _value) {
+  void set inferredTypeSlot(int _value) {
     assert(!_finished);
-    _hasImplicitType = _value;
+    assert(_value == null || _value >= 0);
+    _inferredTypeSlot = _value;
   }
 
+  UnlinkedParamBuilder({String name, int nameOffset, EntityRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, int inferredTypeSlot})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _type = type,
+      _parameters = parameters,
+      _kind = kind,
+      _isFunctionTyped = isFunctionTyped,
+      _isInitializingFormal = isInitializingFormal,
+      _inferredTypeSlot = inferredTypeSlot;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -2723,7 +4119,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_type != null) {
       fbBuilder.addOffset(2, offset_type);
@@ -2732,7 +4128,7 @@
       fbBuilder.addOffset(3, offset_parameters);
     }
     if (_kind != null && _kind != UnlinkedParamKind.required) {
-      fbBuilder.addInt32(4, _kind.index);
+      fbBuilder.addUint32(4, _kind.index);
     }
     if (_isFunctionTyped == true) {
       fbBuilder.addBool(5, true);
@@ -2740,26 +4136,13 @@
     if (_isInitializingFormal == true) {
       fbBuilder.addBool(6, true);
     }
-    if (_hasImplicitType == true) {
-      fbBuilder.addBool(7, true);
+    if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
+      fbBuilder.addUint32(7, _inferredTypeSlot);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedParamBuilder encodeUnlinkedParam({String name, int nameOffset, UnlinkedTypeRefBuilder type, List<UnlinkedParamBuilder> parameters, UnlinkedParamKind kind, bool isFunctionTyped, bool isInitializingFormal, bool hasImplicitType}) {
-  UnlinkedParamBuilder builder = new UnlinkedParamBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.type = type;
-  builder.parameters = parameters;
-  builder.kind = kind;
-  builder.isFunctionTyped = isFunctionTyped;
-  builder.isInitializingFormal = isInitializingFormal;
-  builder.hasImplicitType = hasImplicitType;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a function parameter.
  */
@@ -2777,12 +4160,10 @@
 
   /**
    * If [isFunctionTyped] is `true`, the declared return type.  If
-   * [isFunctionTyped] is `false`, the declared type.  Absent if
-   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
-   * that when strong mode is enabled, the actual type may be different due to
-   * type inference.
+   * [isFunctionTyped] is `false`, the declared type.  Absent if the type is
+   * implicit.
    */
-  UnlinkedTypeRef get type;
+  EntityRef get type;
 
   /**
    * If [isFunctionTyped] is `true`, the parameters of the function type.
@@ -2806,10 +4187,17 @@
   bool get isInitializingFormal;
 
   /**
-   * Indicates whether this parameter lacks an explicit type declaration.
-   * Always false for a function-typed parameter.
+   * If this parameter's type is inferrable, nonzero slot id identifying which
+   * entry in [LinkedLibrary.types] contains the inferred type.  If there is no
+   * matching entry in [LinkedLibrary.types], then no type was inferred for
+   * this variable, so its static type is `dynamic`.
+   *
+   * Note that although strong mode considers initializing formals to be
+   * inferrable, they are not marked as such in the summary; if their type is
+   * not specified, they always inherit the static type of the corresponding
+   * field.
    */
-  bool get hasImplicitType;
+  int get inferredTypeSlot;
 }
 
 class _UnlinkedParamReader extends fb.TableReader<_UnlinkedParamImpl> {
@@ -2819,31 +4207,19 @@
   _UnlinkedParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedParamImpl(bp);
 }
 
-class _UnlinkedParamImpl implements UnlinkedParam {
+class _UnlinkedParamImpl extends Object with _UnlinkedParamMixin implements UnlinkedParam {
   final fb.BufferPointer _bp;
 
   _UnlinkedParamImpl(this._bp);
 
   String _name;
   int _nameOffset;
-  UnlinkedTypeRef _type;
+  EntityRef _type;
   List<UnlinkedParam> _parameters;
   UnlinkedParamKind _kind;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
-  bool _hasImplicitType;
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "type": type,
-    "parameters": parameters,
-    "kind": kind,
-    "isFunctionTyped": isFunctionTyped,
-    "isInitializingFormal": isInitializingFormal,
-    "hasImplicitType": hasImplicitType,
-  };
+  int _inferredTypeSlot;
 
   @override
   String get name {
@@ -2853,13 +4229,13 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
   @override
-  UnlinkedTypeRef get type {
-    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+  EntityRef get type {
+    _type ??= const _EntityRefReader().vTableGet(_bp, 2, null);
     return _type;
   }
 
@@ -2871,7 +4247,7 @@
 
   @override
   UnlinkedParamKind get kind {
-    _kind ??= UnlinkedParamKind.values[const fb.Int32Reader().vTableGet(_bp, 4, 0)];
+    _kind ??= const _UnlinkedParamKindReader().vTableGet(_bp, 4, UnlinkedParamKind.required);
     return _kind;
   }
 
@@ -2888,19 +4264,34 @@
   }
 
   @override
-  bool get hasImplicitType {
-    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
-    return _hasImplicitType;
+  int get inferredTypeSlot {
+    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 7, 0);
+    return _inferredTypeSlot;
   }
 }
 
-class UnlinkedPartBuilder {
+abstract class _UnlinkedParamMixin implements UnlinkedParam {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "type": type,
+    "parameters": parameters,
+    "kind": kind,
+    "isFunctionTyped": isFunctionTyped,
+    "isInitializingFormal": isInitializingFormal,
+    "inferredTypeSlot": inferredTypeSlot,
+  };
+}
+
+class UnlinkedPartBuilder extends Object with _UnlinkedPartMixin implements UnlinkedPart {
   bool _finished = false;
 
   int _uriOffset;
   int _uriEnd;
 
-  UnlinkedPartBuilder();
+  @override
+  int get uriOffset => _uriOffset ??= 0;
 
   /**
    * Offset of the URI string (including quotes) relative to the beginning of
@@ -2908,39 +4299,41 @@
    */
   void set uriOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriOffset = _value;
   }
 
+  @override
+  int get uriEnd => _uriEnd ??= 0;
+
   /**
    * End of the URI string (including quotes) relative to the beginning of the
    * file.
    */
   void set uriEnd(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _uriEnd = _value;
   }
 
+  UnlinkedPartBuilder({int uriOffset, int uriEnd})
+    : _uriOffset = uriOffset,
+      _uriEnd = uriEnd;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
     fbBuilder.startTable();
     if (_uriOffset != null && _uriOffset != 0) {
-      fbBuilder.addInt32(0, _uriOffset);
+      fbBuilder.addUint32(0, _uriOffset);
     }
     if (_uriEnd != null && _uriEnd != 0) {
-      fbBuilder.addInt32(1, _uriEnd);
+      fbBuilder.addUint32(1, _uriEnd);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedPartBuilder encodeUnlinkedPart({int uriOffset, int uriEnd}) {
-  UnlinkedPartBuilder builder = new UnlinkedPartBuilder();
-  builder.uriOffset = uriOffset;
-  builder.uriEnd = uriEnd;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a part declaration.
  */
@@ -2966,7 +4359,7 @@
   _UnlinkedPartImpl createObject(fb.BufferPointer bp) => new _UnlinkedPartImpl(bp);
 }
 
-class _UnlinkedPartImpl implements UnlinkedPart {
+class _UnlinkedPartImpl extends Object with _UnlinkedPartMixin implements UnlinkedPart {
   final fb.BufferPointer _bp;
 
   _UnlinkedPartImpl(this._bp);
@@ -2975,32 +4368,36 @@
   int _uriEnd;
 
   @override
-  Map<String, Object> toMap() => {
-    "uriOffset": uriOffset,
-    "uriEnd": uriEnd,
-  };
-
-  @override
   int get uriOffset {
-    _uriOffset ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
     return _uriOffset;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _uriEnd;
   }
 }
 
-class UnlinkedPublicNameBuilder {
+abstract class _UnlinkedPartMixin implements UnlinkedPart {
+  @override
+  Map<String, Object> toMap() => {
+    "uriOffset": uriOffset,
+    "uriEnd": uriEnd,
+  };
+}
+
+class UnlinkedPublicNameBuilder extends Object with _UnlinkedPublicNameMixin implements UnlinkedPublicName {
   bool _finished = false;
 
   String _name;
-  PrelinkedReferenceKind _kind;
+  ReferenceKind _kind;
   int _numTypeParameters;
+  List<UnlinkedPublicNameBuilder> _constMembers;
 
-  UnlinkedPublicNameBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * The name itself.
@@ -3010,62 +4407,81 @@
     _name = _value;
   }
 
+  @override
+  ReferenceKind get kind => _kind ??= ReferenceKind.classOrEnum;
+
   /**
    * The kind of object referred to by the name.
    */
-  void set kind(PrelinkedReferenceKind _value) {
+  void set kind(ReferenceKind _value) {
     assert(!_finished);
     _kind = _value;
   }
 
+  @override
+  int get numTypeParameters => _numTypeParameters ??= 0;
+
   /**
    * If the entity being referred to is generic, the number of type parameters
    * it accepts.  Otherwise zero.
    */
   void set numTypeParameters(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _numTypeParameters = _value;
   }
 
+  @override
+  List<UnlinkedPublicNameBuilder> get constMembers => _constMembers ??= <UnlinkedPublicNameBuilder>[];
+
+  /**
+   * If this [UnlinkedPublicName] is a class, the list of members which can be
+   * referenced from constants - static constant fields, static methods, and
+   * constructors.  Otherwise empty.
+   */
+  void set constMembers(List<UnlinkedPublicNameBuilder> _value) {
+    assert(!_finished);
+    _constMembers = _value;
+  }
+
+  UnlinkedPublicNameBuilder({String name, ReferenceKind kind, int numTypeParameters, List<UnlinkedPublicNameBuilder> constMembers})
+    : _name = name,
+      _kind = kind,
+      _numTypeParameters = numTypeParameters,
+      _constMembers = constMembers;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
     fb.Offset offset_name;
+    fb.Offset offset_constMembers;
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
+    if (!(_constMembers == null || _constMembers.isEmpty)) {
+      offset_constMembers = fbBuilder.writeList(_constMembers.map((b) => b.finish(fbBuilder)).toList());
+    }
     fbBuilder.startTable();
     if (offset_name != null) {
       fbBuilder.addOffset(0, offset_name);
     }
-    if (_kind != null && _kind != PrelinkedReferenceKind.classOrEnum) {
-      fbBuilder.addInt32(1, _kind.index);
+    if (_kind != null && _kind != ReferenceKind.classOrEnum) {
+      fbBuilder.addUint32(1, _kind.index);
     }
     if (_numTypeParameters != null && _numTypeParameters != 0) {
-      fbBuilder.addInt32(2, _numTypeParameters);
+      fbBuilder.addUint32(2, _numTypeParameters);
+    }
+    if (offset_constMembers != null) {
+      fbBuilder.addOffset(3, offset_constMembers);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedPublicNameBuilder encodeUnlinkedPublicName({String name, PrelinkedReferenceKind kind, int numTypeParameters}) {
-  UnlinkedPublicNameBuilder builder = new UnlinkedPublicNameBuilder();
-  builder.name = name;
-  builder.kind = kind;
-  builder.numTypeParameters = numTypeParameters;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a specific name contributed by a
  * compilation unit to a library's public namespace.
  *
- * TODO(paulberry): add a count of generic parameters, so that resynthesis
- * doesn't have to peek into the library to obtain this info.
- *
- * TODO(paulberry): for classes, add info about static members and
- * constructors, since this will be needed to prelink info about constants.
- *
  * TODO(paulberry): some of this information is redundant with information
  * elsewhere in the summary.  Consider reducing the redundancy to reduce
  * summary size.
@@ -3080,13 +4496,20 @@
   /**
    * The kind of object referred to by the name.
    */
-  PrelinkedReferenceKind get kind;
+  ReferenceKind get kind;
 
   /**
    * If the entity being referred to is generic, the number of type parameters
    * it accepts.  Otherwise zero.
    */
   int get numTypeParameters;
+
+  /**
+   * If this [UnlinkedPublicName] is a class, the list of members which can be
+   * referenced from constants - static constant fields, static methods, and
+   * constructors.  Otherwise empty.
+   */
+  List<UnlinkedPublicName> get constMembers;
 }
 
 class _UnlinkedPublicNameReader extends fb.TableReader<_UnlinkedPublicNameImpl> {
@@ -3096,21 +4519,15 @@
   _UnlinkedPublicNameImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNameImpl(bp);
 }
 
-class _UnlinkedPublicNameImpl implements UnlinkedPublicName {
+class _UnlinkedPublicNameImpl extends Object with _UnlinkedPublicNameMixin implements UnlinkedPublicName {
   final fb.BufferPointer _bp;
 
   _UnlinkedPublicNameImpl(this._bp);
 
   String _name;
-  PrelinkedReferenceKind _kind;
+  ReferenceKind _kind;
   int _numTypeParameters;
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "kind": kind,
-    "numTypeParameters": numTypeParameters,
-  };
+  List<UnlinkedPublicName> _constMembers;
 
   @override
   String get name {
@@ -3119,26 +4536,43 @@
   }
 
   @override
-  PrelinkedReferenceKind get kind {
-    _kind ??= PrelinkedReferenceKind.values[const fb.Int32Reader().vTableGet(_bp, 1, 0)];
+  ReferenceKind get kind {
+    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 1, ReferenceKind.classOrEnum);
     return _kind;
   }
 
   @override
   int get numTypeParameters {
-    _numTypeParameters ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _numTypeParameters;
   }
+
+  @override
+  List<UnlinkedPublicName> get constMembers {
+    _constMembers ??= const fb.ListReader<UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 3, const <UnlinkedPublicName>[]);
+    return _constMembers;
+  }
 }
 
-class UnlinkedPublicNamespaceBuilder {
+abstract class _UnlinkedPublicNameMixin implements UnlinkedPublicName {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "kind": kind,
+    "numTypeParameters": numTypeParameters,
+    "constMembers": constMembers,
+  };
+}
+
+class UnlinkedPublicNamespaceBuilder extends Object with _UnlinkedPublicNamespaceMixin implements UnlinkedPublicNamespace {
   bool _finished = false;
 
   List<UnlinkedPublicNameBuilder> _names;
   List<UnlinkedExportPublicBuilder> _exports;
   List<String> _parts;
 
-  UnlinkedPublicNamespaceBuilder();
+  @override
+  List<UnlinkedPublicNameBuilder> get names => _names ??= <UnlinkedPublicNameBuilder>[];
 
   /**
    * Public names defined in the compilation unit.
@@ -3151,6 +4585,9 @@
     _names = _value;
   }
 
+  @override
+  List<UnlinkedExportPublicBuilder> get exports => _exports ??= <UnlinkedExportPublicBuilder>[];
+
   /**
    * Export declarations in the compilation unit.
    */
@@ -3159,6 +4596,9 @@
     _exports = _value;
   }
 
+  @override
+  List<String> get parts => _parts ??= <String>[];
+
   /**
    * URIs referenced by part declarations in the compilation unit.
    */
@@ -3167,6 +4607,11 @@
     _parts = _value;
   }
 
+  UnlinkedPublicNamespaceBuilder({List<UnlinkedPublicNameBuilder> names, List<UnlinkedExportPublicBuilder> exports, List<String> parts})
+    : _names = names,
+      _exports = exports,
+      _parts = parts;
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder));
@@ -3201,14 +4646,6 @@
   }
 }
 
-UnlinkedPublicNamespaceBuilder encodeUnlinkedPublicNamespace({List<UnlinkedPublicNameBuilder> names, List<UnlinkedExportPublicBuilder> exports, List<String> parts}) {
-  UnlinkedPublicNamespaceBuilder builder = new UnlinkedPublicNamespaceBuilder();
-  builder.names = names;
-  builder.exports = exports;
-  builder.parts = parts;
-  return builder;
-}
-
 /**
  * Unlinked summary information about what a compilation unit contributes to a
  * library's public namespace.  This is the subset of [UnlinkedUnit] that is
@@ -3246,7 +4683,7 @@
   _UnlinkedPublicNamespaceImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNamespaceImpl(bp);
 }
 
-class _UnlinkedPublicNamespaceImpl implements UnlinkedPublicNamespace {
+class _UnlinkedPublicNamespaceImpl extends Object with _UnlinkedPublicNamespaceMixin implements UnlinkedPublicNamespace {
   final fb.BufferPointer _bp;
 
   _UnlinkedPublicNamespaceImpl(this._bp);
@@ -3256,13 +4693,6 @@
   List<String> _parts;
 
   @override
-  Map<String, Object> toMap() => {
-    "names": names,
-    "exports": exports,
-    "parts": parts,
-  };
-
-  @override
   List<UnlinkedPublicName> get names {
     _names ??= const fb.ListReader<UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 0, const <UnlinkedPublicName>[]);
     return _names;
@@ -3281,23 +4711,36 @@
   }
 }
 
-class UnlinkedReferenceBuilder {
+abstract class _UnlinkedPublicNamespaceMixin implements UnlinkedPublicNamespace {
+  @override
+  Map<String, Object> toMap() => {
+    "names": names,
+    "exports": exports,
+    "parts": parts,
+  };
+}
+
+class UnlinkedReferenceBuilder extends Object with _UnlinkedReferenceMixin implements UnlinkedReference {
   bool _finished = false;
 
   String _name;
   int _prefixReference;
 
-  UnlinkedReferenceBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
-   * Name of the entity being referred to.  The empty string refers to the
-   * pseudo-type `dynamic`.
+   * Name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
    */
   void set name(String _value) {
     assert(!_finished);
     _name = _value;
   }
 
+  @override
+  int get prefixReference => _prefixReference ??= 0;
+
   /**
    * Prefix used to refer to the entity, or zero if no prefix is used.  This is
    * an index into [UnlinkedUnit.references].
@@ -3308,9 +4751,14 @@
    */
   void set prefixReference(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _prefixReference = _value;
   }
 
+  UnlinkedReferenceBuilder({String name, int prefixReference})
+    : _name = name,
+      _prefixReference = prefixReference;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -3323,19 +4771,12 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_prefixReference != null && _prefixReference != 0) {
-      fbBuilder.addInt32(1, _prefixReference);
+      fbBuilder.addUint32(1, _prefixReference);
     }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedReferenceBuilder encodeUnlinkedReference({String name, int prefixReference}) {
-  UnlinkedReferenceBuilder builder = new UnlinkedReferenceBuilder();
-  builder.name = name;
-  builder.prefixReference = prefixReference;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a name referred to in one library that
  * might be defined in another.
@@ -3343,8 +4784,8 @@
 abstract class UnlinkedReference extends base.SummaryClass {
 
   /**
-   * Name of the entity being referred to.  The empty string refers to the
-   * pseudo-type `dynamic`.
+   * Name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
    */
   String get name;
 
@@ -3366,7 +4807,7 @@
   _UnlinkedReferenceImpl createObject(fb.BufferPointer bp) => new _UnlinkedReferenceImpl(bp);
 }
 
-class _UnlinkedReferenceImpl implements UnlinkedReference {
+class _UnlinkedReferenceImpl extends Object with _UnlinkedReferenceMixin implements UnlinkedReference {
   final fb.BufferPointer _bp;
 
   _UnlinkedReferenceImpl(this._bp);
@@ -3375,12 +4816,6 @@
   int _prefixReference;
 
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "prefixReference": prefixReference,
-  };
-
-  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _name;
@@ -3388,22 +4823,31 @@
 
   @override
   int get prefixReference {
-    _prefixReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _prefixReference;
   }
 }
 
-class UnlinkedTypedefBuilder {
+abstract class _UnlinkedReferenceMixin implements UnlinkedReference {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "prefixReference": prefixReference,
+  };
+}
+
+class UnlinkedTypedefBuilder extends Object with _UnlinkedTypedefMixin implements UnlinkedTypedef {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
   UnlinkedDocumentationCommentBuilder _documentationComment;
   List<UnlinkedTypeParamBuilder> _typeParameters;
-  UnlinkedTypeRefBuilder _returnType;
+  EntityRefBuilder _returnType;
   List<UnlinkedParamBuilder> _parameters;
 
-  UnlinkedTypedefBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the typedef.
@@ -3413,14 +4857,21 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the typedef name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the typedef, or `null` if there is no
    * documentation comment.
@@ -3430,6 +4881,9 @@
     _documentationComment = _value;
   }
 
+  @override
+  List<UnlinkedTypeParamBuilder> get typeParameters => _typeParameters ??= <UnlinkedTypeParamBuilder>[];
+
   /**
    * Type parameters of the typedef, if any.
    */
@@ -3438,14 +4892,20 @@
     _typeParameters = _value;
   }
 
+  @override
+  EntityRefBuilder get returnType => _returnType;
+
   /**
-   * Return type of the typedef.  Absent if the return type is `void`.
+   * Return type of the typedef.
    */
-  void set returnType(UnlinkedTypeRefBuilder _value) {
+  void set returnType(EntityRefBuilder _value) {
     assert(!_finished);
     _returnType = _value;
   }
 
+  @override
+  List<UnlinkedParamBuilder> get parameters => _parameters ??= <UnlinkedParamBuilder>[];
+
   /**
    * Parameters of the executable, if any.
    */
@@ -3454,6 +4914,14 @@
     _parameters = _value;
   }
 
+  UnlinkedTypedefBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, EntityRefBuilder returnType, List<UnlinkedParamBuilder> parameters})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment,
+      _typeParameters = typeParameters,
+      _returnType = returnType,
+      _parameters = parameters;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -3482,7 +4950,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -3500,17 +4968,6 @@
   }
 }
 
-UnlinkedTypedefBuilder encodeUnlinkedTypedef({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, List<UnlinkedTypeParamBuilder> typeParameters, UnlinkedTypeRefBuilder returnType, List<UnlinkedParamBuilder> parameters}) {
-  UnlinkedTypedefBuilder builder = new UnlinkedTypedefBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  builder.typeParameters = typeParameters;
-  builder.returnType = returnType;
-  builder.parameters = parameters;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a typedef declaration.
  */
@@ -3538,9 +4995,9 @@
   List<UnlinkedTypeParam> get typeParameters;
 
   /**
-   * Return type of the typedef.  Absent if the return type is `void`.
+   * Return type of the typedef.
    */
-  UnlinkedTypeRef get returnType;
+  EntityRef get returnType;
 
   /**
    * Parameters of the executable, if any.
@@ -3555,7 +5012,7 @@
   _UnlinkedTypedefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypedefImpl(bp);
 }
 
-class _UnlinkedTypedefImpl implements UnlinkedTypedef {
+class _UnlinkedTypedefImpl extends Object with _UnlinkedTypedefMixin implements UnlinkedTypedef {
   final fb.BufferPointer _bp;
 
   _UnlinkedTypedefImpl(this._bp);
@@ -3564,20 +5021,10 @@
   int _nameOffset;
   UnlinkedDocumentationComment _documentationComment;
   List<UnlinkedTypeParam> _typeParameters;
-  UnlinkedTypeRef _returnType;
+  EntityRef _returnType;
   List<UnlinkedParam> _parameters;
 
   @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-    "typeParameters": typeParameters,
-    "returnType": returnType,
-    "parameters": parameters,
-  };
-
-  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _name;
@@ -3585,7 +5032,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -3602,8 +5049,8 @@
   }
 
   @override
-  UnlinkedTypeRef get returnType {
-    _returnType ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 4, null);
+  EntityRef get returnType {
+    _returnType ??= const _EntityRefReader().vTableGet(_bp, 4, null);
     return _returnType;
   }
 
@@ -3614,14 +5061,27 @@
   }
 }
 
-class UnlinkedTypeParamBuilder {
+abstract class _UnlinkedTypedefMixin implements UnlinkedTypedef {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "typeParameters": typeParameters,
+    "returnType": returnType,
+    "parameters": parameters,
+  };
+}
+
+class UnlinkedTypeParamBuilder extends Object with _UnlinkedTypeParamMixin implements UnlinkedTypeParam {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
-  UnlinkedTypeRefBuilder _bound;
+  EntityRefBuilder _bound;
 
-  UnlinkedTypeParamBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the type parameter.
@@ -3631,23 +5091,35 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the type parameter name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  EntityRefBuilder get bound => _bound;
+
   /**
    * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
    * null.
    */
-  void set bound(UnlinkedTypeRefBuilder _value) {
+  void set bound(EntityRefBuilder _value) {
     assert(!_finished);
     _bound = _value;
   }
 
+  UnlinkedTypeParamBuilder({String name, int nameOffset, EntityRefBuilder bound})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _bound = bound;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
@@ -3664,7 +5136,7 @@
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_bound != null) {
       fbBuilder.addOffset(2, offset_bound);
@@ -3673,14 +5145,6 @@
   }
 }
 
-UnlinkedTypeParamBuilder encodeUnlinkedTypeParam({String name, int nameOffset, UnlinkedTypeRefBuilder bound}) {
-  UnlinkedTypeParamBuilder builder = new UnlinkedTypeParamBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.bound = bound;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a type parameter declaration.
  */
@@ -3700,7 +5164,7 @@
    * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
    * null.
    */
-  UnlinkedTypeRef get bound;
+  EntityRef get bound;
 }
 
 class _UnlinkedTypeParamReader extends fb.TableReader<_UnlinkedTypeParamImpl> {
@@ -3710,21 +5174,14 @@
   _UnlinkedTypeParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeParamImpl(bp);
 }
 
-class _UnlinkedTypeParamImpl implements UnlinkedTypeParam {
+class _UnlinkedTypeParamImpl extends Object with _UnlinkedTypeParamMixin implements UnlinkedTypeParam {
   final fb.BufferPointer _bp;
 
   _UnlinkedTypeParamImpl(this._bp);
 
   String _name;
   int _nameOffset;
-  UnlinkedTypeRef _bound;
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "bound": bound,
-  };
+  EntityRef _bound;
 
   @override
   String get name {
@@ -3734,191 +5191,27 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
   @override
-  UnlinkedTypeRef get bound {
-    _bound ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 2, null);
+  EntityRef get bound {
+    _bound ??= const _EntityRefReader().vTableGet(_bp, 2, null);
     return _bound;
   }
 }
 
-class UnlinkedTypeRefBuilder {
-  bool _finished = false;
-
-  int _reference;
-  int _paramReference;
-  List<UnlinkedTypeRefBuilder> _typeArguments;
-
-  UnlinkedTypeRefBuilder();
-
-  /**
-   * 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
-   * [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.
-   */
-  void set reference(int _value) {
-    assert(!_finished);
-    _reference = _value;
-  }
-
-  /**
-   * If this is a reference to a type parameter, one-based index into the list
-   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
-   * Bruijn index conventions; that is, innermost parameters come first, and
-   * if a class or method has multiple parameters, they are indexed from right
-   * to left.  So for instance, if the enclosing declaration is
-   *
-   *     class C<T,U> {
-   *       m<V,W> {
-   *         ...
-   *       }
-   *     }
-   *
-   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
-   * respectively.
-   *
-   * If the type being referred to is not a type parameter, [paramReference] is
-   * zero.
-   */
-  void set paramReference(int _value) {
-    assert(!_finished);
-    _paramReference = _value;
-  }
-
-  /**
-   * If this is an instantiation of a generic type, the type arguments used to
-   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
-   */
-  void set typeArguments(List<UnlinkedTypeRefBuilder> _value) {
-    assert(!_finished);
-    _typeArguments = _value;
-  }
-
-  fb.Offset finish(fb.Builder fbBuilder) {
-    assert(!_finished);
-    _finished = true;
-    fb.Offset offset_typeArguments;
-    if (!(_typeArguments == null || _typeArguments.isEmpty)) {
-      offset_typeArguments = fbBuilder.writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
-    }
-    fbBuilder.startTable();
-    if (_reference != null && _reference != 0) {
-      fbBuilder.addInt32(0, _reference);
-    }
-    if (_paramReference != null && _paramReference != 0) {
-      fbBuilder.addInt32(1, _paramReference);
-    }
-    if (offset_typeArguments != null) {
-      fbBuilder.addOffset(2, offset_typeArguments);
-    }
-    return fbBuilder.endTable();
-  }
-}
-
-UnlinkedTypeRefBuilder encodeUnlinkedTypeRef({int reference, int paramReference, List<UnlinkedTypeRefBuilder> typeArguments}) {
-  UnlinkedTypeRefBuilder builder = new UnlinkedTypeRefBuilder();
-  builder.reference = reference;
-  builder.paramReference = paramReference;
-  builder.typeArguments = typeArguments;
-  return builder;
-}
-
-/**
- * Unlinked summary information about a reference to a type.
- */
-abstract class UnlinkedTypeRef extends base.SummaryClass {
-
-  /**
-   * 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
-   * [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.
-   */
-  int get reference;
-
-  /**
-   * If this is a reference to a type parameter, one-based index into the list
-   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
-   * Bruijn index conventions; that is, innermost parameters come first, and
-   * if a class or method has multiple parameters, they are indexed from right
-   * to left.  So for instance, if the enclosing declaration is
-   *
-   *     class C<T,U> {
-   *       m<V,W> {
-   *         ...
-   *       }
-   *     }
-   *
-   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
-   * respectively.
-   *
-   * If the type being referred to is not a type parameter, [paramReference] is
-   * zero.
-   */
-  int get paramReference;
-
-  /**
-   * If this is an instantiation of a generic type, the type arguments used to
-   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
-   */
-  List<UnlinkedTypeRef> get typeArguments;
-}
-
-class _UnlinkedTypeRefReader extends fb.TableReader<_UnlinkedTypeRefImpl> {
-  const _UnlinkedTypeRefReader();
-
-  @override
-  _UnlinkedTypeRefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeRefImpl(bp);
-}
-
-class _UnlinkedTypeRefImpl implements UnlinkedTypeRef {
-  final fb.BufferPointer _bp;
-
-  _UnlinkedTypeRefImpl(this._bp);
-
-  int _reference;
-  int _paramReference;
-  List<UnlinkedTypeRef> _typeArguments;
-
+abstract class _UnlinkedTypeParamMixin implements UnlinkedTypeParam {
   @override
   Map<String, Object> toMap() => {
-    "reference": reference,
-    "paramReference": paramReference,
-    "typeArguments": typeArguments,
+    "name": name,
+    "nameOffset": nameOffset,
+    "bound": bound,
   };
-
-  @override
-  int get reference {
-    _reference ??= const fb.Int32Reader().vTableGet(_bp, 0, 0);
-    return _reference;
-  }
-
-  @override
-  int get paramReference {
-    _paramReference ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
-    return _paramReference;
-  }
-
-  @override
-  List<UnlinkedTypeRef> get typeArguments {
-    _typeArguments ??= const fb.ListReader<UnlinkedTypeRef>(const _UnlinkedTypeRefReader()).vTableGet(_bp, 2, const <UnlinkedTypeRef>[]);
-    return _typeArguments;
-  }
 }
 
-class UnlinkedUnitBuilder {
+class UnlinkedUnitBuilder extends Object with _UnlinkedUnitMixin implements UnlinkedUnit {
   bool _finished = false;
 
   String _libraryName;
@@ -3936,7 +5229,8 @@
   List<UnlinkedTypedefBuilder> _typedefs;
   List<UnlinkedVariableBuilder> _variables;
 
-  UnlinkedUnitBuilder();
+  @override
+  String get libraryName => _libraryName ??= '';
 
   /**
    * Name of the library (from a "library" declaration, if present).
@@ -3946,24 +5240,35 @@
     _libraryName = _value;
   }
 
+  @override
+  int get libraryNameOffset => _libraryNameOffset ??= 0;
+
   /**
    * Offset of the library name relative to the beginning of the file (or 0 if
    * the library has no name).
    */
   void set libraryNameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _libraryNameOffset = _value;
   }
 
+  @override
+  int get libraryNameLength => _libraryNameLength ??= 0;
+
   /**
    * Length of the library name as it appears in the source code (or 0 if the
    * library has no name).
    */
   void set libraryNameLength(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _libraryNameLength = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get libraryDocumentationComment => _libraryDocumentationComment;
+
   /**
    * Documentation comment for the library, or `null` if there is no
    * documentation comment.
@@ -3973,6 +5278,9 @@
     _libraryDocumentationComment = _value;
   }
 
+  @override
+  UnlinkedPublicNamespaceBuilder get publicNamespace => _publicNamespace;
+
   /**
    * Unlinked public namespace of this compilation unit.
    */
@@ -3981,16 +5289,24 @@
     _publicNamespace = _value;
   }
 
+  @override
+  List<UnlinkedReferenceBuilder> get references => _references ??= <UnlinkedReferenceBuilder>[];
+
   /**
    * 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".
+   * zeroth element of this array is always populated and is used to represent
+   * the absence of a reference in places where a reference is optional (for
+   * example [UnlinkedReference.prefixReference or
+   * UnlinkedImport.prefixReference]).
    */
   void set references(List<UnlinkedReferenceBuilder> _value) {
     assert(!_finished);
     _references = _value;
   }
 
+  @override
+  List<UnlinkedClassBuilder> get classes => _classes ??= <UnlinkedClassBuilder>[];
+
   /**
    * Classes declared in the compilation unit.
    */
@@ -3999,6 +5315,9 @@
     _classes = _value;
   }
 
+  @override
+  List<UnlinkedEnumBuilder> get enums => _enums ??= <UnlinkedEnumBuilder>[];
+
   /**
    * Enums declared in the compilation unit.
    */
@@ -4007,6 +5326,9 @@
     _enums = _value;
   }
 
+  @override
+  List<UnlinkedExecutableBuilder> get executables => _executables ??= <UnlinkedExecutableBuilder>[];
+
   /**
    * Top level executable objects (functions, getters, and setters) declared in
    * the compilation unit.
@@ -4016,6 +5338,9 @@
     _executables = _value;
   }
 
+  @override
+  List<UnlinkedExportNonPublicBuilder> get exports => _exports ??= <UnlinkedExportNonPublicBuilder>[];
+
   /**
    * Export declarations in the compilation unit.
    */
@@ -4024,6 +5349,9 @@
     _exports = _value;
   }
 
+  @override
+  List<UnlinkedImportBuilder> get imports => _imports ??= <UnlinkedImportBuilder>[];
+
   /**
    * Import declarations in the compilation unit.
    */
@@ -4032,6 +5360,9 @@
     _imports = _value;
   }
 
+  @override
+  List<UnlinkedPartBuilder> get parts => _parts ??= <UnlinkedPartBuilder>[];
+
   /**
    * Part declarations in the compilation unit.
    */
@@ -4040,6 +5371,9 @@
     _parts = _value;
   }
 
+  @override
+  List<UnlinkedTypedefBuilder> get typedefs => _typedefs ??= <UnlinkedTypedefBuilder>[];
+
   /**
    * Typedefs declared in the compilation unit.
    */
@@ -4048,6 +5382,9 @@
     _typedefs = _value;
   }
 
+  @override
+  List<UnlinkedVariableBuilder> get variables => _variables ??= <UnlinkedVariableBuilder>[];
+
   /**
    * Top level variables declared in the compilation unit.
    */
@@ -4056,6 +5393,22 @@
     _variables = _value;
   }
 
+  UnlinkedUnitBuilder({String libraryName, int libraryNameOffset, int libraryNameLength, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedPartBuilder> parts, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables})
+    : _libraryName = libraryName,
+      _libraryNameOffset = libraryNameOffset,
+      _libraryNameLength = libraryNameLength,
+      _libraryDocumentationComment = libraryDocumentationComment,
+      _publicNamespace = publicNamespace,
+      _references = references,
+      _classes = classes,
+      _enums = enums,
+      _executables = executables,
+      _exports = exports,
+      _imports = imports,
+      _parts = parts,
+      _typedefs = typedefs,
+      _variables = variables;
+
   List<int> toBuffer() {
     fb.Builder fbBuilder = new fb.Builder();
     return fbBuilder.finish(finish(fbBuilder));
@@ -4117,10 +5470,10 @@
       fbBuilder.addOffset(0, offset_libraryName);
     }
     if (_libraryNameOffset != null && _libraryNameOffset != 0) {
-      fbBuilder.addInt32(1, _libraryNameOffset);
+      fbBuilder.addUint32(1, _libraryNameOffset);
     }
     if (_libraryNameLength != null && _libraryNameLength != 0) {
-      fbBuilder.addInt32(2, _libraryNameLength);
+      fbBuilder.addUint32(2, _libraryNameLength);
     }
     if (offset_libraryDocumentationComment != null) {
       fbBuilder.addOffset(3, offset_libraryDocumentationComment);
@@ -4159,25 +5512,6 @@
   }
 }
 
-UnlinkedUnitBuilder encodeUnlinkedUnit({String libraryName, int libraryNameOffset, int libraryNameLength, UnlinkedDocumentationCommentBuilder libraryDocumentationComment, UnlinkedPublicNamespaceBuilder publicNamespace, List<UnlinkedReferenceBuilder> references, List<UnlinkedClassBuilder> classes, List<UnlinkedEnumBuilder> enums, List<UnlinkedExecutableBuilder> executables, List<UnlinkedExportNonPublicBuilder> exports, List<UnlinkedImportBuilder> imports, List<UnlinkedPartBuilder> parts, List<UnlinkedTypedefBuilder> typedefs, List<UnlinkedVariableBuilder> variables}) {
-  UnlinkedUnitBuilder builder = new UnlinkedUnitBuilder();
-  builder.libraryName = libraryName;
-  builder.libraryNameOffset = libraryNameOffset;
-  builder.libraryNameLength = libraryNameLength;
-  builder.libraryDocumentationComment = libraryDocumentationComment;
-  builder.publicNamespace = publicNamespace;
-  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;
-}
-
 /**
  * Unlinked summary information about a compilation unit ("part file").
  */
@@ -4217,8 +5551,10 @@
 
   /**
    * 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".
+   * zeroth element of this array is always populated and is used to represent
+   * the absence of a reference in places where a reference is optional (for
+   * example [UnlinkedReference.prefixReference or
+   * UnlinkedImport.prefixReference]).
    */
   List<UnlinkedReference> get references;
 
@@ -4271,7 +5607,7 @@
   _UnlinkedUnitImpl createObject(fb.BufferPointer bp) => new _UnlinkedUnitImpl(bp);
 }
 
-class _UnlinkedUnitImpl implements UnlinkedUnit {
+class _UnlinkedUnitImpl extends Object with _UnlinkedUnitMixin implements UnlinkedUnit {
   final fb.BufferPointer _bp;
 
   _UnlinkedUnitImpl(this._bp);
@@ -4292,24 +5628,6 @@
   List<UnlinkedVariable> _variables;
 
   @override
-  Map<String, Object> toMap() => {
-    "libraryName": libraryName,
-    "libraryNameOffset": libraryNameOffset,
-    "libraryNameLength": libraryNameLength,
-    "libraryDocumentationComment": libraryDocumentationComment,
-    "publicNamespace": publicNamespace,
-    "references": references,
-    "classes": classes,
-    "enums": enums,
-    "executables": executables,
-    "exports": exports,
-    "imports": imports,
-    "parts": parts,
-    "typedefs": typedefs,
-    "variables": variables,
-  };
-
-  @override
   String get libraryName {
     _libraryName ??= const fb.StringReader().vTableGet(_bp, 0, '');
     return _libraryName;
@@ -4317,13 +5635,13 @@
 
   @override
   int get libraryNameOffset {
-    _libraryNameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _libraryNameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _libraryNameOffset;
   }
 
   @override
   int get libraryNameLength {
-    _libraryNameLength ??= const fb.Int32Reader().vTableGet(_bp, 2, 0);
+    _libraryNameLength ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _libraryNameLength;
   }
 
@@ -4394,19 +5712,42 @@
   }
 }
 
-class UnlinkedVariableBuilder {
+abstract class _UnlinkedUnitMixin implements UnlinkedUnit {
+  @override
+  Map<String, Object> toMap() => {
+    "libraryName": libraryName,
+    "libraryNameOffset": libraryNameOffset,
+    "libraryNameLength": libraryNameLength,
+    "libraryDocumentationComment": libraryDocumentationComment,
+    "publicNamespace": publicNamespace,
+    "references": references,
+    "classes": classes,
+    "enums": enums,
+    "executables": executables,
+    "exports": exports,
+    "imports": imports,
+    "parts": parts,
+    "typedefs": typedefs,
+    "variables": variables,
+  };
+}
+
+class UnlinkedVariableBuilder extends Object with _UnlinkedVariableMixin implements UnlinkedVariable {
   bool _finished = false;
 
   String _name;
   int _nameOffset;
   UnlinkedDocumentationCommentBuilder _documentationComment;
-  UnlinkedTypeRefBuilder _type;
+  EntityRefBuilder _type;
+  UnlinkedConstBuilder _constExpr;
   bool _isStatic;
   bool _isFinal;
   bool _isConst;
-  bool _hasImplicitType;
+  int _propagatedTypeSlot;
+  int _inferredTypeSlot;
 
-  UnlinkedVariableBuilder();
+  @override
+  String get name => _name ??= '';
 
   /**
    * Name of the variable.
@@ -4416,14 +5757,21 @@
     _name = _value;
   }
 
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
   /**
    * Offset of the variable name relative to the beginning of the file.
    */
   void set nameOffset(int _value) {
     assert(!_finished);
+    assert(_value == null || _value >= 0);
     _nameOffset = _value;
   }
 
+  @override
+  UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
+
   /**
    * Documentation comment for the variable, or `null` if there is no
    * documentation comment.
@@ -4433,15 +5781,32 @@
     _documentationComment = _value;
   }
 
+  @override
+  EntityRefBuilder get type => _type;
+
   /**
-   * 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.
+   * Declared type of the variable.  Absent if the type is implicit.
    */
-  void set type(UnlinkedTypeRefBuilder _value) {
+  void set type(EntityRefBuilder _value) {
     assert(!_finished);
     _type = _value;
   }
 
+  @override
+  UnlinkedConstBuilder get constExpr => _constExpr;
+
+  /**
+   * If [isConst] is true, and the variable has an initializer, the constant
+   * expression in the initializer.
+   */
+  void set constExpr(UnlinkedConstBuilder _value) {
+    assert(!_finished);
+    _constExpr = _value;
+  }
+
+  @override
+  bool get isStatic => _isStatic ??= false;
+
   /**
    * Indicates whether the variable is declared using the `static` keyword.
    *
@@ -4454,6 +5819,9 @@
     _isStatic = _value;
   }
 
+  @override
+  bool get isFinal => _isFinal ??= false;
+
   /**
    * Indicates whether the variable is declared using the `final` keyword.
    */
@@ -4462,6 +5830,9 @@
     _isFinal = _value;
   }
 
+  @override
+  bool get isConst => _isConst ??= false;
+
   /**
    * Indicates whether the variable is declared using the `const` keyword.
    */
@@ -4470,20 +5841,57 @@
     _isConst = _value;
   }
 
+  @override
+  int get propagatedTypeSlot => _propagatedTypeSlot ??= 0;
+
   /**
-   * Indicates whether this variable lacks an explicit type declaration.
+   * If this variable is propagable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the propagated type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then this variable's
+   * propagated type is the same as its declared type.
+   *
+   * Non-propagable variables have a [propagatedTypeSlot] of zero.
    */
-  void set hasImplicitType(bool _value) {
+  void set propagatedTypeSlot(int _value) {
     assert(!_finished);
-    _hasImplicitType = _value;
+    assert(_value == null || _value >= 0);
+    _propagatedTypeSlot = _value;
   }
 
+  @override
+  int get inferredTypeSlot => _inferredTypeSlot ??= 0;
+
+  /**
+   * If this variable is inferrable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the inferred type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then no type was
+   * inferred for this variable, so its static type is `dynamic`.
+   */
+  void set inferredTypeSlot(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _inferredTypeSlot = _value;
+  }
+
+  UnlinkedVariableBuilder({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, EntityRefBuilder type, UnlinkedConstBuilder constExpr, bool isStatic, bool isFinal, bool isConst, int propagatedTypeSlot, int inferredTypeSlot})
+    : _name = name,
+      _nameOffset = nameOffset,
+      _documentationComment = documentationComment,
+      _type = type,
+      _constExpr = constExpr,
+      _isStatic = isStatic,
+      _isFinal = isFinal,
+      _isConst = isConst,
+      _propagatedTypeSlot = propagatedTypeSlot,
+      _inferredTypeSlot = inferredTypeSlot;
+
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
     fb.Offset offset_name;
     fb.Offset offset_documentationComment;
     fb.Offset offset_type;
+    fb.Offset offset_constExpr;
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
@@ -4493,12 +5901,15 @@
     if (_type != null) {
       offset_type = _type.finish(fbBuilder);
     }
+    if (_constExpr != null) {
+      offset_constExpr = _constExpr.finish(fbBuilder);
+    }
     fbBuilder.startTable();
     if (offset_name != null) {
       fbBuilder.addOffset(0, offset_name);
     }
     if (_nameOffset != null && _nameOffset != 0) {
-      fbBuilder.addInt32(1, _nameOffset);
+      fbBuilder.addUint32(1, _nameOffset);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(2, offset_documentationComment);
@@ -4506,35 +5917,28 @@
     if (offset_type != null) {
       fbBuilder.addOffset(3, offset_type);
     }
-    if (_isStatic == true) {
-      fbBuilder.addBool(4, true);
+    if (offset_constExpr != null) {
+      fbBuilder.addOffset(4, offset_constExpr);
     }
-    if (_isFinal == true) {
+    if (_isStatic == true) {
       fbBuilder.addBool(5, true);
     }
-    if (_isConst == true) {
+    if (_isFinal == true) {
       fbBuilder.addBool(6, true);
     }
-    if (_hasImplicitType == true) {
+    if (_isConst == true) {
       fbBuilder.addBool(7, true);
     }
+    if (_propagatedTypeSlot != null && _propagatedTypeSlot != 0) {
+      fbBuilder.addUint32(8, _propagatedTypeSlot);
+    }
+    if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
+      fbBuilder.addUint32(9, _inferredTypeSlot);
+    }
     return fbBuilder.endTable();
   }
 }
 
-UnlinkedVariableBuilder encodeUnlinkedVariable({String name, int nameOffset, UnlinkedDocumentationCommentBuilder documentationComment, UnlinkedTypeRefBuilder type, bool isStatic, bool isFinal, bool isConst, bool hasImplicitType}) {
-  UnlinkedVariableBuilder builder = new UnlinkedVariableBuilder();
-  builder.name = name;
-  builder.nameOffset = nameOffset;
-  builder.documentationComment = documentationComment;
-  builder.type = type;
-  builder.isStatic = isStatic;
-  builder.isFinal = isFinal;
-  builder.isConst = isConst;
-  builder.hasImplicitType = hasImplicitType;
-  return builder;
-}
-
 /**
  * Unlinked summary information about a top level variable, local variable, or
  * a field.
@@ -4558,10 +5962,15 @@
   UnlinkedDocumentationComment get documentationComment;
 
   /**
-   * 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.
+   * Declared type of the variable.  Absent if the type is implicit.
    */
-  UnlinkedTypeRef get type;
+  EntityRef get type;
+
+  /**
+   * If [isConst] is true, and the variable has an initializer, the constant
+   * expression in the initializer.
+   */
+  UnlinkedConst get constExpr;
 
   /**
    * Indicates whether the variable is declared using the `static` keyword.
@@ -4583,9 +5992,22 @@
   bool get isConst;
 
   /**
-   * Indicates whether this variable lacks an explicit type declaration.
+   * If this variable is propagable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the propagated type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then this variable's
+   * propagated type is the same as its declared type.
+   *
+   * Non-propagable variables have a [propagatedTypeSlot] of zero.
    */
-  bool get hasImplicitType;
+  int get propagatedTypeSlot;
+
+  /**
+   * If this variable is inferrable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the inferred type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then no type was
+   * inferred for this variable, so its static type is `dynamic`.
+   */
+  int get inferredTypeSlot;
 }
 
 class _UnlinkedVariableReader extends fb.TableReader<_UnlinkedVariableImpl> {
@@ -4595,7 +6017,7 @@
   _UnlinkedVariableImpl createObject(fb.BufferPointer bp) => new _UnlinkedVariableImpl(bp);
 }
 
-class _UnlinkedVariableImpl implements UnlinkedVariable {
+class _UnlinkedVariableImpl extends Object with _UnlinkedVariableMixin implements UnlinkedVariable {
   final fb.BufferPointer _bp;
 
   _UnlinkedVariableImpl(this._bp);
@@ -4603,23 +6025,13 @@
   String _name;
   int _nameOffset;
   UnlinkedDocumentationComment _documentationComment;
-  UnlinkedTypeRef _type;
+  EntityRef _type;
+  UnlinkedConst _constExpr;
   bool _isStatic;
   bool _isFinal;
   bool _isConst;
-  bool _hasImplicitType;
-
-  @override
-  Map<String, Object> toMap() => {
-    "name": name,
-    "nameOffset": nameOffset,
-    "documentationComment": documentationComment,
-    "type": type,
-    "isStatic": isStatic,
-    "isFinal": isFinal,
-    "isConst": isConst,
-    "hasImplicitType": hasImplicitType,
-  };
+  int _propagatedTypeSlot;
+  int _inferredTypeSlot;
 
   @override
   String get name {
@@ -4629,7 +6041,7 @@
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Int32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
     return _nameOffset;
   }
 
@@ -4640,33 +6052,61 @@
   }
 
   @override
-  UnlinkedTypeRef get type {
-    _type ??= const _UnlinkedTypeRefReader().vTableGet(_bp, 3, null);
+  EntityRef get type {
+    _type ??= const _EntityRefReader().vTableGet(_bp, 3, null);
     return _type;
   }
 
   @override
+  UnlinkedConst get constExpr {
+    _constExpr ??= const _UnlinkedConstReader().vTableGet(_bp, 4, null);
+    return _constExpr;
+  }
+
+  @override
   bool get isStatic {
-    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 5, false);
     return _isStatic;
   }
 
   @override
   bool get isFinal {
-    _isFinal ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    _isFinal ??= const fb.BoolReader().vTableGet(_bp, 6, false);
     return _isFinal;
   }
 
   @override
   bool get isConst {
-    _isConst ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    _isConst ??= const fb.BoolReader().vTableGet(_bp, 7, false);
     return _isConst;
   }
 
   @override
-  bool get hasImplicitType {
-    _hasImplicitType ??= const fb.BoolReader().vTableGet(_bp, 7, false);
-    return _hasImplicitType;
+  int get propagatedTypeSlot {
+    _propagatedTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 8, 0);
+    return _propagatedTypeSlot;
   }
+
+  @override
+  int get inferredTypeSlot {
+    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 9, 0);
+    return _inferredTypeSlot;
+  }
+}
+
+abstract class _UnlinkedVariableMixin implements UnlinkedVariable {
+  @override
+  Map<String, Object> toMap() => {
+    "name": name,
+    "nameOffset": nameOffset,
+    "documentationComment": documentationComment,
+    "type": type,
+    "constExpr": constExpr,
+    "isStatic": isStatic,
+    "isFinal": isFinal,
+    "isConst": isConst,
+    "propagatedTypeSlot": propagatedTypeSlot,
+    "inferredTypeSlot": inferredTypeSlot,
+  };
 }
 
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index ad4834f..1e3caad 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -6,7 +6,7 @@
 import 'package:analyzer/src/summary/name_filter.dart';
 
 /**
- * Create a [PrelinkedLibraryBuilder] corresponding to the given
+ * Create a [LinkedLibraryBuilder] corresponding to the given
  * [definingUnit], which should be the defining compilation unit for a library.
  * Compilation units referenced by the defining compilation unit via `part`
  * declarations will be retrieved using [getPart].  Public namespaces for
@@ -14,8 +14,8 @@
  * declarations (and files reachable from them via `part` and `export`
  * declarations) will be retrieved using [getImport].
  */
-PrelinkedLibraryBuilder prelink(UnlinkedUnit definingUnit,
-    GetPartCallback getPart, GetImportCallback getImport) {
+LinkedLibraryBuilder prelink(UnlinkedUnit definingUnit, GetPartCallback getPart,
+    GetImportCallback getImport) {
   return new _Prelinker(definingUnit, getPart, getImport).prelink();
 }
 
@@ -32,7 +32,7 @@
 
 /**
  * Type of the callback used by the prelinker to obtain unlinked summaries of
- * part files of the library to be prelinked.  [relaviteUri] should be
+ * part files of the library to be prelinked.  [relativeUri] should be
  * interpreted relative to the defining compilation unit of the library being
  * prelinked.
  *
@@ -41,6 +41,16 @@
 typedef UnlinkedUnit GetPartCallback(String relativeUri);
 
 /**
+ * A [_Meaning] representing a class.
+ */
+class _ClassMeaning extends _Meaning {
+  final Map<String, _Meaning> namespace;
+
+  _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace)
+      : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters);
+}
+
+/**
  * A [_Meaning] stores all the information necessary to find the declaration
  * referred to by a name in a namespace.
  */
@@ -53,7 +63,7 @@
   /**
    * The kind of entity being referred to.
    */
-  final PrelinkedReferenceKind kind;
+  final ReferenceKind kind;
 
   /**
    * Which of the dependencies of the library being prelinked contains the
@@ -70,10 +80,18 @@
   _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters);
 
   /**
-   * Encode this [_Meaning] as a [PrelinkedReference].
+ * Encode this [_Meaning] as a [LinkedExportName], using the given [name].
+ */
+  LinkedExportName encodeExportName(String name) {
+    return new LinkedExportNameBuilder(
+        name: name, dependency: dependency, unit: unit, kind: kind);
+  }
+
+/**
+   * Encode this [_Meaning] as a [LinkedReference].
    */
-  PrelinkedReferenceBuilder encode() {
-    return encodePrelinkedReference(
+  LinkedReferenceBuilder encodeReference() {
+    return new LinkedReferenceBuilder(
         unit: unit,
         kind: kind,
         dependency: dependency,
@@ -87,7 +105,7 @@
 class _PrefixMeaning extends _Meaning {
   final Map<String, _Meaning> namespace = <String, _Meaning>{};
 
-  _PrefixMeaning() : super(0, PrelinkedReferenceKind.prefix, 0, 0);
+  _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0);
 }
 
 /**
@@ -117,15 +135,17 @@
    * Names defined inside the library being prelinked.
    */
   final Map<String, _Meaning> privateNamespace = <String, _Meaning>{
-    '': new _Meaning(0, PrelinkedReferenceKind.classOrEnum, 0, 0)
+    'dynamic': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0),
+    'void': new _Meaning(0, ReferenceKind.classOrEnum, 0, 0)
   };
 
   /**
    * List of dependencies of the library being prelinked.  This will be output
-   * to [PrelinkedLibrary.dependencies].
+   * to [LinkedLibrary.dependencies].
    */
-  final List<PrelinkedDependencyBuilder> dependencies =
-      <PrelinkedDependencyBuilder>[encodePrelinkedDependency()];
+  final List<LinkedDependencyBuilder> dependencies = <LinkedDependencyBuilder>[
+    new LinkedDependencyBuilder()
+  ];
 
   /**
    * Map from the relative URI of a dependent library to the index of the
@@ -157,9 +177,9 @@
     int dependency = dependencies.length;
     uriToDependency[relativeUri] = dependency;
     List<String> unitUris = getUnitUris(relativeUri);
-    PrelinkedDependencyBuilder prelinkedDependency =
-        encodePrelinkedDependency(uri: relativeUri, parts: unitUris.sublist(1));
-    dependencies.add(prelinkedDependency);
+    LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder(
+        uri: relativeUri, parts: unitUris.sublist(1));
+    dependencies.add(linkedDependency);
 
     Map<String, _Meaning> aggregated = <String, _Meaning>{};
 
@@ -170,10 +190,19 @@
         continue;
       }
       for (UnlinkedPublicName name in importedNamespace.names) {
-        aggregated.putIfAbsent(
-            name.name,
-            () => new _Meaning(
-                unitNum, name.kind, dependency, name.numTypeParameters));
+        aggregated.putIfAbsent(name.name, () {
+          if (name.kind == ReferenceKind.classOrEnum) {
+            Map<String, _Meaning> namespace = <String, _Meaning>{};
+            name.constMembers.forEach((executable) {
+              namespace[executable.name] = new _Meaning(unitNum,
+                  executable.kind, dependency, executable.numTypeParameters);
+            });
+            return new _ClassMeaning(
+                unitNum, dependency, name.numTypeParameters, namespace);
+          }
+          return new _Meaning(
+              unitNum, name.kind, dependency, name.numTypeParameters);
+        });
       }
     }
 
@@ -185,10 +214,14 @@
    * Compute the export namespace for the library whose URI is reachable from
    * [definingUnit] via [relativeUri], by aggregating together public namespace
    * information from the library and the transitive closure of its exports.
+   *
+   * If [relativeUri] is `null` (meaning the export namespace of [definingUnit]
+   * should be computed), then names defined in [definingUnit] are ignored.
    */
   Map<String, _Meaning> computeExportNamespace(String relativeUri) {
-    Map<String, _Meaning> exportNamespace =
-        aggregatePublicNamespace(relativeUri);
+    Map<String, _Meaning> exportNamespace = relativeUri == null
+        ? <String, _Meaning>{}
+        : aggregatePublicNamespace(relativeUri);
     void chaseExports(
         NameFilter filter, String relativeUri, Set<String> seenUris) {
       if (seenUris.add(relativeUri)) {
@@ -197,17 +230,16 @@
         if (exportedNamespace != null) {
           for (UnlinkedExportPublic export in exportedNamespace.exports) {
             String exportUri = resolveUri(relativeUri, export.uri);
+            NameFilter newFilter = filter.merge(
+                new NameFilter.forUnlinkedCombinators(export.combinators));
             aggregatePublicNamespace(exportUri)
                 .forEach((String name, _Meaning meaning) {
-              if (filter.accepts(name) && !exportNamespace.containsKey(name)) {
+              if (newFilter.accepts(name) &&
+                  !exportNamespace.containsKey(name)) {
                 exportNamespace[name] = meaning;
               }
             });
-            chaseExports(
-                filter.merge(
-                    new NameFilter.forUnlinkedCombinators(export.combinators)),
-                exportUri,
-                seenUris);
+            chaseExports(newFilter, exportUri, seenUris);
           }
         }
         seenUris.remove(relativeUri);
@@ -224,32 +256,65 @@
    */
   void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
     for (UnlinkedClass cls in unit.classes) {
-      privateNamespace.putIfAbsent(
-          cls.name,
-          () => new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0,
-              cls.typeParameters.length));
+      privateNamespace.putIfAbsent(cls.name, () {
+        Map<String, _Meaning> namespace = <String, _Meaning>{};
+        cls.fields.forEach((field) {
+          if (field.isStatic && field.isConst) {
+            namespace[field.name] =
+                new _Meaning(unitNum, ReferenceKind.constField, 0, 0);
+          }
+        });
+        cls.executables.forEach((executable) {
+          ReferenceKind kind = null;
+          if (executable.kind == UnlinkedExecutableKind.constructor &&
+              executable.isConst) {
+            kind = ReferenceKind.constructor;
+          } else if (executable.kind ==
+                  UnlinkedExecutableKind.functionOrMethod &&
+              executable.isStatic) {
+            kind = ReferenceKind.staticMethod;
+          }
+          if (kind != null) {
+            namespace[executable.name] = new _Meaning(
+                unitNum, kind, 0, executable.typeParameters.length);
+          }
+        });
+        return new _ClassMeaning(
+            unitNum, 0, cls.typeParameters.length, namespace);
+      });
     }
     for (UnlinkedEnum enm in unit.enums) {
-      privateNamespace.putIfAbsent(
-          enm.name,
-          () =>
-              new _Meaning(unitNum, PrelinkedReferenceKind.classOrEnum, 0, 0));
+      privateNamespace.putIfAbsent(enm.name,
+          () => new _Meaning(unitNum, ReferenceKind.classOrEnum, 0, 0));
     }
     for (UnlinkedExecutable executable in unit.executables) {
       privateNamespace.putIfAbsent(
           executable.name,
-          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0,
+          () => new _Meaning(
+              unitNum,
+              executable.kind == UnlinkedExecutableKind.functionOrMethod
+                  ? ReferenceKind.topLevelFunction
+                  : ReferenceKind.topLevelPropertyAccessor,
+              0,
               executable.typeParameters.length));
     }
     for (UnlinkedTypedef typedef in unit.typedefs) {
       privateNamespace.putIfAbsent(
           typedef.name,
-          () => new _Meaning(unitNum, PrelinkedReferenceKind.typedef, 0,
+          () => new _Meaning(unitNum, ReferenceKind.typedef, 0,
               typedef.typeParameters.length));
     }
     for (UnlinkedVariable variable in unit.variables) {
-      privateNamespace.putIfAbsent(variable.name,
-          () => new _Meaning(unitNum, PrelinkedReferenceKind.other, 0, 0));
+      privateNamespace.putIfAbsent(
+          variable.name,
+          () => new _Meaning(
+              unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
+      if (!(variable.isConst || variable.isFinal)) {
+        privateNamespace.putIfAbsent(
+            variable.name + '=',
+            () => new _Meaning(
+                unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
+      }
     }
   }
 
@@ -328,47 +393,60 @@
   }
 
   /**
-   * Produce a [PrelinkedUnit] for the given [unit], by resolving every one of
+   * Produce a [LinkedUnit] for the given [unit], by resolving every one of
    * its references.
    */
-  PrelinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
+  LinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
     if (unit == null) {
-      return encodePrelinkedUnit();
+      return new LinkedUnitBuilder();
     }
     Map<int, Map<String, _Meaning>> prefixNamespaces =
         <int, Map<String, _Meaning>>{};
-    List<PrelinkedReferenceBuilder> references = <PrelinkedReferenceBuilder>[];
+    List<LinkedReferenceBuilder> references = <LinkedReferenceBuilder>[];
     for (int i = 0; i < unit.references.length; i++) {
       UnlinkedReference reference = unit.references[i];
       Map<String, _Meaning> namespace;
-      if (reference.prefixReference != 0) {
+      if (reference.prefixReference == 0) {
+        namespace = privateNamespace;
+      } else {
         // Prefix references must always point backward.
         assert(reference.prefixReference < i);
         namespace = prefixNamespaces[reference.prefixReference];
+        // If in `a.length` the `a` prefix is a top-level variable or a field,
+        // then it must be the `String.length` property reference.
+        if (namespace == null && reference.name == 'length') {
+          ReferenceKind prefixKind = references[reference.prefixReference].kind;
+          if (prefixKind == ReferenceKind.topLevelPropertyAccessor ||
+              prefixKind == ReferenceKind.constField) {
+            references
+                .add(new LinkedReferenceBuilder(kind: ReferenceKind.length));
+            continue;
+          }
+        }
         // Prefix references must always point to proper prefixes.
         assert(namespace != null);
-      } else {
-        namespace = privateNamespace;
       }
       _Meaning meaning = namespace[reference.name];
       if (meaning != null) {
         if (meaning is _PrefixMeaning) {
           prefixNamespaces[i] = meaning.namespace;
+        } else if (meaning is _ClassMeaning) {
+          prefixNamespaces[i] = meaning.namespace;
         }
-        references.add(meaning.encode());
+        references.add(meaning.encodeReference());
       } else {
-        references.add(
-            encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
+        references
+            .add(new LinkedReferenceBuilder(kind: ReferenceKind.unresolved));
       }
     }
-    return encodePrelinkedUnit(references: references);
+    return new LinkedUnitBuilder(references: references);
   }
 
   /**
-   * Form the [PrelinkedLibrary] for the [definingUnit] that was passed to the
+   * Form the [LinkedLibrary] for the [definingUnit] that was passed to the
    * constructor.
    */
-  PrelinkedLibraryBuilder prelink() {
+  LinkedLibraryBuilder prelink() {
     // Gather up the unlinked summaries for all the compilation units in the
     // library.
     List<UnlinkedUnit> units = getUnitUris(null).map(getPartCached).toList();
@@ -382,6 +460,16 @@
       }
     }
 
+    // Fill in exported names.  This must be done before filling in prefixes
+    // defined in import declarations, because prefixes shouldn't shadow
+    // exports.
+    List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
+    computeExportNamespace(null).forEach((String name, _Meaning meaning) {
+      if (!privateNamespace.containsKey(name)) {
+        exportNames.add(meaning.encodeExportName(name));
+      }
+    });
+
     // Fill in prefixes defined in import declarations.
     for (UnlinkedImport import in units[0].imports) {
       if (import.prefixReference != 0) {
@@ -396,12 +484,14 @@
         definingUnit.imports.map(handleImport).toList();
 
     // Link each compilation unit.
-    List<PrelinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
+    List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();
 
-    return encodePrelinkedLibrary(
+    return new LinkedLibraryBuilder(
         units: linkedUnits,
         dependencies: dependencies,
-        importDependencies: importDependencies);
+        importDependencies: importDependencies,
+        exportNames: exportNames,
+        numPrelinkedDependencies: dependencies.length);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index e8751b0..1f24248 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -14,7 +14,7 @@
 UnlinkedPublicNamespaceBuilder computePublicNamespace(CompilationUnit unit) {
   _PublicNamespaceVisitor visitor = new _PublicNamespaceVisitor();
   unit.accept(visitor);
-  return encodeUnlinkedPublicNamespace(
+  return new UnlinkedPublicNamespaceBuilder(
       names: visitor.names, exports: visitor.exports, parts: visitor.parts);
 }
 
@@ -26,12 +26,12 @@
 
   @override
   UnlinkedCombinatorBuilder visitHideCombinator(HideCombinator node) {
-    return encodeUnlinkedCombinator(hides: encodeNames(node.hiddenNames));
+    return new UnlinkedCombinatorBuilder(hides: encodeNames(node.hiddenNames));
   }
 
   @override
   UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
-    return encodeUnlinkedCombinator(shows: encodeNames(node.shownNames));
+    return new UnlinkedCombinatorBuilder(shows: encodeNames(node.shownNames));
   }
 }
 
@@ -43,36 +43,81 @@
 
   _PublicNamespaceVisitor();
 
-  void addNameIfPublic(
-      String name, PrelinkedReferenceKind kind, int numTypeParameters) {
+  UnlinkedPublicNameBuilder addNameIfPublic(
+      String name, ReferenceKind kind, int numTypeParameters) {
     if (isPublic(name)) {
-      names.add(encodeUnlinkedPublicName(
-          name: name, kind: kind, numTypeParameters: numTypeParameters));
+      UnlinkedPublicNameBuilder b = new UnlinkedPublicNameBuilder(
+          name: name, kind: kind, numTypeParameters: numTypeParameters);
+      names.add(b);
+      return b;
     }
+    return null;
   }
 
   bool isPublic(String name) => !name.startsWith('_');
 
   @override
   visitClassDeclaration(ClassDeclaration node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+    UnlinkedPublicNameBuilder cls = addNameIfPublic(
+        node.name.name,
+        ReferenceKind.classOrEnum,
         node.typeParameters?.typeParameters?.length ?? 0);
+    if (cls != null) {
+      for (ClassMember member in node.members) {
+        if (member is FieldDeclaration &&
+            member.isStatic &&
+            member.fields.isConst) {
+          for (VariableDeclaration field in member.fields.variables) {
+            String name = field.name.name;
+            if (isPublic(name)) {
+              cls.constMembers.add(new UnlinkedPublicNameBuilder(
+                  name: name,
+                  kind: ReferenceKind.constField,
+                  numTypeParameters: 0));
+            }
+          }
+        }
+        if (member is MethodDeclaration &&
+            member.isStatic &&
+            !member.isGetter &&
+            !member.isSetter &&
+            !member.isOperator) {
+          String name = member.name.name;
+          if (isPublic(name)) {
+            cls.constMembers.add(new UnlinkedPublicNameBuilder(
+                name: name,
+                kind: ReferenceKind.staticMethod,
+                numTypeParameters:
+                    member.typeParameters?.typeParameters?.length ?? 0));
+          }
+        }
+        if (member is ConstructorDeclaration && member.constKeyword != null) {
+          String name = member.name != null ? member.name.name : '';
+          if (isPublic(name)) {
+            cls.constMembers.add(new UnlinkedPublicNameBuilder(
+                name: name,
+                kind: ReferenceKind.constructor,
+                numTypeParameters: 0));
+          }
+        }
+      }
+    }
   }
 
   @override
   visitClassTypeAlias(ClassTypeAlias node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum,
+    addNameIfPublic(node.name.name, ReferenceKind.classOrEnum,
         node.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitEnumDeclaration(EnumDeclaration node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.classOrEnum, 0);
+    addNameIfPublic(node.name.name, ReferenceKind.classOrEnum, 0);
   }
 
   @override
   visitExportDirective(ExportDirective node) {
-    exports.add(encodeUnlinkedExportPublic(
+    exports.add(new UnlinkedExportPublicBuilder(
         uri: node.uri.stringValue,
         combinators: node.combinators
             .map((Combinator c) => c.accept(new _CombinatorEncoder()))
@@ -85,13 +130,17 @@
     if (node.isSetter) {
       name += '=';
     }
-    addNameIfPublic(name, PrelinkedReferenceKind.other,
+    addNameIfPublic(
+        name,
+        node.isGetter || node.isSetter
+            ? ReferenceKind.topLevelPropertyAccessor
+            : ReferenceKind.topLevelFunction,
         node.functionExpression.typeParameters?.typeParameters?.length ?? 0);
   }
 
   @override
   visitFunctionTypeAlias(FunctionTypeAlias node) {
-    addNameIfPublic(node.name.name, PrelinkedReferenceKind.typedef,
+    addNameIfPublic(node.name.name, ReferenceKind.typedef,
         node.typeParameters?.typeParameters?.length ?? 0);
   }
 
@@ -103,9 +152,9 @@
   @override
   visitVariableDeclaration(VariableDeclaration node) {
     String name = node.name.name;
-    addNameIfPublic(name, PrelinkedReferenceKind.other, 0);
+    addNameIfPublic(name, ReferenceKind.topLevelPropertyAccessor, 0);
     if (!node.isFinal && !node.isConst) {
-      addNameIfPublic('$name=', PrelinkedReferenceKind.other, 0);
+      addNameIfPublic('$name=', ReferenceKind.topLevelPropertyAccessor, 0);
     }
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 23b103c..d70d392 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -4,40 +4,30 @@
 
 library summary_resynthesizer;
 
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/element.dart';
+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/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/generated/utilities_dart.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);
-
-/**
  * Implementation of [ElementResynthesizer] used when resynthesizing an element
  * model from summaries.
  */
-class SummaryResynthesizer extends ElementResynthesizer {
+abstract class SummaryResynthesizer extends ElementResynthesizer {
   /**
-   * Callback used to obtain the prelinked summary for a given URI.
+   * The parent [SummaryResynthesizer] which is asked to resynthesize elements
+   * and get summaries before this resynthesizer attempts to do this.
+   * Can be `null`.
    */
-  final GetPrelinkedSummaryCallback getPrelinkedSummary;
-
-  /**
-   * Callback used to obtain the unlinked summary for a given URI.
-   */
-  final GetUnlinkedSummaryCallback getUnlinkedSummary;
+  final SummaryResynthesizer parent;
 
   /**
    * Source factory used to convert URIs to [Source] objects.
@@ -56,6 +46,12 @@
   final TypeProvider typeProvider;
 
   /**
+   * Indicates whether the summary should be resynthesized assuming strong mode
+   * semantics.
+   */
+  final bool strongMode;
+
+  /**
    * 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).
@@ -70,8 +66,8 @@
   final Map<String, LibraryElement> _resynthesizedLibraries =
       <String, LibraryElement>{};
 
-  SummaryResynthesizer(AnalysisContext context, this.typeProvider,
-      this.getPrelinkedSummary, this.getUnlinkedSummary, this.sourceFactory)
+  SummaryResynthesizer(this.parent, AnalysisContext context, this.typeProvider,
+      this.sourceFactory, this.strongMode)
       : super(context);
 
   /**
@@ -79,28 +75,68 @@
    */
   int get resynthesisCount => _resynthesizedLibraries.length;
 
+  /**
+   * Perform delayed finalization of the `dart:core` and `dart:async` libraries.
+   */
+  void finalizeCoreAsyncLibraries() {
+    (_resynthesizedLibraries['dart:core'] as LibraryElementImpl)
+        .createLoadLibraryFunction(typeProvider);
+    (_resynthesizedLibraries['dart:async'] as LibraryElementImpl)
+        .createLoadLibraryFunction(typeProvider);
+  }
+
   @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];
+    List<String> components = location.components;
+    String libraryUri = components[0];
+    // Ask the parent resynthesizer.
+    if (parent != null && parent._hasLibrarySummary(libraryUri)) {
+      return parent.getElement(location);
+    }
+    // Resynthesize locally.
+    if (components.length == 1) {
+      return getLibraryElement(libraryUri);
+    } else if (components.length == 3 || components.length == 4) {
       Map<String, Map<String, Element>> libraryMap =
-          _resynthesizedElements[uri];
+          _resynthesizedElements[libraryUri];
       if (libraryMap == null) {
-        getLibraryElement(uri);
-        libraryMap = _resynthesizedElements[uri];
+        getLibraryElement(libraryUri);
+        libraryMap = _resynthesizedElements[libraryUri];
         assert(libraryMap != null);
       }
-      Map<String, Element> compilationUnitElements =
-          libraryMap[location.components[1]];
+      Map<String, Element> compilationUnitElements = libraryMap[components[1]];
+      Element element;
       if (compilationUnitElements != null) {
-        Element element = compilationUnitElements[location.components[2]];
-        if (element != null) {
-          return element;
+        element = compilationUnitElements[components[2]];
+      }
+      if (element != null && components.length == 4) {
+        String name = components[3];
+        Element parentElement = element;
+        if (parentElement is ClassElement) {
+          if (name.endsWith('?')) {
+            element =
+                parentElement.getGetter(name.substring(0, name.length - 1));
+          } else if (name.endsWith('=')) {
+            element =
+                parentElement.getSetter(name.substring(0, name.length - 1));
+          } else if (name.isEmpty) {
+            element = parentElement.unnamedConstructor;
+          } else {
+            element = parentElement.getField(name) ??
+                parentElement.getMethod(name) ??
+                parentElement.getNamedConstructor(name);
+          }
+        } else {
+          // The only elements that are currently retrieved using 4-component
+          // locations are class members.
+          throw new StateError(
+              '4-element locations not supported for ${element.runtimeType}');
         }
       }
-      throw new Exception('Element not found in summary: $location');
+      if (element == null) {
+        throw new Exception('Element not found in summary: $location');
+      }
+      return element;
     } else {
       throw new UnimplementedError(location.toString());
     }
@@ -111,16 +147,19 @@
    * hasn't been resynthesized already.
    */
   LibraryElement getLibraryElement(String uri) {
+    if (parent != null && parent._hasLibrarySummary(uri)) {
+      return parent.getLibraryElement(uri);
+    }
     return _resynthesizedLibraries.putIfAbsent(uri, () {
-      PrelinkedLibrary serializedLibrary = getPrelinkedSummary(uri);
+      LinkedLibrary serializedLibrary = _getLinkedSummaryOrThrow(uri);
       List<UnlinkedUnit> serializedUnits = <UnlinkedUnit>[
-        getUnlinkedSummary(uri)
+        _getUnlinkedSummaryOrThrow(uri)
       ];
       Source librarySource = _getSource(uri);
       for (String part in serializedUnits[0].publicNamespace.parts) {
         Source partSource = sourceFactory.resolveUri(librarySource, part);
         String partAbsUri = partSource.uri.toString();
-        serializedUnits.add(getUnlinkedSummary(partAbsUri));
+        serializedUnits.add(_getUnlinkedSummaryOrThrow(partAbsUri));
       }
       _LibraryResynthesizer libraryResynthesizer = new _LibraryResynthesizer(
           this, serializedLibrary, serializedUnits, librarySource);
@@ -131,11 +170,73 @@
   }
 
   /**
+   * Return the [LinkedLibrary] for the given [uri] or `null` if it could not
+   * be found.  Caller has already checked that `parent.hasLibrarySummary(uri)`
+   * returns `false`.
+   */
+  LinkedLibrary getLinkedSummary(String uri);
+
+  /**
+   * Return the [UnlinkedUnit] for the given [uri] or `null` if it could not
+   * be found.  Caller has already checked that `parent.hasLibrarySummary(uri)`
+   * returns `false`.
+   */
+  UnlinkedUnit getUnlinkedSummary(String uri);
+
+  /**
+   * Return `true` if this resynthesizer can provide summaries of the libraries
+   * with the given [uri].  Caller has already checked that
+   * `parent.hasLibrarySummary(uri)` returns `false`.
+   */
+  bool hasLibrarySummary(String uri);
+
+  /**
+   * Return the [LinkedLibrary] for the given [uri] or throw [StateError] if it
+   * could not be found.
+   */
+  LinkedLibrary _getLinkedSummaryOrThrow(String uri) {
+    if (parent != null && parent._hasLibrarySummary(uri)) {
+      return parent._getLinkedSummaryOrThrow(uri);
+    }
+    LinkedLibrary summary = getLinkedSummary(uri);
+    if (summary != null) {
+      return summary;
+    }
+    throw new StateError('Unable to find linked summary: $uri');
+  }
+
+  /**
    * Get the [Source] object for the given [uri].
    */
   Source _getSource(String uri) {
     return _sources.putIfAbsent(uri, () => sourceFactory.forUri(uri));
   }
+
+  /**
+   * Return the [UnlinkedUnit] for the given [uri] or throw [StateError] if it
+   * could not be found.
+   */
+  UnlinkedUnit _getUnlinkedSummaryOrThrow(String uri) {
+    if (parent != null && parent._hasLibrarySummary(uri)) {
+      return parent._getUnlinkedSummaryOrThrow(uri);
+    }
+    UnlinkedUnit summary = getUnlinkedSummary(uri);
+    if (summary != null) {
+      return summary;
+    }
+    throw new StateError('Unable to find unlinked summary: $uri');
+  }
+
+  /**
+   * Return `true` if this resynthesizer can provide summaries of the libraries
+   * with the given [uri].
+   */
+  bool _hasLibrarySummary(String uri) {
+    if (parent != null && parent._hasLibrarySummary(uri)) {
+      return true;
+    }
+    return hasLibrarySummary(uri);
+  }
 }
 
 /**
@@ -149,9 +250,9 @@
   final SummaryResynthesizer summaryResynthesizer;
 
   /**
-   * Prelinked summary of the library to be resynthesized.
+   * Linked summary of the library to be resynthesized.
    */
-  final PrelinkedLibrary prelinkedLibrary;
+  final LinkedLibrary linkedLibrary;
 
   /**
    * Unlinked compilation units constituting the library to be resynthesized.
@@ -182,9 +283,9 @@
   ElementHolder unitHolder;
 
   /**
-   * The [PrelinkedUnit] from which elements are currently being resynthesized.
+   * The [LinkedUnit] from which elements are currently being resynthesized.
    */
-  PrelinkedUnit prelinkedUnit;
+  LinkedUnit linkedUnit;
 
   /**
    * The [UnlinkedUnit] from which elements are currently being resynthesized.
@@ -192,6 +293,12 @@
   UnlinkedUnit unlinkedUnit;
 
   /**
+   * Map from slot id to the corresponding [EntityRef] object for linked types
+   * (i.e. propagated and inferred types).
+   */
+  Map<int, EntityRef> linkedTypeMap;
+
+  /**
    * 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.
@@ -210,7 +317,14 @@
    */
   List<TypeParameterElement> currentTypeParameters = <TypeParameterElement>[];
 
-  _LibraryResynthesizer(this.summaryResynthesizer, this.prelinkedLibrary,
+  /**
+   * If a class is currently being resynthesized, map from field name to the
+   * corresponding field element.  This is used when resynthesizing
+   * initializing formal parameters.
+   */
+  Map<String, FieldElementImpl> fields;
+
+  _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
       this.unlinkedUnits, this.librarySource) {
     isCoreLibrary = librarySource.uri.toString() == 'dart:core';
   }
@@ -235,6 +349,7 @@
       }
       ClassElementImpl classElement = new ClassElementImpl(
           serializedClass.name, serializedClass.nameOffset);
+      classElement.abstract = serializedClass.isAbstract;
       classElement.mixinApplication = serializedClass.isMixinApplication;
       InterfaceTypeImpl correspondingType = new InterfaceTypeImpl(classElement);
       if (serializedClass.supertype != null) {
@@ -251,6 +366,10 @@
       classElement.mixins = serializedClass.mixins.map(buildType).toList();
       classElement.typeParameters = currentTypeParameters;
       ElementHolder memberHolder = new ElementHolder();
+      fields = <String, FieldElementImpl>{};
+      for (UnlinkedVariable serializedVariable in serializedClass.fields) {
+        buildVariable(serializedVariable, memberHolder);
+      }
       bool constructorFound = false;
       for (UnlinkedExecutable serializedExecutable
           in serializedClass.executables) {
@@ -267,9 +386,6 @@
             break;
         }
       }
-      for (UnlinkedVariable serializedVariable in serializedClass.fields) {
-        buildVariable(serializedVariable, memberHolder);
-      }
       if (!serializedClass.isMixinApplication) {
         if (!constructorFound) {
           // Synthesize implicit constructors.
@@ -292,6 +408,7 @@
       unitHolder.addType(classElement);
     } finally {
       currentTypeParameters = <TypeParameterElement>[];
+      fields = null;
     }
   }
 
@@ -350,7 +467,6 @@
    */
   void buildEnum(UnlinkedEnum serializedEnum) {
     assert(!isCoreLibrary);
-    // TODO(paulberry): add offset support (for this element type and others)
     ClassElementImpl classElement =
         new ClassElementImpl(serializedEnum.name, serializedEnum.nameOffset);
     classElement.enum2 = true;
@@ -413,6 +529,7 @@
         } else {
           MethodElementImpl executableElement =
               new MethodElementImpl(name, serializedExecutable.nameOffset);
+          executableElement.abstract = serializedExecutable.isAbstract;
           buildExecutableCommonParts(executableElement, serializedExecutable);
           executableElement.static = serializedExecutable.isStatic;
           holder.addMethod(executableElement);
@@ -427,6 +544,7 @@
           executableElement.static = true;
         } else {
           executableElement.static = serializedExecutable.isStatic;
+          executableElement.abstract = serializedExecutable.isAbstract;
         }
         buildExecutableCommonParts(executableElement, serializedExecutable);
         DartType type;
@@ -455,8 +573,6 @@
         } 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
@@ -481,18 +597,21 @@
     }
     executableElement.parameters =
         serializedExecutable.parameters.map(buildParameter).toList();
-    if (serializedExecutable.returnType != null) {
-      executableElement.returnType = buildType(serializedExecutable.returnType);
-    } else if (serializedExecutable.kind ==
-        UnlinkedExecutableKind.constructor) {
-      // Return type was set by the caller.
+    if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) {
+      // Caller handles setting the return type.
+      assert(serializedExecutable.returnType == null);
     } else {
-      executableElement.returnType = VoidTypeImpl.instance;
+      bool isSetter =
+          serializedExecutable.kind == UnlinkedExecutableKind.setter;
+      executableElement.returnType =
+          buildLinkedType(serializedExecutable.inferredReturnTypeSlot) ??
+              buildType(serializedExecutable.returnType,
+                  defaultVoid: isSetter && summaryResynthesizer.strongMode);
+      executableElement.hasImplicitReturnType =
+          serializedExecutable.returnType == null;
     }
     executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
         executableElement, null, oldTypeArguments, false);
-    executableElement.hasImplicitReturnType =
-        serializedExecutable.hasImplicitReturnType;
     executableElement.external = serializedExecutable.isExternal;
     currentTypeParameters.removeRange(
         oldTypeParametersLength, currentTypeParameters.length);
@@ -523,6 +642,62 @@
   }
 
   /**
+   * Build an [ElementHandle] referring to the entity referred to by the given
+   * [exportName].
+   */
+  ElementHandle buildExportName(LinkedExportName exportName) {
+    String name = exportName.name;
+    if (exportName.kind == ReferenceKind.topLevelPropertyAccessor &&
+        !name.endsWith('=')) {
+      name += '?';
+    }
+    ElementLocationImpl location = getReferencedLocation(
+        linkedLibrary.dependencies[exportName.dependency],
+        exportName.unit,
+        name);
+    switch (exportName.kind) {
+      case ReferenceKind.classOrEnum:
+        return new ClassElementHandle(summaryResynthesizer, location);
+      case ReferenceKind.typedef:
+        return new FunctionTypeAliasElementHandle(
+            summaryResynthesizer, location);
+      case ReferenceKind.topLevelFunction:
+        return new FunctionElementHandle(summaryResynthesizer, location);
+      case ReferenceKind.topLevelPropertyAccessor:
+        return new PropertyAccessorElementHandle(
+            summaryResynthesizer, location);
+      case ReferenceKind.constructor:
+      case ReferenceKind.constField:
+      case ReferenceKind.staticMethod:
+      case ReferenceKind.length:
+      case ReferenceKind.prefix:
+      case ReferenceKind.unresolved:
+        // Should never happen.  Exported names never refer to import prefixes,
+        // and they always refer to defined top-level entities.
+        throw new StateError('Unexpected export name kind: ${exportName.kind}');
+    }
+  }
+
+  /**
+   * Build the export namespace for the library by aggregating together its
+   * [publicNamespace] and [exportNames].
+   */
+  Namespace buildExportNamespace(
+      Namespace publicNamespace, List<LinkedExportName> exportNames) {
+    HashMap<String, Element> definedNames = new HashMap<String, Element>();
+    // Start by populating all the public names from [publicNamespace].
+    publicNamespace.definedNames.forEach((String name, Element element) {
+      definedNames[name] = element;
+    });
+    // Add all the names from [exportNames].
+    for (LinkedExportName exportName in exportNames) {
+      definedNames.putIfAbsent(
+          exportName.name, () => buildExportName(exportName));
+    }
+    return new Namespace(definedNames);
+  }
+
+  /**
    * Resynthesize a [FieldElement].
    */
   FieldElement buildField(UnlinkedVariable serializedField) {
@@ -618,13 +793,10 @@
    */
   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)
+        .resolveUri(librarySource, linkedLibrary.dependencies[dependency].uri)
         .uri
         .toString();
     importElement.importedLibrary = new LibraryElementHandle(
@@ -636,7 +808,9 @@
       importElement.uri = serializedImport.uri;
       importElement.uriOffset = serializedImport.uriOffset;
       importElement.uriEnd = serializedImport.uriEnd;
+      importElement.deferred = serializedImport.isDeferred;
     }
+    importElement.prefixOffset = serializedImport.prefixOffset;
     if (serializedImport.prefixReference != 0) {
       UnlinkedReference serializedPrefix =
           unlinkedUnits[0].references[serializedImport.prefixReference];
@@ -653,36 +827,35 @@
    */
   LibraryElement buildLibrary() {
     bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
-    LibraryElementImpl libraryElement = new LibraryElementImpl(
+    LibraryElementImpl library = new LibraryElementImpl(
         summaryResynthesizer.context,
         unlinkedUnits[0].libraryName,
         hasName ? unlinkedUnits[0].libraryNameOffset : -1,
         unlinkedUnits[0].libraryNameLength);
-    buildDocumentation(
-        libraryElement, unlinkedUnits[0].libraryDocumentationComment);
+    buildDocumentation(library, unlinkedUnits[0].libraryDocumentationComment);
     CompilationUnitElementImpl definingCompilationUnit =
         new CompilationUnitElementImpl(librarySource.shortName);
-    libraryElement.definingCompilationUnit = definingCompilationUnit;
+    library.definingCompilationUnit = definingCompilationUnit;
     definingCompilationUnit.source = librarySource;
     definingCompilationUnit.librarySource = librarySource;
     List<CompilationUnitElement> parts = <CompilationUnitElement>[];
     UnlinkedUnit unlinkedDefiningUnit = unlinkedUnits[0];
     assert(unlinkedDefiningUnit.publicNamespace.parts.length + 1 ==
-        prelinkedLibrary.units.length);
-    for (int i = 1; i < prelinkedLibrary.units.length; i++) {
+        linkedLibrary.units.length);
+    for (int i = 1; i < linkedLibrary.units.length; i++) {
       CompilationUnitElementImpl part = buildPart(
           unlinkedDefiningUnit.publicNamespace.parts[i - 1],
           unlinkedDefiningUnit.parts[i - 1],
           unlinkedUnits[i]);
       parts.add(part);
     }
-    libraryElement.parts = parts;
+    library.parts = parts;
     List<ImportElement> imports = <ImportElement>[];
     for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) {
       imports.add(buildImport(unlinkedDefiningUnit.imports[i],
-          prelinkedLibrary.importDependencies[i]));
+          linkedLibrary.importDependencies[i]));
     }
-    libraryElement.imports = imports;
+    library.imports = imports;
     List<ExportElement> exports = <ExportElement>[];
     assert(unlinkedDefiningUnit.exports.length ==
         unlinkedDefiningUnit.publicNamespace.exports.length);
@@ -690,40 +863,75 @@
       exports.add(buildExport(unlinkedDefiningUnit.publicNamespace.exports[i],
           unlinkedDefiningUnit.exports[i]));
     }
-    libraryElement.exports = exports;
+    library.exports = exports;
     populateUnit(definingCompilationUnit, 0);
     for (int i = 0; i < parts.length; i++) {
       populateUnit(parts[i], i + 1);
     }
+    BuildLibraryElementUtils.patchTopLevelAccessors(library);
+    // Update delayed Object class references.
     if (isCoreLibrary) {
-      ClassElement objectElement = libraryElement.getType('Object');
+      ClassElement objectElement = library.getType('Object');
       assert(objectElement != null);
       for (ClassElementImpl classElement in delayedObjectSubclasses) {
         classElement.supertype = objectElement.type;
       }
     }
     // Compute namespaces.
-    libraryElement.publicNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(libraryElement);
-    // TODO(paulberry): compute the export namespace from prelinked data, so
-    // that exported libraries won't be unnecessarily resynthesized.
-    libraryElement.exportNamespace =
-        new NamespaceBuilder().createExportNamespaceForLibrary(libraryElement);
-    // Find the entry point.
-    libraryElement.entryPoint =
-        libraryElement.exportNamespace.definedNames.values.firstWhere(
-            (element) => element is FunctionElement && element.isEntryPoint,
-            orElse: () => null);
+    library.publicNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(library);
+    library.exportNamespace = buildExportNamespace(
+        library.publicNamespace, linkedLibrary.exportNames);
+    // Find the entry point.  Note: we can't use element.isEntryPoint because
+    // that will trigger resynthesis of exported libraries.
+    Element entryPoint =
+        library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
+    if (entryPoint is FunctionElement) {
+      library.entryPoint = entryPoint;
+    }
+    // Create the synthetic element for `loadLibrary`.
+    // Until the client received dart:core and dart:async, we cannot do this,
+    // because the TypeProvider is not fully initialized. So, it is up to the
+    // Dart SDK client to initialize TypeProvider and finish the dart:core and
+    // dart:async libraries creation.
+    if (library.name != 'dart.core' && library.name != 'dart.async') {
+      library.createLoadLibraryFunction(summaryResynthesizer.typeProvider);
+    }
     // Done.
-    return libraryElement;
+    return library;
+  }
+
+  /**
+   * Build the appropriate [DartType] object corresponding to a slot id in the
+   * [LinkedUnit.types] table.
+   */
+  DartType buildLinkedType(int slot) {
+    if (slot == 0) {
+      // A slot id of 0 means there is no [DartType] object to build.
+      return null;
+    }
+    EntityRef type = linkedTypeMap[slot];
+    if (type == null) {
+      // A missing entry in [LinkedUnit.types] means there is no [DartType]
+      // stored in this slot.
+      return null;
+    }
+    return buildType(type);
   }
 
   /**
    * Resynthesize a [ParameterElement].
    */
   ParameterElement buildParameter(UnlinkedParam serializedParameter) {
-    ParameterElementImpl parameterElement = new ParameterElementImpl(
-        serializedParameter.name, serializedParameter.nameOffset);
+    ParameterElementImpl parameterElement;
+    if (serializedParameter.isInitializingFormal) {
+      parameterElement = new FieldFormalParameterElementImpl.forNameAndOffset(
+          serializedParameter.name, serializedParameter.nameOffset)
+        ..field = fields[serializedParameter.name];
+    } else {
+      parameterElement = new ParameterElementImpl(
+          serializedParameter.name, serializedParameter.nameOffset);
+    }
     if (serializedParameter.isFunctionTyped) {
       FunctionElementImpl parameterTypeElement =
           new FunctionElementImpl('', -1);
@@ -732,16 +940,21 @@
           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;
-      }
+      parameterTypeElement.returnType = buildType(serializedParameter.type);
       parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
           parameterTypeElement, null, currentTypeArguments, false);
     } else {
-      parameterElement.type = buildType(serializedParameter.type);
-      parameterElement.hasImplicitType = serializedParameter.hasImplicitType;
+      if (serializedParameter.isInitializingFormal &&
+          serializedParameter.type == null) {
+        // The type is inherited from the matching field.
+        parameterElement.type = fields[serializedParameter.name]?.type ??
+            summaryResynthesizer.typeProvider.dynamicType;
+      } else {
+        parameterElement.type =
+            buildLinkedType(serializedParameter.inferredTypeSlot) ??
+                buildType(serializedParameter.type);
+      }
+      parameterElement.hasImplicitType = serializedParameter.type == null;
     }
     switch (serializedParameter.kind) {
       case UnlinkedParamKind.named:
@@ -776,55 +989,47 @@
   }
 
   /**
-   * Build a [DartType] object based on an [UnlinkedTypeRef].  This [DartType]
+   * Build a [DartType] object based on a [EntityRef].  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) {
+  DartType buildType(EntityRef type, {bool defaultVoid: false}) {
+    if (type == null) {
+      if (defaultVoid) {
+        return VoidTypeImpl.instance;
+      } else {
+        return summaryResynthesizer.typeProvider.dynamicType;
+      }
+    }
     if (type.paramReference != 0) {
       // TODO(paulberry): make this work for generic methods.
       return currentTypeParameters[
-              currentTypeParameters.length - type.paramReference]
-          .type;
+          currentTypeParameters.length - type.paramReference].type;
     } else {
-      // 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.publicNamespace.parts[
-              referenceResolution.unit - 1];
-          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;
+      LinkedReference referenceResolution =
+          linkedUnit.references[type.reference];
+      String name;
+      if (type.reference < unlinkedUnit.references.length) {
+        name = unlinkedUnit.references[type.reference].name;
       } else {
-        referencedLibraryUri = librarySource.uri.toString();
+        name = referenceResolution.name;
+      }
+      ElementLocationImpl location;
+      if (referenceResolution.dependency != 0) {
+        location = getReferencedLocation(
+            linkedLibrary.dependencies[referenceResolution.dependency],
+            referenceResolution.unit,
+            name);
+      } else if (referenceResolution.kind == ReferenceKind.unresolved) {
+        return summaryResynthesizer.typeProvider.undefinedType;
+      } else if (name == 'dynamic') {
+        return summaryResynthesizer.typeProvider.dynamicType;
+      } else if (name == 'void') {
+        return VoidTypeImpl.instance;
+      } else {
+        String referencedLibraryUri = librarySource.uri.toString();
+        String partUri;
         if (referenceResolution.unit != 0) {
           String uri = unlinkedUnits[0].publicNamespace.parts[
               referenceResolution.unit - 1];
@@ -834,9 +1039,9 @@
         } else {
           partUri = referencedLibraryUri;
         }
+        location = new ElementLocationImpl.con3(
+            <String>[referencedLibraryUri, partUri, name]);
       }
-      ElementLocationImpl location = new ElementLocationImpl.con3(
-          <String>[referencedLibraryUri, partUri, reference.name]);
       List<DartType> typeArguments = const <DartType>[];
       if (referenceResolution.numTypeParameters != 0) {
         typeArguments = <DartType>[];
@@ -849,16 +1054,16 @@
         }
       }
       switch (referenceResolution.kind) {
-        case PrelinkedReferenceKind.classOrEnum:
+        case ReferenceKind.classOrEnum:
           return new InterfaceTypeImpl.elementWithNameAndArgs(
               new ClassElementHandle(summaryResynthesizer, location),
-              reference.name,
+              name,
               typeArguments);
-        case PrelinkedReferenceKind.typedef:
+        case ReferenceKind.typedef:
           return new FunctionTypeImpl.elementWithNameAndArgs(
               new FunctionTypeAliasElementHandle(
                   summaryResynthesizer, location),
-              reference.name,
+              name,
               typeArguments,
               typeArguments.isNotEmpty);
         default:
@@ -886,12 +1091,8 @@
               serializedTypedef.name, serializedTypedef.nameOffset);
       functionTypeAliasElement.parameters =
           serializedTypedef.parameters.map(buildParameter).toList();
-      if (serializedTypedef.returnType != null) {
-        functionTypeAliasElement.returnType =
-            buildType(serializedTypedef.returnType);
-      } else {
-        functionTypeAliasElement.returnType = VoidTypeImpl.instance;
-      }
+      functionTypeAliasElement.returnType =
+          buildType(serializedTypedef.returnType);
       functionTypeAliasElement.type =
           new FunctionTypeImpl.forTypedef(functionTypeAliasElement);
       functionTypeAliasElement.typeParameters = currentTypeParameters;
@@ -938,6 +1139,7 @@
       element.static = serializedVariable.isStatic;
       holder.addField(element);
       buildImplicitAccessors(element, holder);
+      fields[element.name] = element;
     }
   }
 
@@ -946,9 +1148,13 @@
    */
   void buildVariableCommonParts(PropertyInducingElementImpl element,
       UnlinkedVariable serializedVariable) {
-    element.type = buildType(serializedVariable.type);
+    element.type = buildLinkedType(serializedVariable.inferredTypeSlot) ??
+        buildType(serializedVariable.type);
     element.const3 = serializedVariable.isConst;
-    element.hasImplicitType = serializedVariable.hasImplicitType;
+    element.final2 = serializedVariable.isFinal;
+    element.hasImplicitType = serializedVariable.type == null;
+    element.propagatedType =
+        buildLinkedType(serializedVariable.propagatedTypeSlot);
     buildDocumentation(element, serializedVariable.documentationComment);
   }
 
@@ -963,12 +1169,44 @@
   }
 
   /**
+   * Build an [ElementLocationImpl] for the entity in the given [unit] of the
+   * given [dependency], having the given [name].
+   */
+  ElementLocationImpl getReferencedLocation(
+      LinkedDependency dependency, int unit, String name) {
+    Source referencedLibrarySource = summaryResynthesizer.sourceFactory
+        .resolveUri(librarySource, dependency.uri);
+    String referencedLibraryUri = referencedLibrarySource.uri.toString();
+    // TODO(paulberry): consider changing Location format so that this is
+    // not necessary (2nd string in location should just be the unit
+    // number).
+    String partUri;
+    if (unit != 0) {
+      UnlinkedUnit referencedLibraryDefiningUnit =
+          summaryResynthesizer._getUnlinkedSummaryOrThrow(referencedLibraryUri);
+      String uri =
+          referencedLibraryDefiningUnit.publicNamespace.parts[unit - 1];
+      Source partSource = summaryResynthesizer.sourceFactory
+          .resolveUri(referencedLibrarySource, uri);
+      partUri = partSource.uri.toString();
+    } else {
+      partUri = referencedLibraryUri;
+    }
+    return new ElementLocationImpl.con3(
+        <String>[referencedLibraryUri, partUri, name]);
+  }
+
+  /**
    * Populate a [CompilationUnitElement] by deserializing all the elements
    * contained in it.
    */
   void populateUnit(CompilationUnitElementImpl unit, int unitNum) {
-    prelinkedUnit = prelinkedLibrary.units[unitNum];
+    linkedUnit = linkedLibrary.units[unitNum];
     unlinkedUnit = unlinkedUnits[unitNum];
+    linkedTypeMap = <int, EntityRef>{};
+    for (EntityRef t in linkedUnit.types) {
+      linkedTypeMap[t.slot] = t;
+    }
     unitHolder = new ElementHolder();
     unlinkedUnit.classes.forEach(buildClass);
     unlinkedUnit.enums.forEach(buildEnum);
@@ -998,9 +1236,16 @@
     for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
       elementMap[typeAlias.name] = typeAlias;
     }
+    for (FunctionElement function in unit.functions) {
+      elementMap[function.name] = function;
+    }
+    for (PropertyAccessorElementImpl accessor in unit.accessors) {
+      elementMap[accessor.identifier] = accessor;
+    }
     resummarizedElements[absoluteUri] = elementMap;
     unitHolder = null;
-    prelinkedUnit = null;
+    linkedUnit = null;
     unlinkedUnit = null;
+    linkedTypeMap = null;
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
new file mode 100644
index 0000000..c43a9b9
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -0,0 +1,884 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library serialization.summarize_ast;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/public_namespace_computer.dart';
+import 'package:analyzer/src/summary/summarize_const_expr.dart';
+
+/**
+ * Serialize all the declarations in [compilationUnit] to an unlinked summary.
+ */
+UnlinkedUnitBuilder serializeAstUnlinked(CompilationUnit compilationUnit) {
+  return new _SummarizeAstVisitor().serializeCompilationUnit(compilationUnit);
+}
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single constant [Expression].
+ */
+class _ConstExprSerializer extends AbstractConstExprSerializer {
+  final _SummarizeAstVisitor visitor;
+
+  _ConstExprSerializer(this.visitor);
+
+  @override
+  EntityRefBuilder serializeConstructorName(ConstructorName constructor) {
+    EntityRefBuilder typeBuilder = serializeType(constructor.type);
+    if (constructor.name == null) {
+      return typeBuilder;
+    } else {
+      String name = constructor.name.name;
+      int nameRef = visitor.serializeReference(typeBuilder.reference, name);
+      return new EntityRefBuilder(reference: nameRef);
+    }
+  }
+
+  EntityRefBuilder serializeIdentifier(Identifier identifier) {
+    EntityRefBuilder b = new EntityRefBuilder();
+    if (identifier is SimpleIdentifier) {
+      b.reference = visitor.serializeReference(null, identifier.name);
+    } else if (identifier is PrefixedIdentifier) {
+      int prefix = visitor.serializeReference(null, identifier.prefix.name);
+      b.reference =
+          visitor.serializeReference(prefix, identifier.identifier.name);
+    } else {
+      throw new StateError(
+          'Unexpected identifier type: ${identifier.runtimeType}');
+    }
+    return b;
+  }
+
+  @override
+  EntityRefBuilder serializePropertyAccess(PropertyAccess access) {
+    Expression target = access.target;
+    if (target is Identifier) {
+      EntityRefBuilder targetRef = serializeIdentifier(target);
+      return new EntityRefBuilder(
+          reference: visitor.serializeReference(
+              targetRef.reference, access.propertyName.name));
+    } else {
+      // TODO(scheglov) should we handle other targets in malformed constants?
+      throw new StateError('Unexpected target type: ${target.runtimeType}');
+    }
+  }
+
+  @override
+  EntityRefBuilder serializeType(TypeName node) {
+    return visitor.serializeTypeName(node);
+  }
+}
+
+/**
+ * An [_OtherScopedEntity] is a [_ScopedEntity] that does not refer to a type
+ * parameter.  Since we don't need to track any special information about these
+ * types of scoped entities, it is a singleton class.
+ */
+class _OtherScopedEntity extends _ScopedEntity {
+  static final _OtherScopedEntity _instance = new _OtherScopedEntity._();
+
+  factory _OtherScopedEntity() => _instance;
+
+  _OtherScopedEntity._();
+}
+
+/**
+ * A [_Scope] represents a set of name/value pairs defined locally within a
+ * limited span of a compilation unit.  (Note that the spec also uses the term
+ * "scope" to refer to the set of names defined at top level within a
+ * compilation unit, but we do not use [_Scope] for that purpose).
+ */
+class _Scope {
+  /**
+   * Names defined in this scope, and their meanings.
+   */
+  Map<String, _ScopedEntity> _definedNames = <String, _ScopedEntity>{};
+
+  /**
+   * Look up the meaning associated with the given [name], and return it.  If
+   * [name] is not defined in this scope, return `null`.
+   */
+  _ScopedEntity operator [](String name) => _definedNames[name];
+
+  /**
+   * Let the given [name] refer to [entity] within this scope.
+   */
+  void operator []=(String name, _ScopedEntity entity) {
+    _definedNames[name] = entity;
+  }
+}
+
+/**
+ * Base class for entities that can live inside a scope.
+ */
+abstract class _ScopedEntity {}
+
+/**
+ * A [_ScopedTypeParameter] is a [_ScopedEntity] that refers to a type
+ * parameter of a class, typedef, or executable.
+ */
+class _ScopedTypeParameter extends _ScopedEntity {
+  /**
+   * Index of the type parameter within this scope.  Since summaries use De
+   * Bruijn indices to refer to type parameters, which count upwards from the
+   * innermost bound name, the last type parameter in the scope has an index of
+   * 1, and each preceding type parameter has the next higher index.
+   */
+  final int index;
+
+  _ScopedTypeParameter(this.index);
+}
+
+/**
+ * Visitor used to create a summary from an AST.
+ */
+class _SummarizeAstVisitor extends SimpleAstVisitor {
+  /**
+   * List of objects which should be written to [UnlinkedUnit.classes].
+   */
+  final List<UnlinkedClassBuilder> classes = <UnlinkedClassBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.enums].
+   */
+  final List<UnlinkedEnumBuilder> enums = <UnlinkedEnumBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.executables]
+   * or [UnlinkedClass.executables].
+   */
+  List<UnlinkedExecutableBuilder> executables = <UnlinkedExecutableBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.exports].
+   */
+  final List<UnlinkedExportNonPublicBuilder> exports =
+      <UnlinkedExportNonPublicBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.parts].
+   */
+  final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.typedefs].
+   */
+  final List<UnlinkedTypedefBuilder> typedefs = <UnlinkedTypedefBuilder>[];
+
+  /**
+   * List of objects which should be written to [UnlinkedUnit.variables] or
+   * [UnlinkedClass.fields].
+   */
+  List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
+
+  /**
+   * The unlinked portion of the "imports table".  This is the list of objects
+   * which should be written to [UnlinkedUnit.imports].
+   */
+  final List<UnlinkedImportBuilder> unlinkedImports = <UnlinkedImportBuilder>[];
+
+  /**
+   * The unlinked portion of the "references table".  This is the list of
+   * objects which should be written to [UnlinkedUnit.references].
+   */
+  final List<UnlinkedReferenceBuilder> unlinkedReferences =
+      <UnlinkedReferenceBuilder>[new UnlinkedReferenceBuilder()];
+
+  /**
+   * Map associating names used as prefixes in this compilation unit with their
+   * associated indices into [UnlinkedUnit.references].
+   */
+  final Map<String, int> prefixIndices = <String, int>{};
+
+  /**
+   * List of [_Scope]s currently in effect.  This is used to resolve type names
+   * to type parameters within classes, typedefs, and executables.
+   */
+  final List<_Scope> scopes = <_Scope>[];
+
+  /**
+   * True if 'dart:core' has been explicitly imported.
+   */
+  bool hasCoreBeenImported = false;
+
+  /**
+   * Names referenced by this compilation unit.  Structured as a map from
+   * prefix index to (map from name to reference table index), where "prefix
+   * index" means the index into [UnlinkedUnit.references] of the prefix (or
+   * `null` if there is no prefix), and "reference table index" means the index
+   * into [UnlinkedUnit.references] for the name itself.
+   */
+  final Map<int, Map<String, int>> nameToReference = <int, Map<String, int>>{};
+
+  /**
+   * If the library has a library directive, the library name derived from it.
+   * Otherwise `null`.
+   */
+  String libraryName;
+
+  /**
+   * If the library has a library directive, the offset of the library name.
+   * Otherwise `null`.
+   */
+  int libraryNameOffset;
+
+  /**
+   * If the library has a library directive, the length of the library name, as
+   * it appears in the source file.  Otherwise `null`.
+   */
+  int libraryNameLength;
+
+  /**
+   * If the library has a library directive, the documentation comment for it
+   * (if any).  Otherwise `null`.
+   */
+  UnlinkedDocumentationCommentBuilder libraryDocumentationComment;
+
+  /**
+   * The number of slot ids which have been assigned to this compilation unit.
+   */
+  int numSlots = 0;
+
+  /**
+   * Create a slot id for storing a propagated or inferred type.
+   */
+  int assignTypeSlot() => ++numSlots;
+
+  /**
+   * Build a [_Scope] object containing the names defined within the body of a
+   * class declaration.
+   */
+  _Scope buildClassMemberScope(NodeList<ClassMember> members) {
+    _Scope scope = new _Scope();
+    for (ClassMember member in members) {
+      // TODO(paulbery): consider replacing these if-tests with dynamic method
+      // dispatch.
+      if (member is MethodDeclaration) {
+        if (member.isSetter || member.isOperator) {
+          // We don't have to handle setters or operators because the only
+          // thing we look up is type names.
+        } else {
+          scope[member.name.name] = new _OtherScopedEntity();
+        }
+      } else if (member is FieldDeclaration) {
+        for (VariableDeclaration field in member.fields.variables) {
+          // A field declaration introduces two names, one with a trailing `=`.
+          // We don't have to worry about the one with a trailing `=` because
+          // the only thing we look up is type names.
+          scope[field.name.name] = new _OtherScopedEntity();
+        }
+      }
+    }
+    return scope;
+  }
+
+  /**
+   * Serialize a [ClassDeclaration] or [ClassTypeAlias] into an [UnlinkedClass]
+   * and store the result in [classes].
+   */
+  void serializeClass(
+      Token abstractKeyword,
+      String name,
+      int nameOffset,
+      TypeParameterList typeParameters,
+      TypeName superclass,
+      WithClause withClause,
+      ImplementsClause implementsClause,
+      NodeList<ClassMember> members,
+      bool isMixinApplication,
+      Comment documentationComment) {
+    int oldScopesLength = scopes.length;
+    List<UnlinkedExecutableBuilder> oldExecutables = executables;
+    executables = <UnlinkedExecutableBuilder>[];
+    List<UnlinkedVariableBuilder> oldVariables = variables;
+    variables = <UnlinkedVariableBuilder>[];
+    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
+    scopes.add(typeParameterScope);
+    UnlinkedClassBuilder b = new UnlinkedClassBuilder();
+    b.name = name;
+    b.nameOffset = nameOffset;
+    b.isMixinApplication = isMixinApplication;
+    b.typeParameters =
+        serializeTypeParameters(typeParameters, typeParameterScope);
+    if (superclass != null) {
+      b.supertype = serializeTypeName(superclass);
+    }
+    if (withClause != null) {
+      b.mixins = withClause.mixinTypes.map(serializeTypeName).toList();
+    }
+    if (implementsClause != null) {
+      b.interfaces =
+          implementsClause.interfaces.map(serializeTypeName).toList();
+    }
+    if (members != null) {
+      scopes.add(buildClassMemberScope(members));
+      for (ClassMember member in members) {
+        member.accept(this);
+      }
+      scopes.removeLast();
+    }
+    b.executables = executables;
+    b.fields = variables;
+    b.isAbstract = abstractKeyword != null;
+    b.documentationComment = serializeDocumentation(documentationComment);
+    classes.add(b);
+    scopes.removeLast();
+    assert(scopes.length == oldScopesLength);
+    executables = oldExecutables;
+    variables = oldVariables;
+  }
+
+  /**
+   * Serialize a [Combinator] into an [UnlinkedCombinator].
+   */
+  UnlinkedCombinatorBuilder serializeCombinator(Combinator combinator) {
+    UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
+    if (combinator is ShowCombinator) {
+      b.shows =
+          combinator.shownNames.map((SimpleIdentifier id) => id.name).toList();
+    } else if (combinator is HideCombinator) {
+      b.hides =
+          combinator.hiddenNames.map((SimpleIdentifier id) => id.name).toList();
+    } else {
+      throw new StateError(
+          'Unexpected combinator type: ${combinator.runtimeType}');
+    }
+    return b;
+  }
+
+  /**
+   * Main entry point for serializing an AST.
+   */
+  UnlinkedUnitBuilder serializeCompilationUnit(
+      CompilationUnit compilationUnit) {
+    compilationUnit.directives.accept(this);
+    if (!hasCoreBeenImported) {
+      unlinkedImports.add(new UnlinkedImportBuilder(isImplicit: true));
+    }
+    compilationUnit.declarations.accept(this);
+    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
+    b.libraryName = libraryName;
+    b.libraryNameOffset = libraryNameOffset;
+    b.libraryNameLength = libraryNameLength;
+    b.libraryDocumentationComment = libraryDocumentationComment;
+    b.classes = classes;
+    b.enums = enums;
+    b.executables = executables;
+    b.exports = exports;
+    b.imports = unlinkedImports;
+    b.parts = parts;
+    b.references = unlinkedReferences;
+    b.typedefs = typedefs;
+    b.variables = variables;
+    b.publicNamespace = computePublicNamespace(compilationUnit);
+    return b;
+  }
+
+  /**
+   * Serialize the given [expression], creating an [UnlinkedConstBuilder].
+   */
+  UnlinkedConstBuilder serializeConstExpr(Expression expression) {
+    _ConstExprSerializer serializer = new _ConstExprSerializer(this);
+    serializer.serialize(expression);
+    return serializer.toBuilder();
+  }
+
+  /**
+   * Serialize a [Comment] node into an [UnlinkedDocumentationComment] object.
+   */
+  UnlinkedDocumentationCommentBuilder serializeDocumentation(
+      Comment documentationComment) {
+    if (documentationComment == null) {
+      return null;
+    }
+    String text = documentationComment.tokens
+        .map((Token t) => t.toString())
+        .join()
+        .replaceAll('\r\n', '\n');
+    return new UnlinkedDocumentationCommentBuilder(
+        text: text,
+        offset: documentationComment.offset,
+        length: documentationComment.length);
+  }
+
+  /**
+   * Serialize a [FunctionDeclaration] or [MethodDeclaration] into an
+   * [UnlinkedExecutable].
+   */
+  UnlinkedExecutableBuilder serializeExecutable(
+      SimpleIdentifier name,
+      bool isGetter,
+      bool isSetter,
+      TypeName returnType,
+      FormalParameterList formalParameters,
+      FunctionBody body,
+      bool isTopLevel,
+      bool isDeclaredStatic,
+      Comment documentationComment,
+      TypeParameterList typeParameters,
+      bool isExternal) {
+    int oldScopesLength = scopes.length;
+    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
+    scopes.add(typeParameterScope);
+    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
+    String nameString = name.name;
+    if (isGetter) {
+      b.kind = UnlinkedExecutableKind.getter;
+    } else if (isSetter) {
+      b.kind = UnlinkedExecutableKind.setter;
+      nameString = '$nameString=';
+    } else {
+      b.kind = UnlinkedExecutableKind.functionOrMethod;
+    }
+    b.isAbstract = body is EmptyFunctionBody;
+    b.name = nameString;
+    b.nameOffset = name.offset;
+    b.typeParameters =
+        serializeTypeParameters(typeParameters, typeParameterScope);
+    if (!isTopLevel) {
+      b.isStatic = isDeclaredStatic;
+    }
+    b.returnType = serializeTypeName(returnType);
+    b.isExternal = isExternal;
+    bool isSemanticallyStatic = isTopLevel || isDeclaredStatic;
+    if (formalParameters != null) {
+      b.parameters = formalParameters.parameters
+          .map((FormalParameter p) => p.accept(this))
+          .toList();
+      if (!isSemanticallyStatic) {
+        for (int i = 0; i < formalParameters.parameters.length; i++) {
+          if (!b.parameters[i].isFunctionTyped &&
+              b.parameters[i].type == null) {
+            b.parameters[i].inferredTypeSlot = assignTypeSlot();
+          }
+        }
+      }
+    }
+    b.documentationComment = serializeDocumentation(documentationComment);
+    if (returnType == null && !isSemanticallyStatic) {
+      b.inferredReturnTypeSlot = assignTypeSlot();
+    }
+    scopes.removeLast();
+    assert(scopes.length == oldScopesLength);
+    return b;
+  }
+
+  /**
+   * Serialize the return type and parameters of a function-typed formal
+   * parameter and store them in [b].
+   */
+  void serializeFunctionTypedParameterDetails(UnlinkedParamBuilder b,
+      TypeName returnType, FormalParameterList parameters) {
+    EntityRefBuilder serializedReturnType = serializeTypeName(returnType);
+    if (serializedReturnType != null) {
+      b.type = serializedReturnType;
+    }
+    b.parameters = parameters.parameters
+        .map((FormalParameter p) => p.accept(this))
+        .toList();
+  }
+
+  /**
+   * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
+   * [SimpleFormalParameter] into an [UnlinkedParam].
+   */
+  UnlinkedParamBuilder serializeParameter(NormalFormalParameter node) {
+    UnlinkedParamBuilder b = new UnlinkedParamBuilder();
+    b.name = node.identifier.name;
+    b.nameOffset = node.identifier.offset;
+    switch (node.kind) {
+      case ParameterKind.REQUIRED:
+        b.kind = UnlinkedParamKind.required;
+        break;
+      case ParameterKind.POSITIONAL:
+        b.kind = UnlinkedParamKind.positional;
+        break;
+      case ParameterKind.NAMED:
+        b.kind = UnlinkedParamKind.named;
+        break;
+      default:
+        throw new StateError('Unexpected parameter kind: ${node.kind}');
+    }
+    return b;
+  }
+
+  /**
+   * Serialize a reference to a top level name declared elsewhere, by adding an
+   * entry to the references table if necessary.  If [prefixIndex] is not null,
+   * the reference is associated with the prefix having the given index in the
+   * references table.
+   */
+  int serializeReference(int prefixIndex, String name) => nameToReference
+          .putIfAbsent(prefixIndex, () => <String, int>{})
+          .putIfAbsent(name, () {
+        int index = unlinkedReferences.length;
+        unlinkedReferences.add(new UnlinkedReferenceBuilder(
+            prefixReference: prefixIndex, name: name));
+        return index;
+      });
+
+  /**
+   * Serialize a type name (which might be defined in a nested scope, at top
+   * level within this library, or at top level within an imported library) to
+   * a [EntityRef].  Note that this method does the right thing if the
+   * name doesn't refer to an entity other than a type (e.g. a class member).
+   */
+  EntityRefBuilder serializeTypeName(TypeName node) {
+    if (node == null) {
+      return null;
+    } else {
+      EntityRefBuilder b = new EntityRefBuilder();
+      Identifier identifier = node.name;
+      if (identifier is SimpleIdentifier) {
+        String name = identifier.name;
+        int indexOffset = 0;
+        for (int i = scopes.length - 1; i >= 0; i--) {
+          _Scope scope = scopes[i];
+          _ScopedEntity entity = scope[name];
+          if (entity != null) {
+            if (entity is _ScopedTypeParameter) {
+              b.paramReference = indexOffset + entity.index;
+              return b;
+            } else {
+              // None of the other things that can be declared in local scopes
+              // are types, so this is an error and should be treated as a
+              // reference to `dynamic`.
+              b.reference = serializeReference(null, 'dynamic');
+              return b;
+            }
+          }
+          if (scope is _TypeParameterScope) {
+            indexOffset += scope.length;
+          }
+        }
+        b.reference = serializeReference(null, name);
+      } else if (identifier is PrefixedIdentifier) {
+        int prefixIndex = prefixIndices.putIfAbsent(identifier.prefix.name,
+            () => serializeReference(null, identifier.prefix.name));
+        b.reference =
+            serializeReference(prefixIndex, identifier.identifier.name);
+      } else {
+        throw new StateError(
+            'Unexpected identifier type: ${identifier.runtimeType}');
+      }
+      if (node.typeArguments != null) {
+        // Trailing type arguments of type 'dynamic' should be omitted.
+        NodeList<TypeName> args = node.typeArguments.arguments;
+        int numArgsToSerialize = args.length;
+        while (
+            numArgsToSerialize > 0 && isDynamic(args[numArgsToSerialize - 1])) {
+          --numArgsToSerialize;
+        }
+        if (numArgsToSerialize > 0) {
+          List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
+          for (int i = 0; i < numArgsToSerialize; i++) {
+            serializedArguments.add(serializeTypeName(args[i]));
+          }
+          b.typeArguments = serializedArguments;
+        }
+      }
+      return b;
+    }
+  }
+
+  /**
+   * Serialize the given [typeParameters] into a list of [UnlinkedTypeParam]s,
+   * and also store them in [typeParameterScope].
+   */
+  List<UnlinkedTypeParamBuilder> serializeTypeParameters(
+      TypeParameterList typeParameters,
+      _TypeParameterScope typeParameterScope) {
+    if (typeParameters != null) {
+      for (int i = 0; i < typeParameters.typeParameters.length; i++) {
+        TypeParameter typeParameter = typeParameters.typeParameters[i];
+        typeParameterScope[typeParameter.name.name] =
+            new _ScopedTypeParameter(typeParameters.typeParameters.length - i);
+      }
+      return typeParameters.typeParameters.map(visitTypeParameter).toList();
+    }
+    return const <UnlinkedTypeParamBuilder>[];
+  }
+
+  /**
+   * Serialize the given [variables] into [UnlinkedVariable]s, and store them
+   * in [this.variables].
+   */
+  void serializeVariables(VariableDeclarationList variables,
+      bool isDeclaredStatic, Comment documentationComment, bool isField) {
+    for (VariableDeclaration variable in variables.variables) {
+      UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
+      b.isFinal = variables.isFinal;
+      b.isConst = variables.isConst;
+      b.isStatic = isDeclaredStatic;
+      b.name = variable.name.name;
+      b.nameOffset = variable.name.offset;
+      b.type = serializeTypeName(variables.type);
+      b.documentationComment = serializeDocumentation(documentationComment);
+      if (variable.isConst) {
+        Expression initializer = variable.initializer;
+        if (initializer != null) {
+          b.constExpr = serializeConstExpr(initializer);
+        }
+      }
+      if (variable.initializer != null &&
+          (variables.isFinal || variables.isConst)) {
+        b.propagatedTypeSlot = assignTypeSlot();
+      }
+      bool isSemanticallyStatic = !isField || isDeclaredStatic;
+      if (variables.type == null &&
+          (variable.initializer != null || !isSemanticallyStatic)) {
+        b.inferredTypeSlot = assignTypeSlot();
+      }
+      this.variables.add(b);
+    }
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    TypeName superclass =
+        node.extendsClause == null ? null : node.extendsClause.superclass;
+    serializeClass(
+        node.abstractKeyword,
+        node.name.name,
+        node.name.offset,
+        node.typeParameters,
+        superclass,
+        node.withClause,
+        node.implementsClause,
+        node.members,
+        false,
+        node.documentationComment);
+  }
+
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    serializeClass(
+        node.abstractKeyword,
+        node.name.name,
+        node.name.offset,
+        node.typeParameters,
+        node.superclass,
+        node.withClause,
+        node.implementsClause,
+        null,
+        true,
+        node.documentationComment);
+  }
+
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
+    if (node.name != null) {
+      b.name = node.name.name;
+      b.nameOffset = node.name.offset;
+    } else {
+      b.nameOffset = node.returnType.offset;
+    }
+    b.parameters = node.parameters.parameters
+        .map((FormalParameter p) => p.accept(this))
+        .toList();
+    b.kind = UnlinkedExecutableKind.constructor;
+    b.isFactory = node.factoryKeyword != null;
+    b.isConst = node.constKeyword != null;
+    b.isExternal = node.externalKeyword != null;
+    b.documentationComment = serializeDocumentation(node.documentationComment);
+    executables.add(b);
+  }
+
+  @override
+  UnlinkedParamBuilder visitDefaultFormalParameter(
+      DefaultFormalParameter node) {
+    return node.parameter.accept(this);
+  }
+
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    UnlinkedEnumBuilder b = new UnlinkedEnumBuilder();
+    b.name = node.name.name;
+    b.nameOffset = node.name.offset;
+    b.values = node.constants
+        .map((EnumConstantDeclaration value) => new UnlinkedEnumValueBuilder(
+            name: value.name.name, nameOffset: value.name.offset))
+        .toList();
+    b.documentationComment = serializeDocumentation(node.documentationComment);
+    enums.add(b);
+  }
+
+  @override
+  void visitExportDirective(ExportDirective node) {
+    UnlinkedExportNonPublicBuilder b = new UnlinkedExportNonPublicBuilder(
+        uriOffset: node.uri.offset, uriEnd: node.uri.end, offset: node.offset);
+    exports.add(b);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    serializeVariables(node.fields, node.staticKeyword != null,
+        node.documentationComment, true);
+  }
+
+  @override
+  UnlinkedParamBuilder visitFieldFormalParameter(FieldFormalParameter node) {
+    UnlinkedParamBuilder b = serializeParameter(node);
+    b.isInitializingFormal = true;
+    if (node.type != null || node.parameters != null) {
+      b.isFunctionTyped = node.parameters != null;
+      if (node.parameters != null) {
+        serializeFunctionTypedParameterDetails(b, node.type, node.parameters);
+      } else {
+        b.type = serializeTypeName(node.type);
+      }
+    }
+    return b;
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    executables.add(serializeExecutable(
+        node.name,
+        node.isGetter,
+        node.isSetter,
+        node.returnType,
+        node.functionExpression.parameters,
+        node.functionExpression.body,
+        true,
+        false,
+        node.documentationComment,
+        node.functionExpression.typeParameters,
+        node.externalKeyword != null));
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    int oldScopesLength = scopes.length;
+    _TypeParameterScope typeParameterScope = new _TypeParameterScope();
+    scopes.add(typeParameterScope);
+    UnlinkedTypedefBuilder b = new UnlinkedTypedefBuilder();
+    b.name = node.name.name;
+    b.nameOffset = node.name.offset;
+    b.typeParameters =
+        serializeTypeParameters(node.typeParameters, typeParameterScope);
+    EntityRefBuilder serializedReturnType = serializeTypeName(node.returnType);
+    if (serializedReturnType != null) {
+      b.returnType = serializedReturnType;
+    }
+    b.parameters = node.parameters.parameters
+        .map((FormalParameter p) => p.accept(this))
+        .toList();
+    b.documentationComment = serializeDocumentation(node.documentationComment);
+    typedefs.add(b);
+    scopes.removeLast();
+    assert(scopes.length == oldScopesLength);
+  }
+
+  @override
+  UnlinkedParamBuilder visitFunctionTypedFormalParameter(
+      FunctionTypedFormalParameter node) {
+    UnlinkedParamBuilder b = serializeParameter(node);
+    b.isFunctionTyped = true;
+    serializeFunctionTypedParameterDetails(b, node.returnType, node.parameters);
+    return b;
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    UnlinkedImportBuilder b = new UnlinkedImportBuilder();
+    if (node.uri.stringValue == 'dart:core') {
+      hasCoreBeenImported = true;
+    }
+    b.offset = node.offset;
+    b.combinators = node.combinators.map(serializeCombinator).toList();
+    if (node.prefix != null) {
+      b.prefixReference = serializeReference(null, node.prefix.name);
+      b.prefixOffset = node.prefix.offset;
+    }
+    b.isDeferred = node.deferredKeyword != null;
+    b.uri = node.uri.stringValue;
+    b.uriOffset = node.uri.offset;
+    b.uriEnd = node.uri.end;
+    unlinkedImports.add(b);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    libraryName =
+        node.name.components.map((SimpleIdentifier id) => id.name).join('.');
+    libraryNameOffset = node.name.offset;
+    libraryNameLength = node.name.length;
+    libraryDocumentationComment =
+        serializeDocumentation(node.documentationComment);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    executables.add(serializeExecutable(
+        node.name,
+        node.isGetter,
+        node.isSetter,
+        node.returnType,
+        node.parameters,
+        node.body,
+        false,
+        node.isStatic,
+        node.documentationComment,
+        node.typeParameters,
+        node.externalKeyword != null));
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    parts.add(new UnlinkedPartBuilder(
+        uriOffset: node.uri.offset, uriEnd: node.uri.end));
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {}
+
+  @override
+  UnlinkedParamBuilder visitSimpleFormalParameter(SimpleFormalParameter node) {
+    UnlinkedParamBuilder b = serializeParameter(node);
+    b.type = serializeTypeName(node.type);
+    return b;
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    serializeVariables(node.variables, false, node.documentationComment, false);
+  }
+
+  @override
+  UnlinkedTypeParamBuilder visitTypeParameter(TypeParameter node) {
+    UnlinkedTypeParamBuilder b = new UnlinkedTypeParamBuilder();
+    b.name = node.name.name;
+    b.nameOffset = node.name.offset;
+    if (node.bound != null) {
+      b.bound = serializeTypeName(node.bound);
+    }
+    return b;
+  }
+
+  /**
+   * Helper method to determine if a given [typeName] refers to `dynamic`.
+   */
+  static bool isDynamic(TypeName typeName) {
+    Identifier name = typeName.name;
+    return name is SimpleIdentifier && name.name == 'dynamic';
+  }
+}
+
+/**
+ * A [_TypeParameterScope] is a [_Scope] which defines [_ScopedTypeParameter]s.
+ */
+class _TypeParameterScope extends _Scope {
+  /**
+   * Get the number of [_ScopedTypeParameter]s defined in this
+   * [_TypeParameterScope].
+   */
+  int get length => _definedNames.length;
+}
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
new file mode 100644
index 0000000..f6dea26
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -0,0 +1,308 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library serialization.summarize_const_expr;
+
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/summary/format.dart';
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single constant [Expression].
+ */
+abstract class AbstractConstExprSerializer {
+  /**
+   * See [UnlinkedConstBuilder.operations].
+   */
+  final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
+
+  /**
+   * See [UnlinkedConstBuilder.ints].
+   */
+  final List<int> ints = <int>[];
+
+  /**
+   * See [UnlinkedConstBuilder.doubles].
+   */
+  final List<double> doubles = <double>[];
+
+  /**
+   * See [UnlinkedConstBuilder.strings].
+   */
+  final List<String> strings = <String>[];
+
+  /**
+   * See [UnlinkedConstBuilder.references].
+   */
+  final List<EntityRefBuilder> references = <EntityRefBuilder>[];
+
+  /**
+   * Serialize the given [expr] expression into this serializer state.
+   */
+  void serialize(Expression expr) {
+    if (expr is IntegerLiteral) {
+      _pushInt(expr.value);
+    } else if (expr is DoubleLiteral) {
+      operations.add(UnlinkedConstOperation.pushDouble);
+      doubles.add(expr.value);
+    } else if (expr is BooleanLiteral) {
+      if (expr.value) {
+        operations.add(UnlinkedConstOperation.pushTrue);
+      } else {
+        operations.add(UnlinkedConstOperation.pushFalse);
+      }
+    } else if (expr is StringLiteral) {
+      _serializeString(expr);
+    } else if (expr is SymbolLiteral) {
+      strings.add(expr.components.map((token) => token.lexeme).join('.'));
+      operations.add(UnlinkedConstOperation.pushString);
+      operations.add(UnlinkedConstOperation.makeSymbol);
+    } else if (expr is NullLiteral) {
+      operations.add(UnlinkedConstOperation.pushNull);
+    } else if (expr is Identifier) {
+      references.add(serializeIdentifier(expr));
+      operations.add(UnlinkedConstOperation.pushReference);
+    } else if (expr is InstanceCreationExpression) {
+      _serializeInstanceCreation(expr);
+    } else if (expr is ListLiteral) {
+      _serializeListLiteral(expr);
+    } else if (expr is MapLiteral) {
+      _serializeMapLiteral(expr);
+    } else if (expr is MethodInvocation) {
+      String name = expr.methodName.name;
+      if (name != 'identical') {
+        throw new _ConstExprSerializationError(
+            'Only "identity" function invocation is allowed.');
+      }
+      if (expr.argumentList == null ||
+          expr.argumentList.arguments.length != 2) {
+        throw new _ConstExprSerializationError(
+            'The function "identity" requires exactly 2 arguments.');
+      }
+      expr.argumentList.arguments.forEach(serialize);
+      operations.add(UnlinkedConstOperation.identical);
+    } else if (expr is BinaryExpression) {
+      _serializeBinaryExpression(expr);
+    } else if (expr is ConditionalExpression) {
+      serialize(expr.condition);
+      serialize(expr.thenExpression);
+      serialize(expr.elseExpression);
+      operations.add(UnlinkedConstOperation.conditional);
+    } else if (expr is PrefixExpression) {
+      _serializePrefixExpression(expr);
+    } else if (expr is PropertyAccess) {
+      if (expr.target is! PrefixedIdentifier &&
+          expr.propertyName.name == 'length') {
+        serialize(expr.target);
+        operations.add(UnlinkedConstOperation.length);
+      } else {
+        references.add(serializePropertyAccess(expr));
+        operations.add(UnlinkedConstOperation.pushReference);
+      }
+    } else if (expr is ParenthesizedExpression) {
+      serialize(expr.expression);
+    } else {
+      throw new _ConstExprSerializationError('Unknown expression type: $expr');
+    }
+  }
+
+  /**
+   * Return [EntityRefBuilder] that corresponds to the given [constructor].
+   */
+  EntityRefBuilder serializeConstructorName(ConstructorName constructor);
+
+  /**
+   * Return [EntityRefBuilder] that corresponds to the given [identifier].
+   */
+  EntityRefBuilder serializeIdentifier(Identifier identifier);
+
+  /**
+   * Return [EntityRefBuilder] that corresponds to the given [access].
+   */
+  EntityRefBuilder serializePropertyAccess(PropertyAccess access);
+
+  /**
+   * Return [EntityRefBuilder] that corresponds to the given [type].
+   */
+  EntityRefBuilder serializeType(TypeName type);
+
+  /**
+   * Return the [UnlinkedConstBuilder] that corresponds to the state of this
+   * serializer.
+   */
+  UnlinkedConstBuilder toBuilder() {
+    return new UnlinkedConstBuilder(
+        operations: operations,
+        ints: ints,
+        doubles: doubles,
+        strings: strings,
+        references: references);
+  }
+
+  void _pushInt(int value) {
+    assert(value >= 0);
+    if (value >= (1 << 32)) {
+      _pushInt(value >> 32);
+      operations.add(UnlinkedConstOperation.shiftOr);
+      ints.add(value & 0xFFFFFFFF);
+    } else {
+      operations.add(UnlinkedConstOperation.pushInt);
+      ints.add(value);
+    }
+  }
+
+  void _serializeBinaryExpression(BinaryExpression expr) {
+    serialize(expr.leftOperand);
+    serialize(expr.rightOperand);
+    TokenType operator = expr.operator.type;
+    if (operator == TokenType.EQ_EQ) {
+      operations.add(UnlinkedConstOperation.equal);
+    } else if (operator == TokenType.BANG_EQ) {
+      operations.add(UnlinkedConstOperation.equal);
+      operations.add(UnlinkedConstOperation.not);
+    } else if (operator == TokenType.AMPERSAND_AMPERSAND) {
+      operations.add(UnlinkedConstOperation.and);
+    } else if (operator == TokenType.BAR_BAR) {
+      operations.add(UnlinkedConstOperation.or);
+    } else if (operator == TokenType.CARET) {
+      operations.add(UnlinkedConstOperation.bitXor);
+    } else if (operator == TokenType.AMPERSAND) {
+      operations.add(UnlinkedConstOperation.bitAnd);
+    } else if (operator == TokenType.BAR) {
+      operations.add(UnlinkedConstOperation.bitOr);
+    } else if (operator == TokenType.GT_GT) {
+      operations.add(UnlinkedConstOperation.bitShiftRight);
+    } else if (operator == TokenType.LT_LT) {
+      operations.add(UnlinkedConstOperation.bitShiftLeft);
+    } else if (operator == TokenType.PLUS) {
+      operations.add(UnlinkedConstOperation.add);
+    } else if (operator == TokenType.MINUS) {
+      operations.add(UnlinkedConstOperation.subtract);
+    } else if (operator == TokenType.STAR) {
+      operations.add(UnlinkedConstOperation.multiply);
+    } else if (operator == TokenType.SLASH) {
+      operations.add(UnlinkedConstOperation.divide);
+    } else if (operator == TokenType.TILDE_SLASH) {
+      operations.add(UnlinkedConstOperation.floorDivide);
+    } else if (operator == TokenType.GT) {
+      operations.add(UnlinkedConstOperation.greater);
+    } else if (operator == TokenType.LT) {
+      operations.add(UnlinkedConstOperation.less);
+    } else if (operator == TokenType.GT_EQ) {
+      operations.add(UnlinkedConstOperation.greaterEqual);
+    } else if (operator == TokenType.LT_EQ) {
+      operations.add(UnlinkedConstOperation.lessEqual);
+    } else if (operator == TokenType.PERCENT) {
+      operations.add(UnlinkedConstOperation.modulo);
+    } else {
+      throw new _ConstExprSerializationError('Unknown operator: $operator');
+    }
+  }
+
+  void _serializeInstanceCreation(InstanceCreationExpression expr) {
+    ConstructorName constructor = expr.constructorName;
+    List<Expression> arguments = expr.argumentList.arguments;
+    // Serialize the arguments.
+    List<String> argumentNames = <String>[];
+    arguments.forEach((arg) {
+      if (arg is NamedExpression) {
+        argumentNames.add(arg.name.label.name);
+        serialize(arg.expression);
+      } else {
+        serialize(arg);
+      }
+    });
+    // Add the op-code and numbers of named and positional arguments.
+    operations.add(UnlinkedConstOperation.invokeConstructor);
+    ints.add(argumentNames.length);
+    strings.addAll(argumentNames);
+    ints.add(arguments.length - argumentNames.length);
+    // Serialize the reference.
+    references.add(serializeConstructorName(constructor));
+  }
+
+  void _serializeListLiteral(ListLiteral expr) {
+    List<Expression> elements = expr.elements;
+    elements.forEach(serialize);
+    ints.add(elements.length);
+    if (expr.typeArguments != null &&
+        expr.typeArguments.arguments.length == 1) {
+      references.add(serializeType(expr.typeArguments.arguments[0]));
+      operations.add(UnlinkedConstOperation.makeTypedList);
+    } else {
+      operations.add(UnlinkedConstOperation.makeUntypedList);
+    }
+  }
+
+  void _serializeMapLiteral(MapLiteral expr) {
+    for (MapLiteralEntry entry in expr.entries) {
+      serialize(entry.key);
+      serialize(entry.value);
+    }
+    ints.add(expr.entries.length);
+    if (expr.typeArguments != null &&
+        expr.typeArguments.arguments.length == 2) {
+      references.add(serializeType(expr.typeArguments.arguments[0]));
+      references.add(serializeType(expr.typeArguments.arguments[1]));
+      operations.add(UnlinkedConstOperation.makeTypedMap);
+    } else {
+      operations.add(UnlinkedConstOperation.makeUntypedMap);
+    }
+  }
+
+  void _serializePrefixExpression(PrefixExpression expr) {
+    serialize(expr.operand);
+    TokenType operator = expr.operator.type;
+    if (operator == TokenType.BANG) {
+      operations.add(UnlinkedConstOperation.not);
+    } else if (operator == TokenType.MINUS) {
+      operations.add(UnlinkedConstOperation.negate);
+    } else if (operator == TokenType.TILDE) {
+      operations.add(UnlinkedConstOperation.complement);
+    } else {
+      throw new _ConstExprSerializationError('Unknown operator: $operator');
+    }
+  }
+
+  void _serializeString(StringLiteral expr) {
+    if (expr is AdjacentStrings) {
+      if (expr.strings.every((string) => string is SimpleStringLiteral)) {
+        operations.add(UnlinkedConstOperation.pushString);
+        strings.add(expr.stringValue);
+      } else {
+        expr.strings.forEach(_serializeString);
+        operations.add(UnlinkedConstOperation.concatenate);
+        ints.add(expr.strings.length);
+      }
+    } else if (expr is SimpleStringLiteral) {
+      operations.add(UnlinkedConstOperation.pushString);
+      strings.add(expr.value);
+    } else {
+      StringInterpolation interpolation = expr as StringInterpolation;
+      for (InterpolationElement element in interpolation.elements) {
+        if (element is InterpolationString) {
+          operations.add(UnlinkedConstOperation.pushString);
+          strings.add(element.value);
+        } else {
+          serialize((element as InterpolationExpression).expression);
+        }
+      }
+      operations.add(UnlinkedConstOperation.concatenate);
+      ints.add(interpolation.elements.length);
+    }
+  }
+}
+
+/**
+ * Error that describes a problem during a constant expression serialization.
+ */
+class _ConstExprSerializationError {
+  final String message;
+
+  _ConstExprSerializationError(this.message);
+
+  @override
+  String toString() => message;
+}
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 0eac910..66f31ecc 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -6,32 +6,65 @@
 
 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/resolver.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/name_filter.dart';
+import 'package:analyzer/src/summary/summarize_const_expr.dart';
 
 /**
  * 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.
  */
 LibrarySerializationResult serializeLibrary(
-    LibraryElement lib, TypeProvider typeProvider) {
-  var serializer = new _LibrarySerializer(lib, typeProvider);
-  PrelinkedLibraryBuilder prelinked = serializer.serializeLibrary();
+    LibraryElement lib, TypeProvider typeProvider, bool strongMode) {
+  var serializer = new _LibrarySerializer(lib, typeProvider, strongMode);
+  LinkedLibraryBuilder linked = serializer.serializeLibrary();
   return new LibrarySerializationResult(
-      prelinked, serializer.unlinkedUnits, serializer.unitUris);
+      linked, serializer.unlinkedUnits, serializer.unitUris);
 }
 
+ReferenceKind _getReferenceKind(Element element) {
+  if (element == null ||
+      element is ClassElement ||
+      element is DynamicElementImpl) {
+    return ReferenceKind.classOrEnum;
+  } else if (element is ConstructorElement) {
+    return ReferenceKind.constructor;
+  } else if (element is FunctionElement) {
+    return ReferenceKind.topLevelFunction;
+  } else if (element is FunctionTypeAliasElement) {
+    return ReferenceKind.typedef;
+  } else if (element is PropertyAccessorElement) {
+    if (element.enclosingElement is ClassElement) {
+      return ReferenceKind.constField;
+    }
+    return ReferenceKind.topLevelPropertyAccessor;
+  } else if (element is MethodElement) {
+    return ReferenceKind.staticMethod;
+  } else {
+    throw new Exception('Unexpected element kind: ${element.runtimeType}');
+  }
+}
+
+/**
+ * Type of closures used by [_LibrarySerializer] to defer generation of
+ * [EntityRefBuilder] objects until the end of serialization of a
+ * compilation unit.
+ */
+typedef EntityRefBuilder _SerializeTypeRef();
+
 /**
  * Data structure holding the result of serializing a [LibraryElement].
  */
 class LibrarySerializationResult {
   /**
-   * Pre-linked information the given library.
+   * Linked information the given library.
    */
-  final PrelinkedLibraryBuilder prelinked;
+  final LinkedLibraryBuilder linked;
 
   /**
    * Unlinked information for the compilation units constituting the library.
@@ -46,58 +79,45 @@
    */
   final List<String> unitUris;
 
-  LibrarySerializationResult(this.prelinked, this.unlinkedUnits, this.unitUris);
+  LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris);
 }
 
 /**
  * Instances of this class keep track of intermediate state during
- * serialization of a single library.`
+ * serialization of a single compilation unit.
  */
-class _LibrarySerializer {
+class _CompilationUnitSerializer {
   /**
-   * The library to be serialized.
+   * The [_LibrarySerializer] which is serializing the library of which
+   * [compilationUnit] is a part.
    */
-  final LibraryElement libraryElement;
+  final _LibrarySerializer librarySerializer;
 
   /**
-   * The type provider.  This is used to locate the library for `dart:core`.
+   * The [CompilationUnitElement] being serialized.
    */
-  final TypeProvider typeProvider;
+  final CompilationUnitElement compilationUnit;
 
   /**
-   * List of objects which should be written to [PrelinkedLibrary.units].
+   * The ordinal index of [compilationUnit] within the library, where 0
+   * represents the defining compilation unit.
    */
-  final List<PrelinkedUnitBuilder> prelinkedUnits = <PrelinkedUnitBuilder>[];
+  final int unitNum;
 
   /**
-   * List of unlinked units corresponding to the pre-linked units in
-   * [prelinkedUnits],
+   * The final linked summary of the compilation unit.
    */
-  final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
+  final LinkedUnitBuilder linkedUnit = new LinkedUnitBuilder();
 
   /**
-   * List of absolute URIs of the compilation units in the library.
+   * The final unlinked summary of the compilation unit.
    */
-  final List<String> unitUris = <String>[];
+  final UnlinkedUnitBuilder unlinkedUnit = new UnlinkedUnitBuilder();
 
-  /**
-   * Map from [LibraryElement] to the index of the entry in the "dependency
-   * table" that refers to it.
-   */
-  final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
-
-  /**
-   * The "dependency table".  This is the list of objects which should be
-   * written to [PrelinkedLibrary.dependencies].
-   */
-  final List<PrelinkedDependencyBuilder> dependencies =
-      <PrelinkedDependencyBuilder>[];
-
-  /**
-   * 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>[];
+/**
+ * Absolute URI of the compilation unit.
+ */
+  String unitUri;
 
   /**
    * Map from [Element] to the index of the entry in the "references table"
@@ -112,12 +132,21 @@
   List<UnlinkedReferenceBuilder> unlinkedReferences;
 
   /**
-   * The prelinked portion of the "references table".  This is the list of
-   * objects which should be written to [PrelinkedUnit.references].
+   * The linked portion of the "references table".  This is the list of
+   * objects which should be written to [LinkedUnit.references].
    */
-  List<PrelinkedReferenceBuilder> prelinkedReferences;
+  List<LinkedReferenceBuilder> linkedReferences;
 
-  //final Map<String, int> prefixIndices = <String, int>{};
+  /**
+   * The number of slot ids which have been assigned to this compilation unit.
+   */
+  int numSlots = 0;
+
+  /**
+   * List of closures which should be invoked at the end of serialization of a
+   * compilation unit, to produce [LinkedUnit.types].
+   */
+  final List<_SerializeTypeRef> deferredLinkedTypes = <_SerializeTypeRef>[];
 
   /**
    * Index into the "references table" representing an unresolved reference, if
@@ -126,99 +155,86 @@
    */
   int unresolvedReferenceIndex = null;
 
-  /**
-   * Set of libraries which have been seen so far while visiting the transitive
-   * closure of exports.
-   */
-  final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
-      new Set<LibraryElement>();
-
-  /**
-   * Map from imported element to the prefix which may be used to refer to that
-   * element; elements for which no prefix is needed are absent from this map.
-   */
-  final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
-
-  _LibrarySerializer(this.libraryElement, this.typeProvider) {
-    dependencies.add(encodePrelinkedDependency());
-    dependencyMap[libraryElement] = 0;
-  }
-
-  /**
-   * Retrieve the library element for `dart:core`.
-   */
-  LibraryElement get coreLibrary => typeProvider.objectType.element.library;
+  _CompilationUnitSerializer(
+      this.librarySerializer, this.compilationUnit, this.unitNum);
 
   /**
    * Add all classes, enums, typedefs, executables, and top level variables
-   * from the given compilation unit [element] to the library summary.
+   * from the given compilation unit [element] to the compilation unit summary.
    * [unitNum] indicates the ordinal position of this compilation unit in the
    * library.
    */
-  void addCompilationUnitElements(CompilationUnitElement element, int unitNum) {
-    UnlinkedUnitBuilder b = new UnlinkedUnitBuilder();
-    referenceMap.clear();
-    unlinkedReferences = <UnlinkedReferenceBuilder>[encodeUnlinkedReference()];
-    prelinkedReferences = <PrelinkedReferenceBuilder>[
-      encodePrelinkedReference(kind: PrelinkedReferenceKind.classOrEnum)
+  void addCompilationUnitElements() {
+    unlinkedReferences = <UnlinkedReferenceBuilder>[
+      new UnlinkedReferenceBuilder()
+    ];
+    linkedReferences = <LinkedReferenceBuilder>[
+      new LinkedReferenceBuilder(kind: ReferenceKind.classOrEnum)
     ];
     List<UnlinkedPublicNameBuilder> names = <UnlinkedPublicNameBuilder>[];
-    for (PropertyAccessorElement accessor in element.accessors) {
+    for (PropertyAccessorElement accessor in compilationUnit.accessors) {
       if (accessor.isPublic) {
-        names.add(encodeUnlinkedPublicName(
-            kind: PrelinkedReferenceKind.other,
+        names.add(new UnlinkedPublicNameBuilder(
+            kind: ReferenceKind.topLevelPropertyAccessor,
             name: accessor.name,
             numTypeParameters: accessor.typeParameters.length));
       }
     }
-    for (ClassElement cls in element.types) {
+    for (ClassElement cls in compilationUnit.types) {
       if (cls.isPublic) {
-        names.add(encodeUnlinkedPublicName(
-            kind: PrelinkedReferenceKind.classOrEnum,
+        names.add(new UnlinkedPublicNameBuilder(
+            kind: ReferenceKind.classOrEnum,
             name: cls.name,
-            numTypeParameters: cls.typeParameters.length));
+            numTypeParameters: cls.typeParameters.length,
+            constMembers: serializeClassConstMembers(cls)));
       }
     }
-    for (ClassElement enm in element.enums) {
+    for (ClassElement enm in compilationUnit.enums) {
       if (enm.isPublic) {
-        names.add(encodeUnlinkedPublicName(
-            kind: PrelinkedReferenceKind.classOrEnum, name: enm.name));
+        names.add(new UnlinkedPublicNameBuilder(
+            kind: ReferenceKind.classOrEnum, name: enm.name));
       }
     }
-    for (FunctionElement function in element.functions) {
+    for (FunctionElement function in compilationUnit.functions) {
       if (function.isPublic) {
-        names.add(encodeUnlinkedPublicName(
-            kind: PrelinkedReferenceKind.other,
+        names.add(new UnlinkedPublicNameBuilder(
+            kind: ReferenceKind.topLevelFunction,
             name: function.name,
             numTypeParameters: function.typeParameters.length));
       }
     }
-    for (FunctionTypeAliasElement typedef in element.functionTypeAliases) {
+    for (FunctionTypeAliasElement typedef
+        in compilationUnit.functionTypeAliases) {
       if (typedef.isPublic) {
-        names.add(encodeUnlinkedPublicName(
-            kind: PrelinkedReferenceKind.typedef,
+        names.add(new UnlinkedPublicNameBuilder(
+            kind: ReferenceKind.typedef,
             name: typedef.name,
             numTypeParameters: typedef.typeParameters.length));
       }
     }
     if (unitNum == 0) {
+      LibraryElement libraryElement = librarySerializer.libraryElement;
       if (libraryElement.name.isNotEmpty) {
-        b.libraryName = libraryElement.name;
-        b.libraryNameOffset = libraryElement.nameOffset;
-        b.libraryNameLength = libraryElement.nameLength;
-        b.libraryDocumentationComment = serializeDocumentation(libraryElement);
+        LibraryElement libraryElement = librarySerializer.libraryElement;
+        unlinkedUnit.libraryName = libraryElement.name;
+        unlinkedUnit.libraryNameOffset = libraryElement.nameOffset;
+        unlinkedUnit.libraryNameLength = libraryElement.nameLength;
+        unlinkedUnit.libraryDocumentationComment =
+            serializeDocumentation(libraryElement);
       }
-      b.publicNamespace = encodeUnlinkedPublicNamespace(
+      unlinkedUnit.publicNamespace = new UnlinkedPublicNamespaceBuilder(
           exports: libraryElement.exports.map(serializeExportPublic).toList(),
           parts: libraryElement.parts
               .map((CompilationUnitElement e) => e.uri)
               .toList(),
           names: names);
-      b.exports = libraryElement.exports.map(serializeExportNonPublic).toList();
-      b.imports = libraryElement.imports.map(serializeImport).toList();
-      b.parts = libraryElement.parts
+      unlinkedUnit.exports =
+          libraryElement.exports.map(serializeExportNonPublic).toList();
+      unlinkedUnit.imports =
+          libraryElement.imports.map(serializeImport).toList();
+      unlinkedUnit.parts = libraryElement.parts
           .map((CompilationUnitElement e) =>
-              encodeUnlinkedPart(uriOffset: e.uriOffset, uriEnd: e.uriEnd))
+              new UnlinkedPartBuilder(uriOffset: e.uriOffset, uriEnd: e.uriEnd))
           .toList();
     } else {
       // TODO(paulberry): we need to figure out a way to record library, part,
@@ -227,21 +243,23 @@
       // 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.
-      b.publicNamespace = encodeUnlinkedPublicNamespace(names: names);
+      unlinkedUnit.publicNamespace =
+          new UnlinkedPublicNamespaceBuilder(names: names);
     }
-    b.classes = element.types.map(serializeClass).toList();
-    b.enums = element.enums.map(serializeEnum).toList();
-    b.typedefs = element.functionTypeAliases.map(serializeTypedef).toList();
+    unlinkedUnit.classes = compilationUnit.types.map(serializeClass).toList();
+    unlinkedUnit.enums = compilationUnit.enums.map(serializeEnum).toList();
+    unlinkedUnit.typedefs =
+        compilationUnit.functionTypeAliases.map(serializeTypedef).toList();
     List<UnlinkedExecutableBuilder> executables =
-        element.functions.map(serializeExecutable).toList();
-    for (PropertyAccessorElement accessor in element.accessors) {
+        compilationUnit.functions.map(serializeExecutable).toList();
+    for (PropertyAccessorElement accessor in compilationUnit.accessors) {
       if (!accessor.isSynthetic) {
         executables.add(serializeExecutable(accessor));
       }
     }
-    b.executables = executables;
+    unlinkedUnit.executables = executables;
     List<UnlinkedVariableBuilder> variables = <UnlinkedVariableBuilder>[];
-    for (PropertyAccessorElement accessor in element.accessors) {
+    for (PropertyAccessorElement accessor in compilationUnit.accessors) {
       if (accessor.isSynthetic && accessor.isGetter) {
         PropertyInducingElement variable = accessor.variable;
         if (variable != null) {
@@ -250,45 +268,20 @@
         }
       }
     }
-    b.variables = variables;
-    b.references = unlinkedReferences;
-    unlinkedUnits.add(b);
-    prelinkedUnits.add(encodePrelinkedUnit(references: prelinkedReferences));
-    unitUris.add(element.source.uri.toString());
-    unlinkedReferences = null;
-    prelinkedReferences = null;
+    unlinkedUnit.variables = variables;
+    unlinkedUnit.references = unlinkedReferences;
+    linkedUnit.references = linkedReferences;
+    unitUri = compilationUnit.source.uri.toString();
   }
 
   /**
-   * Add [exportedLibrary] (and the transitive closure of all libraries it
-   * exports) to the dependency table ([PrelinkedLibrary.dependencies]).
+   * Create the [LinkedUnit.types] table based on deferred types that were
+   * found during [addCompilationUnitElements].
    */
-  void addTransitiveExportClosure(LibraryElement exportedLibrary) {
-    if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
-      serializeDependency(exportedLibrary);
-      for (LibraryElement transitiveExport
-          in exportedLibrary.exportedLibraries) {
-        addTransitiveExportClosure(transitiveExport);
-      }
-    }
-  }
-
-  /**
-   * Fill in [prefixMap] using information from [libraryElement.imports].
-   */
-  void computePrefixMap() {
-    for (ImportElement import in libraryElement.imports) {
-      if (import.prefix == null) {
-        continue;
-      }
-      import.importedLibrary.exportNamespace.definedNames
-          .forEach((String name, Element e) {
-        if (new NameFilter.forNamespaceCombinators(import.combinators)
-            .accepts(name)) {
-          prefixMap[e] = import.prefix;
-        }
-      });
-    }
+  void createLinkedTypes() {
+    linkedUnit.types = deferredLinkedTypes
+        .map((_SerializeTypeRef closure) => closure())
+        .toList();
   }
 
   /**
@@ -321,6 +314,23 @@
   }
 
   /**
+   * Get the type arguments for the given [type], or `null` if the type has no
+   * type arguments.
+   *
+   * TODO(paulberry): consider adding an abstract getter to [DartType] to do
+   * this.
+   */
+  List<DartType> getTypeArguments(DartType type) {
+    if (type is InterfaceType) {
+      return type.typeArguments;
+    } else if (type is FunctionType) {
+      return type.typeArguments;
+    } else {
+      return null;
+    }
+  }
+
+  /**
    * Serialize the given [classElement], creating an [UnlinkedClass].
    */
   UnlinkedClassBuilder serializeClass(ClassElement classElement) {
@@ -369,6 +379,43 @@
   }
 
   /**
+   * If [cls] is a class, return the list of its members available for
+   * constants - static constant fields, static methods and constructors.
+   * Otherwise return `null`.
+   */
+  List<UnlinkedPublicNameBuilder> serializeClassConstMembers(ClassElement cls) {
+    if (cls.kind == ElementKind.CLASS) {
+      List<UnlinkedPublicNameBuilder> bs = <UnlinkedPublicNameBuilder>[];
+      for (FieldElement field in cls.fields) {
+        if (field.isStatic && field.isConst && field.isPublic) {
+          bs.add(new UnlinkedPublicNameBuilder(
+              name: field.name,
+              kind: ReferenceKind.constField,
+              numTypeParameters: 0));
+        }
+      }
+      for (MethodElement method in cls.methods) {
+        if (method.isStatic && method.isPublic) {
+          bs.add(new UnlinkedPublicNameBuilder(
+              name: method.name,
+              kind: ReferenceKind.staticMethod,
+              numTypeParameters: method.typeParameters.length));
+        }
+      }
+      for (ConstructorElement constructor in cls.constructors) {
+        if (constructor.isConst && constructor.isPublic) {
+          bs.add(new UnlinkedPublicNameBuilder(
+              name: constructor.name,
+              kind: ReferenceKind.constructor,
+              numTypeParameters: 0));
+        }
+      }
+      return bs;
+    }
+    return null;
+  }
+
+  /**
    * Serialize the given [combinator] into an [UnlinkedCombinator].
    */
   UnlinkedCombinatorBuilder serializeCombinator(
@@ -383,20 +430,12 @@
   }
 
   /**
-   * Return the index of the entry in the dependency table
-   * ([PrelinkedLibrary.dependencies]) for the given [dependentLibrary].  A new
-   * entry is added to the table if necessary to satisfy the request.
+   * Serialize the given [expression], creating an [UnlinkedConstBuilder].
    */
-  int serializeDependency(LibraryElement dependentLibrary) {
-    return dependencyMap.putIfAbsent(dependentLibrary, () {
-      int index = dependencies.length;
-      List<String> parts = dependentLibrary.parts
-          .map((CompilationUnitElement e) => e.source.uri.toString())
-          .toList();
-      dependencies.add(encodePrelinkedDependency(
-          uri: dependentLibrary.source.uri.toString(), parts: parts));
-      return index;
-    });
+  UnlinkedConstBuilder serializeConstExpr(Expression expression) {
+    _ConstExprSerializer serializer = new _ConstExprSerializer(this);
+    serializer.serialize(expression);
+    return serializer.toBuilder();
   }
 
   /**
@@ -409,20 +448,13 @@
     if (element.documentationComment == null) {
       return null;
     }
-    return encodeUnlinkedDocumentationComment(
+    return new UnlinkedDocumentationCommentBuilder(
         text: element.documentationComment,
         offset: element.docRange.offset,
         length: element.docRange.length);
   }
 
   /**
-   * Return the index of the entry in the references table
-   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references])
-   * representing the pseudo-type `dynamic`.
-   */
-  int serializeDynamicReference() => 0;
-
-  /**
    * Serialize the given [enumElement], creating an [UnlinkedEnum].
    */
   UnlinkedEnumBuilder serializeEnum(ClassElement enumElement) {
@@ -432,7 +464,7 @@
     List<UnlinkedEnumValueBuilder> values = <UnlinkedEnumValueBuilder>[];
     for (FieldElement field in enumElement.fields) {
       if (field.isConst && field.type.element == enumElement) {
-        values.add(encodeUnlinkedEnumValue(
+        values.add(new UnlinkedEnumValueBuilder(
             name: field.name,
             nameOffset: field.nameOffset,
             documentationComment: serializeDocumentation(field)));
@@ -451,10 +483,14 @@
     UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
     b.name = executableElement.name;
     b.nameOffset = executableElement.nameOffset;
-    if (executableElement is! ConstructorElement &&
-        !executableElement.type.returnType.isVoid) {
-      b.returnType = serializeTypeRef(
-          executableElement.type.returnType, executableElement);
+    if (executableElement is! ConstructorElement) {
+      if (!executableElement.hasImplicitReturnType) {
+        b.returnType = serializeTypeRef(
+            executableElement.type.returnType, executableElement);
+      } else if (!executableElement.isStatic) {
+        b.inferredReturnTypeSlot =
+            storeInferredType(executableElement.returnType, executableElement);
+      }
     }
     b.typeParameters =
         executableElement.typeParameters.map(serializeTypeParam).toList();
@@ -476,7 +512,6 @@
     b.isAbstract = executableElement.isAbstract;
     b.isStatic = executableElement.isStatic &&
         executableElement.enclosingElement is ClassElement;
-    b.hasImplicitReturnType = executableElement.hasImplicitReturnType;
     b.isExternal = executableElement.isExternal;
     b.documentationComment = serializeDocumentation(executableElement);
     return b;
@@ -507,12 +542,11 @@
 
   /**
    * Serialize the given [importElement] yielding an [UnlinkedImportBuilder].
-   * Also, add pre-linked information about it to the [prelinkedImports] list.
+   * Also, add linked information about it to the [linkedImports] list.
    */
   UnlinkedImportBuilder serializeImport(ImportElement importElement) {
     UnlinkedImportBuilder b = new UnlinkedImportBuilder();
     b.isDeferred = importElement.isDeferred;
-    b.offset = importElement.nameOffset;
     b.combinators = importElement.combinators.map(serializeCombinator).toList();
     if (importElement.prefix != null) {
       b.prefixReference = serializePrefix(importElement.prefix);
@@ -521,36 +555,15 @@
     if (importElement.isSynthetic) {
       b.isImplicit = true;
     } else {
+      b.offset = importElement.nameOffset;
       b.uri = importElement.uri;
       b.uriOffset = importElement.uriOffset;
       b.uriEnd = importElement.uriEnd;
     }
-    addTransitiveExportClosure(importElement.importedLibrary);
-    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() {
-    computePrefixMap();
-    PrelinkedLibraryBuilder pb = new PrelinkedLibraryBuilder();
-    addCompilationUnitElements(libraryElement.definingCompilationUnit, 0);
-    for (int i = 0; i < libraryElement.parts.length; i++) {
-      addCompilationUnitElements(libraryElement.parts[i], i + 1);
-    }
-    pb.units = prelinkedUnits;
-    pb.dependencies = dependencies;
-    pb.importDependencies = prelinkedImports;
-    return pb;
-  }
-
-  /**
    * Serialize the given [parameter] into an [UnlinkedParam].
    */
   UnlinkedParamBuilder serializeParam(ParameterElement parameter,
@@ -572,17 +585,24 @@
     }
     b.isInitializingFormal = parameter.isInitializingFormal;
     DartType type = parameter.type;
-    if (type is FunctionType) {
-      b.isFunctionTyped = true;
-      if (!type.returnType.isVoid) {
-        b.type = serializeTypeRef(type.returnType, parameter);
+    if (parameter.hasImplicitType) {
+      Element contextParent = context.enclosingElement;
+      if (!parameter.isInitializingFormal &&
+          contextParent is ExecutableElement &&
+          !contextParent.isStatic &&
+          contextParent is! ConstructorElement) {
+        b.inferredTypeSlot = storeInferredType(type, context);
       }
-      b.parameters = type.parameters
-          .map((parameter) => serializeParam(parameter, context))
-          .toList();
     } else {
-      b.type = serializeTypeRef(type, context);
-      b.hasImplicitType = parameter.hasImplicitType;
+      if (type is FunctionType) {
+        b.isFunctionTyped = true;
+        b.type = serializeTypeRef(type.returnType, parameter);
+        b.parameters = type.parameters
+            .map((parameter) => serializeParam(parameter, context))
+            .toList();
+      } else {
+        b.type = serializeTypeRef(type, context);
+      }
     }
     return b;
   }
@@ -592,16 +612,36 @@
    */
   int serializePrefix(PrefixElement element) {
     return referenceMap.putIfAbsent(element, () {
-      assert(unlinkedReferences.length == prelinkedReferences.length);
+      assert(unlinkedReferences.length == linkedReferences.length);
       int index = unlinkedReferences.length;
-      unlinkedReferences.add(encodeUnlinkedReference(name: element.name));
-      prelinkedReferences
-          .add(encodePrelinkedReference(kind: PrelinkedReferenceKind.prefix));
+      unlinkedReferences.add(new UnlinkedReferenceBuilder(name: element.name));
+      linkedReferences
+          .add(new LinkedReferenceBuilder(kind: ReferenceKind.prefix));
       return index;
     });
   }
 
   /**
+   * Compute the reference index which should be stored in a [EntityRef].
+   *
+   * If [linked] is true, and a new reference has to be created, the reference
+   * will only be stored in [linkedReferences].
+   */
+  int serializeReferenceForType(DartType type, bool linked) {
+    Element element = type.element;
+    LibraryElement dependentLibrary = element?.library;
+    if (dependentLibrary == null) {
+      assert(type.isDynamic || type.isVoid);
+      if (type is UndefinedTypeImpl) {
+        return serializeUnresolvedReference();
+      }
+      // Note: for a type which is truly `dynamic` or `void`, fall through to
+      // use [_getElementReferenceId].
+    }
+    return _getElementReferenceId(element, linked: linked);
+  }
+
+  /**
    * Serialize the given [typedefElement], creating an [UnlinkedTypedef].
    */
   UnlinkedTypedefBuilder serializeTypedef(
@@ -611,10 +651,7 @@
     b.nameOffset = typedefElement.nameOffset;
     b.typeParameters =
         typedefElement.typeParameters.map(serializeTypeParam).toList();
-    if (!typedefElement.returnType.isVoid) {
-      b.returnType =
-          serializeTypeRef(typedefElement.returnType, typedefElement);
-    }
+    b.returnType = serializeTypeRef(typedefElement.returnType, typedefElement);
     b.parameters = typedefElement.parameters.map(serializeParam).toList();
     b.documentationComment = serializeDocumentation(typedefElement);
     return b;
@@ -635,67 +672,37 @@
   }
 
   /**
-   * Serialize the given [type] into an [UnlinkedTypeRef].
+   * Serialize the given [type] into a [EntityRef].  If [slot] is provided,
+   * it should be included in the [EntityRef].  If [linked] is true, any
+   * references that are created will be populated into [linkedReferences] but
+   * [not [unlinkedReferences].
+   *
+   * [context] is the element within which the [EntityRef] will be
+   * interpreted; this is used to serialize type parameters.
    */
-  UnlinkedTypeRefBuilder serializeTypeRef(DartType type, Element context) {
-    UnlinkedTypeRefBuilder b = new UnlinkedTypeRefBuilder();
+  EntityRefBuilder serializeTypeRef(DartType type, Element context,
+      {bool linked: false, int slot}) {
+    EntityRefBuilder b = new EntityRefBuilder(slot: slot);
     if (type is TypeParameterType) {
       b.paramReference = findTypeParameterIndex(type, context);
     } else {
-      Element element = type.element;
-      LibraryElement dependentLibrary = element.library;
-      if (dependentLibrary == null) {
-        assert(type.isDynamic);
-        if (type is UndefinedTypeImpl) {
-          b.reference = serializeUnresolvedReference();
-        } else {
-          b.reference = serializeDynamicReference();
+      b.reference = serializeReferenceForType(type, linked);
+      List<DartType> typeArguments = getTypeArguments(type);
+      if (typeArguments != null) {
+        // Trailing type arguments of type 'dynamic' should be omitted.
+        int numArgsToSerialize = typeArguments.length;
+        while (numArgsToSerialize > 0 &&
+            typeArguments[numArgsToSerialize - 1].isDynamic) {
+          --numArgsToSerialize;
         }
-      } else {
-        b.reference = referenceMap.putIfAbsent(element, () {
-          assert(unlinkedReferences.length == prelinkedReferences.length);
-          CompilationUnitElement unitElement =
-              element.getAncestor((Element e) => e is CompilationUnitElement);
-          int unit = dependentLibrary.units.indexOf(unitElement);
-          assert(unit != -1);
-          int numTypeParameters = 0;
-          if (element is TypeParameterizedElement) {
-            numTypeParameters = element.typeParameters.length;
+        if (numArgsToSerialize > 0) {
+          List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
+          for (int i = 0; i < numArgsToSerialize; i++) {
+            serializedArguments.add(
+                serializeTypeRef(typeArguments[i], context, linked: linked));
           }
-          // Figure out a prefix that may be used to refer to the given type.
-          // TODO(paulberry): to avoid subtle relinking inconsistencies we
-          // should use the actual prefix from the AST (a given type may be
-          // reachable via multiple prefixes), but sadly, this information is
-          // not recorded in the element model.
-          int prefixReference = 0;
-          PrefixElement prefix = prefixMap[element];
-          if (prefix != null) {
-            prefixReference = serializePrefix(prefix);
-          }
-          int index = unlinkedReferences.length;
-          unlinkedReferences.add(encodeUnlinkedReference(
-              name: element.name, prefixReference: prefixReference));
-          prelinkedReferences.add(encodePrelinkedReference(
-              dependency: serializeDependency(dependentLibrary),
-              kind: element is FunctionTypeAliasElement
-                  ? PrelinkedReferenceKind.typedef
-                  : PrelinkedReferenceKind.classOrEnum,
-              unit: unit,
-              numTypeParameters: numTypeParameters));
-          return index;
-        });
-      }
-      List<DartType> typeArguments;
-      if (type is InterfaceType) {
-        typeArguments = type.typeArguments;
-      } else if (type is FunctionType) {
-        typeArguments = type.typeArguments;
-      }
-      if (typeArguments != null &&
-          typeArguments.any((DartType argument) => !argument.isDynamic)) {
-        b.typeArguments = typeArguments
-            .map((DartType t) => serializeTypeRef(t, context))
-            .toList();
+          b.typeArguments = serializedArguments;
+        }
       }
     }
     return b;
@@ -703,7 +710,7 @@
 
   /**
    * Return the index of the entry in the references table
-   * ([UnlinkedLibrary.references] and [PrelinkedLibrary.references]) used for
+   * ([UnlinkedLibrary.references] and [LinkedLibrary.references]) used for
    * unresolved references.  A new entry is added to the table if necessary to
    * satisfy the request.
    */
@@ -713,11 +720,12 @@
     // the element model.  For the moment we use a name that can't possibly
     // ever exist.
     if (unresolvedReferenceIndex == null) {
-      assert(unlinkedReferences.length == prelinkedReferences.length);
+      assert(unlinkedReferences.length == linkedReferences.length);
       unresolvedReferenceIndex = unlinkedReferences.length;
-      unlinkedReferences.add(encodeUnlinkedReference(name: '*unresolved*'));
-      prelinkedReferences.add(
-          encodePrelinkedReference(kind: PrelinkedReferenceKind.unresolved));
+      unlinkedReferences
+          .add(new UnlinkedReferenceBuilder(name: '*unresolved*'));
+      linkedReferences
+          .add(new LinkedReferenceBuilder(kind: ReferenceKind.unresolved));
     }
     return unresolvedReferenceIndex;
   }
@@ -729,12 +737,390 @@
     UnlinkedVariableBuilder b = new UnlinkedVariableBuilder();
     b.name = variable.name;
     b.nameOffset = variable.nameOffset;
-    b.type = serializeTypeRef(variable.type, variable);
+    if (!variable.hasImplicitType) {
+      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;
     b.documentationComment = serializeDocumentation(variable);
+    if (variable.isConst && variable is ConstVariableElement) {
+      ConstVariableElement constVariable = variable as ConstVariableElement;
+      Expression initializer = constVariable.constantInitializer;
+      if (initializer != null) {
+        b.constExpr = serializeConstExpr(initializer);
+      }
+    }
+    if (b.isFinal || b.isConst) {
+      b.propagatedTypeSlot = storeLinkedType(variable.propagatedType, variable);
+    } else {
+      // Variable is not propagable.
+      assert(variable.propagatedType == null);
+    }
+    if (variable.hasImplicitType &&
+        (variable.initializer != null || !variable.isStatic)) {
+      b.inferredTypeSlot = storeInferredType(variable.type, variable);
+    }
     return b;
   }
+
+  /**
+   * Create a slot id for the given [type] (which is an inferred type).  If
+   * strong mode is enabled and [type] is not `dynamic`, it is stored in
+   * [linkedTypes] so that once the compilation unit has been fully visited, it
+   * will be serialized into [LinkedUnit.types].
+   *
+   * [context] is the element within which the slot id will appear; this is
+   * used to serialize type parameters.
+   */
+  int storeInferredType(DartType type, Element context) {
+    return storeLinkedType(
+        librarySerializer.strongMode && !type.isDynamic ? type : null, context);
+  }
+
+  /**
+   * Create a slot id for the given [type] (which may be either a propagated
+   * type or an inferred type).  If [type] is not `null`, it is stored in
+   * [linkedTypes] so that once the compilation unit has been fully visited,
+   * it will be serialized to [LinkedUnit.types].
+   *
+   * [context] is the element within which the slot id will appear; this is
+   * used to serialize type parameters.
+   */
+  int storeLinkedType(DartType type, Element context) {
+    int slot = ++numSlots;
+    if (type != null) {
+      deferredLinkedTypes
+          .add(() => serializeTypeRef(type, context, linked: true, slot: slot));
+    }
+    return slot;
+  }
+
+  int _getElementReferenceId(Element element, {bool linked: false}) {
+    return referenceMap.putIfAbsent(element, () {
+      if (element is ConstructorElement && element.displayName.isEmpty) {
+        return _getElementReferenceId(element.enclosingElement, linked: linked);
+      }
+      if (element is MethodElement && !element.isStatic) {
+        throw new StateError('Only static methods can be serialized.');
+      }
+      if (element is PropertyAccessorElement) {
+        Element enclosing = element.enclosingElement;
+        if (!(enclosing is CompilationUnitElement || element.isStatic)) {
+          throw new StateError(
+              'Only top-level or static property accessors can be serialized.');
+        }
+      }
+      LibraryElement dependentLibrary = element?.library;
+      int unit;
+      if (dependentLibrary == null) {
+        assert(element == librarySerializer.typeProvider.dynamicType.element ||
+            element == null);
+        unit = 0;
+        dependentLibrary = librarySerializer.libraryElement;
+      } else {
+        CompilationUnitElement unitElement =
+            element.getAncestor((Element e) => e is CompilationUnitElement);
+        unit = dependentLibrary.units.indexOf(unitElement);
+        assert(unit != -1);
+      }
+      int numTypeParameters = 0;
+      if (element is TypeParameterizedElement) {
+        numTypeParameters = element.typeParameters.length;
+      }
+      LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder(
+          dependency: librarySerializer.serializeDependency(dependentLibrary),
+          kind: _getReferenceKind(element),
+          unit: unit,
+          numTypeParameters: numTypeParameters);
+      String name = element == null ? 'void' : element.name;
+      if (linked) {
+        linkedReference.name = name;
+      } else {
+        assert(unlinkedReferences.length == linkedReferences.length);
+        int prefixReference = 0;
+        Element enclosing = element?.enclosingElement;
+        if (enclosing == null || enclosing is CompilationUnitElement) {
+          // Figure out a prefix that may be used to refer to the given element.
+          // TODO(paulberry): to avoid subtle relinking inconsistencies we
+          // should use the actual prefix from the AST (a given type may be
+          // reachable via multiple prefixes), but sadly, this information is
+          // not recorded in the element model.
+          PrefixElement prefix = librarySerializer.prefixMap[element];
+          if (prefix != null) {
+            prefixReference = serializePrefix(prefix);
+          }
+        } else {
+          prefixReference = _getElementReferenceId(enclosing, linked: linked);
+        }
+        unlinkedReferences.add(new UnlinkedReferenceBuilder(
+            name: name, prefixReference: prefixReference));
+      }
+      int index = linkedReferences.length;
+      linkedReferences.add(linkedReference);
+      return index;
+    });
+  }
+
+  int _getLengthPropertyReference(int prefix) {
+    assert(unlinkedReferences.length == linkedReferences.length);
+    int index = linkedReferences.length;
+    unlinkedReferences.add(
+        new UnlinkedReferenceBuilder(name: 'length', prefixReference: prefix));
+    LinkedReferenceBuilder linkedReference =
+        new LinkedReferenceBuilder(kind: ReferenceKind.length);
+    linkedReferences.add(linkedReference);
+    return index;
+  }
+}
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single constant [Expression].
+ */
+class _ConstExprSerializer extends AbstractConstExprSerializer {
+  final _CompilationUnitSerializer serializer;
+
+  _ConstExprSerializer(this.serializer);
+
+  @override
+  EntityRefBuilder serializeConstructorName(ConstructorName constructor) {
+    ConstructorElement element = constructor.staticElement;
+    assert(element != null);
+    int referenceId = serializer._getElementReferenceId(element);
+    return new EntityRefBuilder(reference: referenceId);
+  }
+
+  EntityRefBuilder serializeIdentifier(Identifier identifier) {
+    Element element = identifier.staticElement;
+    assert(element != null);
+    // The only supported instance property accessor - `length`.
+    if (identifier is PrefixedIdentifier &&
+        element is PropertyAccessorElement &&
+        !element.isStatic) {
+      assert(element.name == 'length');
+      Element prefixElement = identifier.prefix.staticElement;
+      int prefixRef = serializer._getElementReferenceId(prefixElement);
+      int lengthRef = serializer._getLengthPropertyReference(prefixRef);
+      return new EntityRefBuilder(reference: lengthRef);
+    }
+    return new EntityRefBuilder(
+        reference: serializer._getElementReferenceId(element));
+  }
+
+  @override
+  EntityRefBuilder serializePropertyAccess(PropertyAccess access) {
+    Element element = access.propertyName.staticElement;
+    assert(element != null);
+    // The only supported instance property accessor - `length`.
+    Expression target = access.target;
+    if (target is Identifier &&
+        element is PropertyAccessorElement &&
+        !element.isStatic) {
+      assert(element.name == 'length');
+      Element prefixElement = target.staticElement;
+      int prefixRef = serializer._getElementReferenceId(prefixElement);
+      int lengthRef = serializer._getLengthPropertyReference(prefixRef);
+      return new EntityRefBuilder(reference: lengthRef);
+    }
+    return new EntityRefBuilder(
+        reference: serializer._getElementReferenceId(element));
+  }
+
+  @override
+  EntityRefBuilder serializeType(TypeName typeName) {
+    DartType type = typeName != null ? typeName.type : DynamicTypeImpl.instance;
+    return serializer.serializeTypeRef(type, null);
+  }
+}
+
+/**
+ * Instances of this class keep track of intermediate state during
+ * serialization of a single library.
+ */
+class _LibrarySerializer {
+  /**
+   * The library to be serialized.
+   */
+  final LibraryElement libraryElement;
+
+  /**
+   * The type provider.  This is used to locate the library for `dart:core`.
+   */
+  final TypeProvider typeProvider;
+
+  /**
+   * Indicates whether the element model being serialized was analyzed using
+   * strong mode.
+   */
+  final bool strongMode;
+
+  /**
+   * Map from [LibraryElement] to the index of the entry in the "dependency
+   * table" that refers to it.
+   */
+  final Map<LibraryElement, int> dependencyMap = <LibraryElement, int>{};
+
+  /**
+   * The "dependency table".  This is the list of objects which should be
+   * written to [LinkedLibrary.dependencies].
+   */
+  final List<LinkedDependencyBuilder> dependencies =
+      <LinkedDependencyBuilder>[];
+
+  /**
+   * The linked portion of the "imports table".  This is the list of ints
+   * which should be written to [LinkedLibrary.imports].
+   */
+  final List<int> linkedImports = <int>[];
+
+  /**
+   * Set of libraries which have been seen so far while visiting the transitive
+   * closure of exports.
+   */
+  final Set<LibraryElement> librariesAddedToTransitiveExportClosure =
+      new Set<LibraryElement>();
+
+  /**
+   * Map from imported element to the prefix which may be used to refer to that
+   * element; elements for which no prefix is needed are absent from this map.
+   */
+  final Map<Element, PrefixElement> prefixMap = <Element, PrefixElement>{};
+
+  /**
+   * List of serializers for the compilation units constituting this library.
+   */
+  final List<_CompilationUnitSerializer> compilationUnitSerializers =
+      <_CompilationUnitSerializer>[];
+
+  _LibrarySerializer(this.libraryElement, this.typeProvider, this.strongMode) {
+    dependencies.add(new LinkedDependencyBuilder());
+    dependencyMap[libraryElement] = 0;
+  }
+
+  /**
+   * Retrieve a list of the URIs for the compilation units in the library.
+   */
+  List<String> get unitUris => compilationUnitSerializers
+      .map((_CompilationUnitSerializer s) => s.unitUri)
+      .toList();
+
+  /**
+   * Retrieve a list of the [UnlinkedUnitBuilder]s for the compilation units in
+   * the library.
+   */
+  List<UnlinkedUnitBuilder> get unlinkedUnits => compilationUnitSerializers
+      .map((_CompilationUnitSerializer s) => s.unlinkedUnit)
+      .toList();
+
+  /**
+   * Add [exportedLibrary] (and the transitive closure of all libraries it
+   * exports) to the dependency table ([LinkedLibrary.dependencies]).
+   */
+  void addTransitiveExportClosure(LibraryElement exportedLibrary) {
+    if (librariesAddedToTransitiveExportClosure.add(exportedLibrary)) {
+      serializeDependency(exportedLibrary);
+      for (LibraryElement transitiveExport
+          in exportedLibrary.exportedLibraries) {
+        addTransitiveExportClosure(transitiveExport);
+      }
+    }
+  }
+
+  /**
+   * Fill in [prefixMap] using information from [libraryElement.imports].
+   */
+  void computePrefixMap() {
+    for (ImportElement import in libraryElement.imports) {
+      if (import.prefix == null) {
+        continue;
+      }
+      import.importedLibrary.exportNamespace.definedNames
+          .forEach((String name, Element e) {
+        if (new NameFilter.forNamespaceCombinators(import.combinators)
+            .accepts(name)) {
+          prefixMap[e] = import.prefix;
+        }
+      });
+    }
+  }
+
+  /**
+   * Return the index of the entry in the dependency table
+   * ([LinkedLibrary.dependencies]) for the given [dependentLibrary].  A new
+   * entry is added to the table if necessary to satisfy the request.
+   */
+  int serializeDependency(LibraryElement dependentLibrary) {
+    return dependencyMap.putIfAbsent(dependentLibrary, () {
+      int index = dependencies.length;
+      List<String> parts = dependentLibrary.parts
+          .map((CompilationUnitElement e) => e.source.uri.toString())
+          .toList();
+      dependencies.add(new LinkedDependencyBuilder(
+          uri: dependentLibrary.source.uri.toString(), parts: parts));
+      return index;
+    });
+  }
+
+  /**
+   * Serialize the whole library element into a [LinkedLibrary].  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].
+   */
+  LinkedLibraryBuilder serializeLibrary() {
+    computePrefixMap();
+    LinkedLibraryBuilder pb = new LinkedLibraryBuilder();
+    for (ExportElement exportElement in libraryElement.exports) {
+      addTransitiveExportClosure(exportElement.exportedLibrary);
+    }
+    for (ImportElement importElement in libraryElement.imports) {
+      addTransitiveExportClosure(importElement.importedLibrary);
+      linkedImports.add(serializeDependency(importElement.importedLibrary));
+    }
+    compilationUnitSerializers.add(new _CompilationUnitSerializer(
+        this, libraryElement.definingCompilationUnit, 0));
+    for (int i = 0; i < libraryElement.parts.length; i++) {
+      compilationUnitSerializers.add(
+          new _CompilationUnitSerializer(this, libraryElement.parts[i], i + 1));
+    }
+    for (_CompilationUnitSerializer compilationUnitSerializer
+        in compilationUnitSerializers) {
+      compilationUnitSerializer.addCompilationUnitElements();
+    }
+    pb.units = compilationUnitSerializers
+        .map((_CompilationUnitSerializer s) => s.linkedUnit)
+        .toList();
+    pb.dependencies = dependencies;
+    pb.numPrelinkedDependencies = dependencies.length;
+    for (_CompilationUnitSerializer compilationUnitSerializer
+        in compilationUnitSerializers) {
+      compilationUnitSerializer.createLinkedTypes();
+    }
+    pb.importDependencies = linkedImports;
+    List<String> exportedNames =
+        libraryElement.exportNamespace.definedNames.keys.toList();
+    exportedNames.sort();
+    List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
+    for (String name in exportedNames) {
+      if (libraryElement.publicNamespace.definedNames.containsKey(name)) {
+        continue;
+      }
+      Element element = libraryElement.exportNamespace.get(name);
+      LibraryElement dependentLibrary = element.library;
+      CompilationUnitElement unitElement =
+          element.getAncestor((Element e) => e is CompilationUnitElement);
+      int unit = dependentLibrary.units.indexOf(unitElement);
+      assert(unit != -1);
+      ReferenceKind kind = _getReferenceKind(element);
+      exportNames.add(new LinkedExportNameBuilder(
+          name: name,
+          dependency: serializeDependency(dependentLibrary),
+          unit: unit,
+          kind: kind));
+    }
+    pb.exportNames = exportNames;
+    return pb;
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 4d9b9fe..95c33f4 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -10,12 +10,15 @@
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart' show Source, SourceKind;
+import 'package:analyzer/src/generated/source.dart'
+    show DartUriResolver, Source, SourceFactory, SourceKind;
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/task/dart.dart'
     show
+        CONSTANT_VALUE,
         LIBRARY_ELEMENT1,
         LIBRARY_ELEMENT2,
         LIBRARY_ELEMENT3,
@@ -32,32 +35,40 @@
 import 'package:analyzer/task/model.dart'
     show AnalysisTarget, ResultDescriptor, TargetedResult;
 
-/**
- * An [SdkAnalysisContext] for Dart SDK with a summary [SdkBundle].
- */
-class SummarySdkAnalysisContext extends SdkAnalysisContext {
+class SdkSummaryResultProvider implements SummaryResultProvider {
+  final InternalAnalysisContext context;
   final SdkBundle bundle;
   final SummaryTypeProvider typeProvider = new SummaryTypeProvider();
 
+  @override
   SummaryResynthesizer resynthesizer;
 
-  SummarySdkAnalysisContext(this.bundle);
+  SdkSummaryResultProvider(this.context, this.bundle) {
+    resynthesizer = new SdkSummaryResynthesizer(
+        context, typeProvider, context.sourceFactory, bundle);
+    _buildCoreLibrary();
+    _buildAsyncLibrary();
+    resynthesizer.finalizeCoreAsyncLibraries();
+    context.typeProvider = typeProvider;
+  }
 
   @override
-  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
-    if (resynthesizer == null) {
-      resynthesizer = new SummaryResynthesizer(this, typeProvider,
-          _getPrelinkedSummary, _getUnlinkedSummary, sourceFactory);
-      _buildCoreLibrary();
-      _buildAsyncLibrary();
-    }
+  bool compute(CacheEntry entry, ResultDescriptor result) {
     if (result == TYPE_PROVIDER) {
+//      print('SummarySdkAnalysisContext: $result');
       entry.setValue(result, typeProvider, TargetedResult.EMPTY_LIST);
       return true;
     }
     AnalysisTarget target = entry.target;
-//    print('SummarySdkAnalysisContext: $result of $target');
+    // TODO(scheglov) we don't actually update "evaluationResult" yet
+    if (result == CONSTANT_VALUE) {
+      if (target.source != null && target.source.isInSystemLibrary) {
+        entry.setValue(result, target, TargetedResult.EMPTY_LIST);
+        return true;
+      }
+    }
     if (target is Source && target.isInSystemLibrary) {
+//      print('SummarySdkAnalysisContext: $result of $target');
       if (result == LIBRARY_ELEMENT1 ||
           result == LIBRARY_ELEMENT2 ||
           result == LIBRARY_ELEMENT3 ||
@@ -80,12 +91,9 @@
         return true;
       } else if (result == SOURCE_KIND) {
         String uri = target.uri.toString();
-        if (bundle.prelinkedLibraryUris.contains(uri)) {
-          entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
-          return true;
-        }
-        if (bundle.unlinkedUnitUris.contains(uri)) {
-          entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+        SourceKind kind = _getSourceKind(uri);
+        if (kind != null) {
+          entry.setValue(result, kind, TargetedResult.EMPTY_LIST);
           return true;
         }
         return false;
@@ -106,23 +114,65 @@
     typeProvider.initializeCore(library);
   }
 
-  PrelinkedLibrary _getPrelinkedSummary(String uri) {
-    for (int i = 0; i < bundle.prelinkedLibraryUris.length; i++) {
-      if (bundle.prelinkedLibraryUris[i] == uri) {
-        return bundle.prelinkedLibraries[i];
-      }
+  /**
+   * Return the [SourceKind] of the given [uri] or `null` if it is unknown.
+   */
+  SourceKind _getSourceKind(String uri) {
+    if (bundle.linkedLibraryUris.contains(uri)) {
+      return SourceKind.LIBRARY;
     }
-    throw new StateError('Unable to find prelinked summary for $uri');
+    if (bundle.unlinkedUnitUris.contains(uri)) {
+      return SourceKind.PART;
+    }
+    return null;
+  }
+}
+
+/**
+ * The implementation of [SummaryResynthesizer] for Dart SDK.
+ */
+class SdkSummaryResynthesizer extends SummaryResynthesizer {
+  final SdkBundle bundle;
+  final Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
+  final Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{};
+
+  SdkSummaryResynthesizer(AnalysisContext context, TypeProvider typeProvider,
+      SourceFactory sourceFactory, this.bundle)
+      : super(null, context, typeProvider, sourceFactory, false) {
+    // TODO(paulberry): we always resynthesize the summary in weak mode.  Is
+    // this ok?
+    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+      unlinkedSummaries[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+    }
+    for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+      linkedSummaries[bundle.linkedLibraryUris[i]] = bundle.linkedLibraries[i];
+    }
   }
 
-  UnlinkedUnit _getUnlinkedSummary(String uri) {
-    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-      if (bundle.unlinkedUnitUris[i] == uri) {
-        return bundle.unlinkedUnits[i];
-      }
-    }
-    throw new StateError('Unable to find unlinked summary for $uri');
+  @override
+  LinkedLibrary getLinkedSummary(String uri) {
+    return linkedSummaries[uri];
   }
+
+  @override
+  UnlinkedUnit getUnlinkedSummary(String uri) {
+    return unlinkedSummaries[uri];
+  }
+
+  @override
+  bool hasLibrarySummary(String uri) {
+    return uri.startsWith('dart:');
+  }
+}
+
+/**
+ * Provider for analysis results.
+ */
+abstract class SummaryResultProvider extends ResultProvider {
+  /**
+   * The [SummaryResynthesizer] of this context, maybe `null`.
+   */
+  SummaryResynthesizer get resynthesizer;
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index df4e7ac..2c99cd2 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -6,11 +6,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/ast/utilities.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/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -1226,10 +1229,24 @@
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     //
+    // Build the enum members if they have not already been created.
+    //
+    EnumDeclaration findFirstEnum() {
+      for (CompilationUnitMember member in unit.declarations) {
+        if (member is EnumDeclaration) {
+          return member;
+        }
+      }
+      return null;
+    }
+    EnumDeclaration firstEnum = findFirstEnum();
+    if (firstEnum != null && firstEnum.element.accessors.isEmpty) {
+      EnumMemberBuilder builder = new EnumMemberBuilder(typeProvider);
+      unit.accept(builder);
+    }
+    //
     // Record outputs.
     //
-    EnumMemberBuilder builder = new EnumMemberBuilder(typeProvider);
-    unit.accept(builder);
     outputs[CREATED_RESOLVED_UNIT2] = true;
     outputs[RESOLVED_UNIT2] = unit;
   }
@@ -1395,7 +1412,6 @@
     //
     // Update "part" directives.
     //
-    LibraryDirective libraryDirective = null;
     LibraryIdentifier libraryNameNode = null;
     String partsLibraryName = _UNKNOWN_LIBRARY_NAME;
     bool hasPartDirective = false;
@@ -1406,11 +1422,8 @@
         <CompilationUnitElementImpl>[];
     for (Directive directive in definingCompilationUnit.directives) {
       if (directive is LibraryDirective) {
-        if (libraryDirective == null) {
-          libraryDirective = directive;
-          libraryNameNode = directive.name;
-          directivesToResolve.add(directive);
-        }
+        libraryNameNode = directive.name;
+        directivesToResolve.add(directive);
       } else if (directive is PartDirective) {
         PartDirective partDirective = directive;
         StringLiteral partUri = partDirective.uri;
@@ -1488,12 +1501,13 @@
     for (Directive directive in directivesToResolve) {
       directive.element = libraryElement;
     }
-    if (sourcedCompilationUnits.isNotEmpty) {
-      _patchTopLevelAccessors(libraryElement);
+    BuildLibraryElementUtils.patchTopLevelAccessors(libraryElement);
+    // set the library documentation to the docs associated with the first
+    // directive in the compilation unit.
+    if (definingCompilationUnit.directives.isNotEmpty) {
+      _setDoc(libraryElement, definingCompilationUnit.directives.first);
     }
-    if (libraryDirective != null) {
-      _setDoc(libraryElement, libraryDirective);
-    }
+
     //
     // Record outputs.
     //
@@ -1503,25 +1517,6 @@
   }
 
   /**
-   * Add all of the non-synthetic [getters] and [setters] defined in the given
-   * [unit] that have no corresponding accessor to one of the given collections.
-   */
-  void _collectAccessors(Map<String, PropertyAccessorElement> getters,
-      List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
-    for (PropertyAccessorElement accessor in unit.accessors) {
-      if (accessor.isGetter) {
-        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
-          getters[accessor.displayName] = accessor;
-        }
-      } else {
-        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
-          setters.add(accessor);
-        }
-      }
-    }
-  }
-
-  /**
    * Return the top-level [FunctionElement] entry point, or `null` if the given
    * [element] does not define an entry point.
    */
@@ -1553,33 +1548,6 @@
   }
 
   /**
-   * Look through all of the compilation units defined for the given [library],
-   * looking for getters and setters that are defined in different compilation
-   * units but that have the same names. If any are found, make sure that they
-   * have the same variable element.
-   */
-  void _patchTopLevelAccessors(LibraryElementImpl library) {
-    HashMap<String, PropertyAccessorElement> getters =
-        new HashMap<String, PropertyAccessorElement>();
-    List<PropertyAccessorElement> setters = <PropertyAccessorElement>[];
-    _collectAccessors(getters, setters, library.definingCompilationUnit);
-    for (CompilationUnitElement unit in library.parts) {
-      _collectAccessors(getters, setters, unit);
-    }
-    for (PropertyAccessorElement setter in setters) {
-      PropertyAccessorElement getter = getters[setter.displayName];
-      if (getter != null) {
-        TopLevelVariableElementImpl variable = getter.variable;
-        TopLevelVariableElementImpl setterVariable = setter.variable;
-        CompilationUnitElementImpl setterUnit = setterVariable.enclosingElement;
-        setterUnit.replaceTopLevelVariable(setterVariable, variable);
-        variable.setter = setter;
-        (setter as PropertyAccessorElementImpl).variable = variable;
-      }
-    }
-  }
-
-  /**
    * If the given [node] has a documentation comment, remember its content
    * and range into the given [element].
    */
@@ -1765,6 +1733,11 @@
     //
     // Record outputs.
     //
+    if (!context.analysisOptions.enableAsync) {
+      AnalysisContextImpl contextImpl = context;
+      asyncLibrary = contextImpl.createMockAsyncLib(coreLibrary);
+      asyncNamespace = asyncLibrary.publicNamespace;
+    }
     TypeProvider typeProvider =
         new TypeProviderImpl.forNamespaces(coreNamespace, asyncNamespace);
     (context as InternalAnalysisContext).typeProvider = typeProvider;
@@ -3257,14 +3230,7 @@
       if (newType == null || newType.isBottom) {
         newType = typeProvider.dynamicType;
       }
-      variable.type = newType;
-      (variable.initializer as ExecutableElementImpl).returnType = newType;
-      if (variable is PropertyInducingElementImpl) {
-        setReturnType(variable.getter, newType);
-        if (!variable.isFinal && !variable.isConst) {
-          setParameterType(variable.setter, newType);
-        }
-      }
+      setFieldType(variable, newType);
     } else {
       // TODO(brianwilkerson) For now we simply don't infer any type for
       // variables or fields involved in a cycle. We could try to be smarter
@@ -3591,6 +3557,16 @@
     HashSet<Source> importedSourceSet =
         new HashSet.from(explicitlyImportedSourceSet);
     Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+    if (coreLibrarySource == null) {
+      String message;
+      DartSdk sdk = context.sourceFactory.dartSdk;
+      if (sdk == null) {
+        message = 'Could not resolve "dart:core": SDK not defined';
+      } else {
+        message = 'Could not resolve "dart:core": SDK incorrectly configured';
+      }
+      throw new AnalysisException(message);
+    }
     importedSourceSet.add(coreLibrarySource);
     //
     // Compute kind.
@@ -5087,7 +5063,8 @@
       'ScanDartTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[LINE_INFO, SCAN_ERRORS, TOKEN_STREAM]);
+      <ResultDescriptor>[LINE_INFO, SCAN_ERRORS, TOKEN_STREAM],
+      suitabilityFor: suitabilityFor);
 
   /**
    * Initialize a newly created task to access the content of the source
@@ -5183,6 +5160,21 @@
       AnalysisContext context, AnalysisTarget target) {
     return new ScanDartTask(context, target);
   }
+
+  /**
+   * Return an indication of how suitable this task is for the given [target].
+   */
+  static TaskSuitability suitabilityFor(AnalysisTarget target) {
+    if (target is Source) {
+      if (target.shortName.endsWith(AnalysisEngine.SUFFIX_DART)) {
+        return TaskSuitability.HIGHEST;
+      }
+      return TaskSuitability.LOWEST;
+    } else if (target is DartScript) {
+      return TaskSuitability.HIGHEST;
+    }
+    return TaskSuitability.NONE;
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index db9cd1d..0f3b523 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -154,7 +154,7 @@
   /**
    * Create a work order that will produce the given [result] for the given
    * [target]. Return the work order that was created, or `null` if the result
-   * has already been computed.
+   * has either already been computed or cannot be computed.
    */
   WorkOrder createWorkOrderForResult(
       AnalysisTarget target, ResultDescriptor result) {
@@ -166,6 +166,9 @@
       return null;
     }
     TaskDescriptor taskDescriptor = taskManager.findTask(target, result);
+    if (taskDescriptor == null) {
+      return null;
+    }
     try {
       WorkItem workItem =
           new WorkItem(context, target, taskDescriptor, result, 0, null);
@@ -709,11 +712,22 @@
           try {
             TaskDescriptor descriptor =
                 taskManager.findTask(inputTarget, inputResult);
+            if (descriptor == null) {
+              throw new AnalysisException(
+                  'Cannot find task to build $inputResult for $inputTarget');
+            }
             return new WorkItem(context, inputTarget, descriptor, inputResult,
                 level + 1, workOrder);
           } on AnalysisException catch (exception, stackTrace) {
             this.exception = new CaughtException(exception, stackTrace);
             return null;
+          } catch (exception, stackTrace) {
+            this.exception = new CaughtException(
+                throw new AnalysisException(
+                    'Cannot create work order to build $inputResult for $inputTarget',
+                    exception),
+                stackTrace);
+            return null;
           }
         }
       } else {
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index b6a771a..01cdd5a 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -279,7 +279,8 @@
       'ParseHtmlTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[HTML_DOCUMENT, HTML_DOCUMENT_ERRORS, LINE_INFO]);
+      <ResultDescriptor>[HTML_DOCUMENT, HTML_DOCUMENT_ERRORS, LINE_INFO],
+      suitabilityFor: suitabilityFor);
 
   /**
    * Initialize a newly created task to access the content of the source
@@ -358,6 +359,20 @@
   }
 
   /**
+   * Return an indication of how suitable this task is for the given [target].
+   */
+  static TaskSuitability suitabilityFor(AnalysisTarget target) {
+    if (target is Source) {
+      String name = target.shortName;
+      if (name.endsWith(AnalysisEngine.SUFFIX_HTML) ||
+          name.endsWith(AnalysisEngine.SUFFIX_HTM)) {
+        return TaskSuitability.HIGHEST;
+      }
+    }
+    return TaskSuitability.NONE;
+  }
+
+  /**
    * Compute [LineInfo] for the given [content].
    */
   static LineInfo _computeLineInfo(String content) {
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 07550c5..05029d3 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -6,10 +6,11 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/lib/src/task/manager.dart b/pkg/analyzer/lib/src/task/manager.dart
index eebc084..c8252fa 100644
--- a/pkg/analyzer/lib/src/task/manager.dart
+++ b/pkg/analyzer/lib/src/task/manager.dart
@@ -83,7 +83,7 @@
       throw new AnalysisException(
           'No tasks registered to compute $result for $target');
     }
-    return _findBestTask(descriptors);
+    return _findBestTask(descriptors, target);
   }
 
   /**
@@ -104,11 +104,20 @@
 
   /**
    * Given a list of task [descriptors] that can be used to compute some
-   * unspecified result, return the descriptor that will compute the result with
-   * the least amount of work.
+   * unspecified result for the given [target], return the descriptor that
+   * should be used to compute the result.
    */
-  TaskDescriptor _findBestTask(List<TaskDescriptor> descriptors) {
-    // TODO(brianwilkerson) Improve this implementation.
-    return descriptors[0];
+  TaskDescriptor _findBestTask(
+      List<TaskDescriptor> descriptors, AnalysisTarget target) {
+    TaskDescriptor best = null;
+    for (TaskDescriptor descriptor in descriptors) {
+      TaskSuitability suitability = descriptor.suitabilityFor(target);
+      if (suitability == TaskSuitability.HIGHEST) {
+        return descriptor;
+      } else if (best == null && suitability == TaskSuitability.LOWEST) {
+        best = descriptor;
+      }
+    }
+    return best;
   }
 }
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 8eaa838..56e2827 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -126,13 +126,23 @@
   final List<ResultDescriptor> results;
 
   /**
+   * The function used to determine whether the described task is suitable for
+   * a given target.
+   */
+  final SuitabilityFor _suitabilityFor;
+
+  /**
    * Initialize a newly created task descriptor to have the given [name] and to
-   * describe a task that takes the inputs built using the given [createTaskInputs],
-   * and produces the given [results]. The [buildTask] will be used to create
-   * the instance of [AnalysisTask] thusly described.
+   * describe a task that takes the inputs built using the given [inputBuilder],
+   * and produces the given [results]. The [buildTask] function will be used to
+   * create the instance of [AnalysisTask] being described. If provided, the
+   * [isAppropriateFor] function will be used to determine whether the task can
+   * be used on a specific target.
    */
   TaskDescriptorImpl(
-      this.name, this.buildTask, this.createTaskInputs, this.results);
+      this.name, this.buildTask, this.createTaskInputs, this.results,
+      {SuitabilityFor suitabilityFor})
+      : _suitabilityFor = suitabilityFor ?? _defaultSuitability;
 
   @override
   AnalysisTask createTask(AnalysisContext context, AnalysisTarget target,
@@ -143,5 +153,16 @@
   }
 
   @override
+  TaskSuitability suitabilityFor(AnalysisTarget target) =>
+      _suitabilityFor(target);
+
+  @override
   String toString() => name;
+
+  /**
+   * The function that will be used to determine the suitability of a task if no
+   * other function is provided.
+   */
+  static TaskSuitability _defaultSuitability(AnalysisTarget target) =>
+      TaskSuitability.LOWEST;
 }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 6775408..4a6483c 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -202,7 +202,8 @@
       'GenerateOptionsErrorsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[ANALYSIS_OPTIONS_ERRORS, LINE_INFO]);
+      <ResultDescriptor>[ANALYSIS_OPTIONS_ERRORS, LINE_INFO],
+      suitabilityFor: suitabilityFor);
 
   final AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
 
@@ -257,6 +258,17 @@
   static GenerateOptionsErrorsTask createTask(
           AnalysisContext context, AnalysisTarget target) =>
       new GenerateOptionsErrorsTask(context, target);
+
+  /**
+   * Return an indication of how suitable this task is for the given [target].
+   */
+  static TaskSuitability suitabilityFor(AnalysisTarget target) {
+    if (target is Source &&
+        target.shortName == AnalysisEngine.ANALYSIS_OPTIONS_FILE) {
+      return TaskSuitability.HIGHEST;
+    }
+    return TaskSuitability.NONE;
+  }
 }
 
 /// Validates `analyzer` language configuration options.
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 29857b0..a67251e7 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -7,10 +7,11 @@
 library analyzer.src.task.strong.checker;
 
 import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.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';
@@ -129,14 +130,9 @@
       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);
+        // We found an argument mismatch, the analyzer will report this too,
+        // so no need to insert an error for this here.
+        continue;
       }
       DartType expectedType = _elementType(element);
       if (expectedType == null) expectedType = DynamicTypeImpl.instance;
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index cf4f822..4f39f6b 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -8,10 +8,10 @@
 // refactored to fit into analyzer.
 library analyzer.src.task.strong.info;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 
@@ -95,13 +95,15 @@
             baseType.isAssignableTo(_cast.toType)));
   }
 
-  @override List<Object> get arguments => [node, baseType, convertedType];
+  @override
+  List<Object> get arguments => [baseType, convertedType];
 
   Cast get cast => _cast;
 
   DartType get convertedType => _cast.toType;
-  @override String get message => '{0} ({1}) will need runtime check '
-      'to cast to type {2}';
+
+  @override
+  String get message => 'Unsound implicit cast from {0} to {1}';
 
   // Factory to create correct DownCast variant.
   static StaticInfo create(
@@ -122,20 +124,18 @@
     }
 
     // Inference "casts":
-    if (expression is Literal) {
+    if (expression is Literal || expression is FunctionExpression) {
       // fromT should be an exact type - this will almost certainly fail at
       // runtime.
       return new StaticTypeError(rules, expression, toT, reason: reason);
     }
-    if (expression is FunctionExpression) {
-      // fromT should be an exact type - this will almost certainly fail at
-      // runtime.
-      return new UninferredClosure(rules, expression, cast);
-    }
     if (expression is InstanceCreationExpression) {
-      // fromT should be an exact type - this will almost certainly fail at
-      // runtime.
-      return new StaticTypeError(rules, expression, toT, reason: reason);
+      ConstructorElement e = expression.staticElement;
+      if (e == null || !e.isFactory) {
+        // fromT should be an exact type - this will almost certainly fail at
+        // runtime.
+        return new StaticTypeError(rules, expression, toT, reason: reason);
+      }
     }
 
     // TODO(vsm): Change this to an assert when we have generic methods and
@@ -292,9 +292,11 @@
       TypeSystem rules, Expression expression, this._type)
       : super(rules, expression);
 
-  @override List get arguments => [node, type];
+  @override
+  List get arguments => [node, type];
   DartType get convertedType => type;
-  @override String get message => '{0} has inferred type {1}';
+  @override
+  String get message => '{0} has inferred type {1}';
   DartType get type => _type;
 
   toErrorCode() => new HintCode(name, message);
@@ -370,7 +372,8 @@
         fromMixin = node.parent is WithClause,
         super(node);
 
-  @override List<Object> get arguments =>
+  @override
+  List<Object> get arguments =>
       [parent.name, element.name, subType, base, baseType];
 
   ClassElement get parent => element.enclosingElement;
@@ -392,8 +395,10 @@
       TypeSystem rules, FormalParameter declaration, this.expectedType)
       : super(declaration);
 
-  @override List<Object> get arguments => [node, expectedType];
-  @override String get message => 'Type check failed: {0} is not of type {1}';
+  @override
+  List<Object> get arguments => [node, expectedType];
+  @override
+  String get message => 'Type check failed: {0} is not of type {1}';
   @override
   String get name => 'STRONG_MODE_INVALID_PARAMETER_DECLARATION';
 }
@@ -424,14 +429,15 @@
 /// could be if initializers have side effects.
 ///
 /// Better to have `super` at the end, as required by the Dart style guide:
-/// <http://goo.gl/q1T4BB>
+/// <https://goo.gl/EY6hDP>
 ///
 /// For now this is the only pattern we support.
 class InvalidSuperInvocation extends StaticError {
   InvalidSuperInvocation(SuperConstructorInvocation node) : super(node);
 
-  @override String get message => "super call must be last in an initializer "
-      "list (see http://goo.gl/q1T4BB): {0}";
+  @override
+  String get message => "super call must be last in an initializer "
+      "list (see https://goo.gl/EY6hDP): {0}";
 
   @override
   String get name => 'STRONG_MODE_INVALID_SUPER_INVOCATION';
@@ -444,8 +450,10 @@
       TypeSystem rules, AstNode declaration, this.expectedType)
       : super(declaration);
 
-  @override List<Object> get arguments => [expectedType];
-  @override String get message => 'Type check failed: null is not of type {0}';
+  @override
+  List<Object> get arguments => [expectedType];
+  @override
+  String get message => 'Type check failed: null is not of type {0}';
 
   @override
   String get name => 'STRONG_MODE_INVALID_VARIABLE_DECLARATION';
@@ -459,7 +467,8 @@
     assert(node is IsExpression || node is AsExpression);
   }
 
-  @override List<Object> get arguments => [type];
+  @override
+  List<Object> get arguments => [type];
   String get message =>
       "Runtime check on non-ground type {0} may throw StrongModeError";
 
@@ -541,31 +550,13 @@
       : baseType = expression.staticType ?? DynamicTypeImpl.instance,
         super(expression);
 
-  @override List<Object> get arguments => [node, baseType, expectedType];
-  @override String get message =>
+  @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');
 
   @override
   String get name => 'STRONG_MODE_STATIC_TYPE_ERROR';
 }
-
-//
-// Temporary "casts" of allocation sites - literals, constructor invocations,
-// and closures.  These should be handled by contextual inference.  In most
-// cases, inference will be sufficient, though in some it may unmask an actual
-// error: e.g.,
-//   List<int> l = [1, 2, 3]; // Inference succeeds
-//   List<String> l = [1, 2, 3]; // Inference reveals static type error
-// We're marking all as warnings for now.
-//
-// TODO(vsm,leafp): Remove this.
-class UninferredClosure extends DownCast {
-  UninferredClosure(TypeSystem rules, FunctionExpression expression, Cast cast)
-      : super._internal(rules, expression, cast);
-
-  @override
-  String get name => 'STRONG_MODE_UNINFERRED_CLOSURE';
-
-  toErrorCode() => new StaticTypeWarningCode(name, message);
-}
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 46b84e0..05b5f1a 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -6,67 +6,31 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/resolver.dart'
     show TypeProvider, InheritanceManager;
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
- * Set the type of the sole parameter of the given [element] to the given [type].
+ * Sets the type of the field. This is stored in the field itself, and the
+ * synthetic getter/setter types.
  */
-void setParameterType(PropertyAccessorElement element, DartType type) {
-  if (element is PropertyAccessorElementImpl) {
-    ParameterElement parameter = _getParameter(element);
-    if (parameter is ParameterElementImpl) {
-      //
-      // Update the type of the parameter.
-      //
-      parameter.type = type;
-      //
-      // Update the type of the setter to reflect the new parameter type.
-      //
-      // TODO(jmesserly): why is this necessary? The function type should always
-      // delegate to the orginal element.
-      FunctionType functionType = element.type;
-      if (functionType is FunctionTypeImpl) {
-        element.type = new FunctionTypeImpl(element);
-      } else {
-        assert(false);
-      }
-    } else {
-      assert(false);
-    }
-  } else {
-    throw new StateError('element is an instance of ${element.runtimeType}');
-    assert(false);
+void setFieldType(VariableElement field, DartType newType) {
+  (field as VariableElementImpl).type = newType;
+  if (field.initializer != null) {
+    (field.initializer as ExecutableElementImpl).returnType = newType;
   }
-}
-
-/**
- * Set the return type of the given [element] to the given [type].
- */
-void setReturnType(ExecutableElement element, DartType type) {
-  if (element is ExecutableElementImpl) {
-    //
-    // Update the return type of the element, which is stored in two places:
-    // directly in the element and indirectly in the type of the element.
-    //
-    // TODO(jmesserly): why is this necessary? The function type should always
-    // delegate to the orginal element.
-    element.returnType = type;
-    FunctionType functionType = element.type;
-    if (functionType is FunctionTypeImpl) {
-      element.type = new FunctionTypeImpl(element);
-    } else {
-      assert(false);
+  if (field is PropertyInducingElementImpl) {
+    (field.getter as ExecutableElementImpl).returnType = newType;
+    if (!field.isFinal && !field.isConst) {
+      (field.setter.parameters[0] as ParameterElementImpl).type =
+          newType;
     }
-  } else {
-    assert(false);
   }
 }
 
@@ -317,7 +281,8 @@
           !_allSameElementKind(element, overriddenMethods)) {
         return;
       }
-      setReturnType(element, _computeReturnType(overriddenMethods));
+      (element as ExecutableElementImpl).returnType =
+          _computeReturnType(overriddenMethods);
       if (element is PropertyAccessorElement) {
         _updateSyntheticVariableType(element);
       }
@@ -387,11 +352,7 @@
       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);
-      }
+      setFieldType(fieldElement, newType);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
new file mode 100644
index 0000000..8ce7ec1
--- /dev/null
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.task.yaml;
+
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/error.dart';
+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/task/general.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:analyzer/task/yaml.dart';
+import 'package:source_span/source_span.dart';
+import 'package:yaml/yaml.dart';
+
+/**
+ * A task that scans the content of a YAML file, producing a YAML document.
+ */
+class ParseYamlTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input whose value is the content of the file.
+   */
+  static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ParseYamlTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[YAML_DOCUMENT, YAML_ERRORS, LINE_INFO],
+      suitabilityFor: suitabilityFor);
+
+  /**
+   * Initialize a newly created task to access the content of the source
+   * associated with the given [target] in the given [context].
+   */
+  ParseYamlTask(InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    Source source = target.source;
+    String uri = source.uri.toString();
+    String content = getRequiredInput(CONTENT_INPUT_NAME);
+
+    if (context.getModificationStamp(source) < 0) {
+      String message = 'Content could not be read';
+      if (context is InternalAnalysisContext) {
+        CacheEntry entry =
+            (context as InternalAnalysisContext).getCacheEntry(target);
+        CaughtException exception = entry.exception;
+        if (exception != null) {
+          message = exception.toString();
+        }
+      }
+      //
+      // Record outputs.
+      //
+      outputs[YAML_DOCUMENT] = loadYamlDocument('', sourceUrl: uri);
+      outputs[YAML_ERRORS] = <AnalysisError>[
+        new AnalysisError(
+            source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message])
+      ];
+      outputs[LINE_INFO] = new LineInfo(<int>[0]);
+    } else {
+      YamlDocument document;
+      List<AnalysisError> errors = <AnalysisError>[];
+      try {
+        document = loadYamlDocument(content, sourceUrl: uri);
+      } on YamlException catch (exception) {
+        SourceSpan span = exception.span;
+        int offset = span.start.offset;
+        int length = span.end.offset - offset;
+        errors.add(new AnalysisError(source, offset, length,
+            YamlErrorCode.PARSE_ERROR, [exception.message]));
+      } catch (exception, stackTrace) {
+        throw new AnalysisException('Error while parsing ${source.fullName}',
+            new CaughtException(exception, stackTrace));
+      }
+      //
+      // Record outputs.
+      //
+      outputs[YAML_DOCUMENT] = document;
+      outputs[YAML_ERRORS] = errors;
+      outputs[LINE_INFO] = new LineInfo.fromContent(content);
+    }
+  }
+
+  /**
+   * 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
+   * [source].
+   */
+  static Map<String, TaskInput> buildInputs(Source source) {
+    return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
+  }
+
+  /**
+   * Create a [ParseYamlTask] based on the given [target] in the given [context].
+   */
+  static ParseYamlTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ParseYamlTask(context, target);
+  }
+
+  /**
+   * Return an indication of how suitable this task is for the given [target].
+   */
+  static TaskSuitability suitabilityFor(AnalysisTarget target) {
+    if (target is Source && target.shortName.endsWith('.yaml')) {
+      return TaskSuitability.HIGHEST;
+    }
+    return TaskSuitability.NONE;
+  }
+}
+
+/**
+ * The error codes used for errors in YAML files.
+ */
+class YamlErrorCode extends ErrorCode {
+  // TODO(brianwilkerson) Move this class to error.dart.
+
+  /**
+   * An error code indicating that there is a syntactic error in the file.
+   *
+   * Parameters:
+   * 0: the error message from the parse error
+   */
+  static const YamlErrorCode PARSE_ERROR =
+      const YamlErrorCode('PARSE_ERROR', '{0}');
+
+  /**
+   * Initialize a newly created error code to have the given [name]. The message
+   * associated with the error will be created from the given [message]
+   * template. The correction associated with the error will be created from the
+   * given [correction] template.
+   */
+  const YamlErrorCode(String name, String message, [String correction])
+      : super(name, message, correction);
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+  @override
+  ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
+}
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/task/dart.dart
index 27258c3..ea132e3 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/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.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 c320659..58e095b 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -36,6 +36,14 @@
 typedef Map<String, TaskInput> CreateTaskInputs(AnalysisTarget target);
 
 /**
+ * A function that takes the target for which a task will produce results and
+ * returns an indication of how suitable the task is for the target. Such
+ * functions are passed to a [TaskDescriptor] to be used to determine their
+ * suitability for computing results.
+ */
+typedef TaskSuitability SuitabilityFor(AnalysisTarget target);
+
+/**
  * A function that converts an object of the type [B] into a [TaskInput].
  * This is used, for example, by a [ListTaskInput] to create task inputs
  * for each value in a list of values.
@@ -355,37 +363,36 @@
    * Return a task input that can be used to compute a flatten list whose
    * elements are combined [subListResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
-      ListResultDescriptor /*<V>*/ subListResult);
+  ListTaskInput/*<V>*/ toFlattenListOf/*<V>*/(
+      ListResultDescriptor/*<V>*/ subListResult);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the elements of this input to the [mapper] function.
    */
-  ListTaskInput /*<V>*/ toList /*<V>*/ (
-      UnaryFunction<E, dynamic /*<=V>*/ > mapper);
+  ListTaskInput/*<V>*/ toList/*<V>*/(UnaryFunction<E, dynamic/*<=V>*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * [valueResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toListOf /*<V>*/ (ResultDescriptor /*<V>*/ valueResult);
+  ListTaskInput/*<V>*/ toListOf/*<V>*/(ResultDescriptor/*<V>*/ valueResult);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the result of passing the
    * corresponding key to the [mapper] function.
    */
-  MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
-      UnaryFunction<E, dynamic /*=V*/ > mapper);
+  MapTaskInput<E, dynamic/*=V*/ > toMap/*<V>*/(
+      UnaryFunction<E, dynamic/*=V*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the [valueResult]'s associated
    * with those elements.
    */
-  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
-      ResultDescriptor /*<V>*/ valueResult);
+  MapTaskInput<AnalysisTarget, dynamic/*=V*/ > toMapOf/*<V>*/(
+      ResultDescriptor/*<V>*/ valueResult);
 }
 
 /**
@@ -400,8 +407,8 @@
    * the result of passing keys [K] and the corresponding elements of [V] to
    * the [mapper] function.
    */
-  TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
-      BinaryFunction<K, dynamic /*element of V*/, dynamic /*=E*/ > mapper);
+  TaskInput<List/*<E>*/ > toFlattenList/*<E>*/(
+      BinaryFunction<K, dynamic /*element of V*/, dynamic/*=E*/ > mapper);
 }
 
 /**
@@ -523,14 +530,14 @@
   /**
    * Initialize a newly created task descriptor to have the given [name] and to
    * describe a task that takes the inputs built using the given [inputBuilder],
-   * and produces the given [results]. The [buildTask] will be used to create
-   * the instance of [AnalysisTask] thusly described.
+   * and produces the given [results]. The [buildTask] function will be used to
+   * create the instance of [AnalysisTask] being described. If provided, the
+   * [isAppropriateFor] function will be used to determine whether the task can
+   * be used on a specific target.
    */
-  factory TaskDescriptor(
-      String name,
-      BuildTask buildTask,
-      CreateTaskInputs inputBuilder,
-      List<ResultDescriptor> results) = TaskDescriptorImpl;
+  factory TaskDescriptor(String name, BuildTask buildTask,
+      CreateTaskInputs inputBuilder, List<ResultDescriptor> results,
+      {SuitabilityFor suitabilityFor}) = TaskDescriptorImpl;
 
   /**
    * Return the builder used to build the inputs to the task.
@@ -553,6 +560,11 @@
    */
   AnalysisTask createTask(AnalysisContext context, AnalysisTarget target,
       Map<String, dynamic> inputs);
+
+  /**
+   * Return an indication of how suitable this task is for the given [target].
+   */
+  TaskSuitability suitabilityFor(AnalysisTarget target);
 }
 
 /**
@@ -571,7 +583,7 @@
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the result of this input to the [mapper] function.
    */
-  ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value));
+  ListTaskInput/*<E>*/ mappedToList/*<E>*/(List/*<E>*/ mapper(V value));
 }
 
 /**
@@ -651,6 +663,11 @@
 }
 
 /**
+ * An indication of how suitable a task is for a given target.
+ */
+enum TaskSuitability { NONE, LOWEST, HIGHEST }
+
+/**
  * [WorkManager]s are used to drive analysis.
  *
  * They know specific of the targets and results they care about,
diff --git a/pkg/analyzer/lib/task/yaml.dart b/pkg/analyzer/lib/task/yaml.dart
new file mode 100644
index 0000000..1795d8f
--- /dev/null
+++ b/pkg/analyzer/lib/task/yaml.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.task.yaml;
+
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:yaml/yaml.dart';
+
+/**
+ * The result of parsing a YAML file.
+ */
+final ResultDescriptor<YamlDocument> YAML_DOCUMENT =
+    new ResultDescriptor<YamlDocument>('YAML_DOCUMENT', null);
+
+/**
+ * The analysis errors associated with a [Source] representing a YAML file.
+ */
+final ListResultDescriptor<AnalysisError> YAML_ERRORS =
+    new ListResultDescriptor<AnalysisError>(
+        'YAML_ERRORS', AnalysisError.NO_ERRORS);
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 607b92c..01abc35 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.1+2
+version: 0.27.2-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
new file mode 100644
index 0000000..f8d51f1
--- /dev/null
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -0,0 +1,1308 @@
+// 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.ast.ast_test;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/parser_test.dart' show ParserTestCase;
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(ClassDeclarationTest);
+  runReflectiveTests(ClassTypeAliasTest);
+  runReflectiveTests(ConstructorDeclarationTest);
+  runReflectiveTests(FieldFormalParameterTest);
+  runReflectiveTests(IndexExpressionTest);
+  runReflectiveTests(NodeListTest);
+  runReflectiveTests(SimpleIdentifierTest);
+  runReflectiveTests(SimpleStringLiteralTest);
+  runReflectiveTests(StringInterpolationTest);
+  runReflectiveTests(VariableDeclarationTest);
+}
+
+@reflectiveTest
+class ClassDeclarationTest extends ParserTestCase {
+  void test_getConstructor() {
+    List<ConstructorInitializer> initializers =
+        new List<ConstructorInitializer>();
+    ConstructorDeclaration defaultConstructor =
+        AstFactory.constructorDeclaration(AstFactory.identifier3("Test"), null,
+            AstFactory.formalParameterList(), initializers);
+    ConstructorDeclaration aConstructor = AstFactory.constructorDeclaration(
+        AstFactory.identifier3("Test"),
+        "a",
+        AstFactory.formalParameterList(),
+        initializers);
+    ConstructorDeclaration bConstructor = AstFactory.constructorDeclaration(
+        AstFactory.identifier3("Test"),
+        "b",
+        AstFactory.formalParameterList(),
+        initializers);
+    ClassDeclaration clazz = AstFactory.classDeclaration(null, "Test", null,
+        null, null, null, [defaultConstructor, aConstructor, bConstructor]);
+    expect(clazz.getConstructor(null), same(defaultConstructor));
+    expect(clazz.getConstructor("a"), same(aConstructor));
+    expect(clazz.getConstructor("b"), same(bConstructor));
+    expect(clazz.getConstructor("noSuchConstructor"), same(null));
+  }
+
+  void test_getField() {
+    VariableDeclaration aVar = AstFactory.variableDeclaration("a");
+    VariableDeclaration bVar = AstFactory.variableDeclaration("b");
+    VariableDeclaration cVar = AstFactory.variableDeclaration("c");
+    ClassDeclaration clazz =
+        AstFactory.classDeclaration(null, "Test", null, null, null, null, [
+      AstFactory.fieldDeclaration2(false, null, [aVar]),
+      AstFactory.fieldDeclaration2(false, null, [bVar, cVar])
+    ]);
+    expect(clazz.getField("a"), same(aVar));
+    expect(clazz.getField("b"), same(bVar));
+    expect(clazz.getField("c"), same(cVar));
+    expect(clazz.getField("noSuchField"), same(null));
+  }
+
+  void test_getMethod() {
+    MethodDeclaration aMethod = AstFactory.methodDeclaration(null, null, null,
+        null, AstFactory.identifier3("a"), AstFactory.formalParameterList());
+    MethodDeclaration bMethod = AstFactory.methodDeclaration(null, null, null,
+        null, AstFactory.identifier3("b"), AstFactory.formalParameterList());
+    ClassDeclaration clazz = AstFactory.classDeclaration(
+        null, "Test", null, null, null, null, [aMethod, bMethod]);
+    expect(clazz.getMethod("a"), same(aMethod));
+    expect(clazz.getMethod("b"), same(bMethod));
+    expect(clazz.getMethod("noSuchMethod"), same(null));
+  }
+
+  void test_isAbstract() {
+    expect(
+        AstFactory
+            .classDeclaration(null, "A", null, null, null, null)
+            .isAbstract,
+        isFalse);
+    expect(
+        AstFactory
+            .classDeclaration(Keyword.ABSTRACT, "B", null, null, null, null)
+            .isAbstract,
+        isTrue);
+  }
+}
+
+@reflectiveTest
+class ClassTypeAliasTest extends ParserTestCase {
+  void test_isAbstract() {
+    expect(
+        AstFactory.classTypeAlias("A", null, null, null, null, null).isAbstract,
+        isFalse);
+    expect(
+        AstFactory
+            .classTypeAlias("B", null, Keyword.ABSTRACT, null, null, null)
+            .isAbstract,
+        isTrue);
+  }
+}
+
+@reflectiveTest
+class ConstructorDeclarationTest extends EngineTestCase {
+  void test_firstTokenAfterCommentAndMetadata_all_inverted() {
+    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+    externalKeyword.offset = 14;
+    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+        Keyword.CONST,
+        Keyword.FACTORY,
+        AstFactory.identifier3('int'),
+        null,
+        null,
+        null,
+        null);
+    declaration.externalKeyword = externalKeyword;
+    declaration.constKeyword.offset = 8;
+    Token factoryKeyword = declaration.factoryKeyword;
+    factoryKeyword.offset = 0;
+    expect(declaration.firstTokenAfterCommentAndMetadata, factoryKeyword);
+  }
+
+  void test_firstTokenAfterCommentAndMetadata_all_normal() {
+    Token token = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+    token.offset = 0;
+    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+        Keyword.CONST,
+        Keyword.FACTORY,
+        AstFactory.identifier3('int'),
+        null,
+        null,
+        null,
+        null);
+    declaration.externalKeyword = token;
+    declaration.constKeyword.offset = 9;
+    declaration.factoryKeyword.offset = 15;
+    expect(declaration.firstTokenAfterCommentAndMetadata, token);
+  }
+
+  void test_firstTokenAfterCommentAndMetadata_constOnly() {
+    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+        Keyword.CONST,
+        null,
+        AstFactory.identifier3('int'),
+        null,
+        null,
+        null,
+        null);
+    expect(declaration.firstTokenAfterCommentAndMetadata,
+        declaration.constKeyword);
+  }
+
+  void test_firstTokenAfterCommentAndMetadata_externalOnly() {
+    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
+    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+        null, null, AstFactory.identifier3('int'), null, null, null, null);
+    declaration.externalKeyword = externalKeyword;
+    expect(declaration.firstTokenAfterCommentAndMetadata, externalKeyword);
+  }
+
+  void test_firstTokenAfterCommentAndMetadata_factoryOnly() {
+    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
+        null,
+        Keyword.FACTORY,
+        AstFactory.identifier3('int'),
+        null,
+        null,
+        null,
+        null);
+    expect(declaration.firstTokenAfterCommentAndMetadata,
+        declaration.factoryKeyword);
+  }
+}
+
+@reflectiveTest
+class FieldFormalParameterTest extends EngineTestCase {
+  void test_endToken_noParameters() {
+    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('field');
+    expect(parameter.endToken, parameter.identifier.endToken);
+  }
+
+  void test_endToken_parameters() {
+    FieldFormalParameter parameter = AstFactory.fieldFormalParameter(
+        null, null, 'field', AstFactory.formalParameterList([]));
+    expect(parameter.endToken, parameter.parameters.endToken);
+  }
+}
+
+@reflectiveTest
+class IndexExpressionTest extends EngineTestCase {
+  void test_inGetterContext_assignment_compound_left() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // a[b] += c
+    AstFactory.assignmentExpression(
+        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
+    expect(expression.inGetterContext(), isTrue);
+  }
+
+  void test_inGetterContext_assignment_simple_left() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // a[b] = c
+    AstFactory.assignmentExpression(
+        expression, TokenType.EQ, AstFactory.identifier3("c"));
+    expect(expression.inGetterContext(), isFalse);
+  }
+
+  void test_inGetterContext_nonAssignment() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // a[b] + c
+    AstFactory.binaryExpression(
+        expression, TokenType.PLUS, AstFactory.identifier3("c"));
+    expect(expression.inGetterContext(), isTrue);
+  }
+
+  void test_inSetterContext_assignment_compound_left() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // a[b] += c
+    AstFactory.assignmentExpression(
+        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
+    expect(expression.inSetterContext(), isTrue);
+  }
+
+  void test_inSetterContext_assignment_compound_right() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // c += a[b]
+    AstFactory.assignmentExpression(
+        AstFactory.identifier3("c"), TokenType.PLUS_EQ, expression);
+    expect(expression.inSetterContext(), isFalse);
+  }
+
+  void test_inSetterContext_assignment_simple_left() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // a[b] = c
+    AstFactory.assignmentExpression(
+        expression, TokenType.EQ, AstFactory.identifier3("c"));
+    expect(expression.inSetterContext(), isTrue);
+  }
+
+  void test_inSetterContext_assignment_simple_right() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // c = a[b]
+    AstFactory.assignmentExpression(
+        AstFactory.identifier3("c"), TokenType.EQ, expression);
+    expect(expression.inSetterContext(), isFalse);
+  }
+
+  void test_inSetterContext_nonAssignment() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    AstFactory.binaryExpression(
+        expression, TokenType.PLUS, AstFactory.identifier3("c"));
+    // a[b] + cc
+    expect(expression.inSetterContext(), isFalse);
+  }
+
+  void test_inSetterContext_postfix() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+    // a[b]++
+    expect(expression.inSetterContext(), isTrue);
+  }
+
+  void test_inSetterContext_prefix_bang() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // !a[b]
+    AstFactory.prefixExpression(TokenType.BANG, expression);
+    expect(expression.inSetterContext(), isFalse);
+  }
+
+  void test_inSetterContext_prefix_minusMinus() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // --a[b]
+    AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+    expect(expression.inSetterContext(), isTrue);
+  }
+
+  void test_inSetterContext_prefix_plusPlus() {
+    IndexExpression expression = AstFactory.indexExpression(
+        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
+    // ++a[b]
+    AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+    expect(expression.inSetterContext(), isTrue);
+  }
+}
+
+@reflectiveTest
+class NodeListTest extends EngineTestCase {
+  void test_add() {
+    AstNode parent = AstFactory.argumentList();
+    AstNode firstNode = AstFactory.booleanLiteral(true);
+    AstNode secondNode = AstFactory.booleanLiteral(false);
+    NodeList<AstNode> list = new NodeList<AstNode>(parent);
+    list.insert(0, secondNode);
+    list.insert(0, firstNode);
+    expect(list, hasLength(2));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(secondNode));
+    expect(firstNode.parent, same(parent));
+    expect(secondNode.parent, same(parent));
+    AstNode thirdNode = AstFactory.booleanLiteral(false);
+    list.insert(1, thirdNode);
+    expect(list, hasLength(3));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(thirdNode));
+    expect(list[2], same(secondNode));
+    expect(firstNode.parent, same(parent));
+    expect(secondNode.parent, same(parent));
+    expect(thirdNode.parent, same(parent));
+  }
+
+  void test_add_negative() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list.insert(-1, AstFactory.booleanLiteral(true));
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_add_tooBig() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list.insert(1, AstFactory.booleanLiteral(true));
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_addAll() {
+    AstNode parent = AstFactory.argumentList();
+    List<AstNode> firstNodes = new List<AstNode>();
+    AstNode firstNode = AstFactory.booleanLiteral(true);
+    AstNode secondNode = AstFactory.booleanLiteral(false);
+    firstNodes.add(firstNode);
+    firstNodes.add(secondNode);
+    NodeList<AstNode> list = new NodeList<AstNode>(parent);
+    list.addAll(firstNodes);
+    expect(list, hasLength(2));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(secondNode));
+    expect(firstNode.parent, same(parent));
+    expect(secondNode.parent, same(parent));
+    List<AstNode> secondNodes = new List<AstNode>();
+    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    AstNode fourthNode = AstFactory.booleanLiteral(false);
+    secondNodes.add(thirdNode);
+    secondNodes.add(fourthNode);
+    list.addAll(secondNodes);
+    expect(list, hasLength(4));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(secondNode));
+    expect(list[2], same(thirdNode));
+    expect(list[3], same(fourthNode));
+    expect(firstNode.parent, same(parent));
+    expect(secondNode.parent, same(parent));
+    expect(thirdNode.parent, same(parent));
+    expect(fourthNode.parent, same(parent));
+  }
+
+  void test_creation() {
+    AstNode owner = AstFactory.argumentList();
+    NodeList<AstNode> list = new NodeList<AstNode>(owner);
+    expect(list, isNotNull);
+    expect(list, hasLength(0));
+    expect(list.owner, same(owner));
+  }
+
+  void test_get_negative() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list[-1];
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_get_tooBig() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list[1];
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_getBeginToken_empty() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    expect(list.beginToken, isNull);
+  }
+
+  void test_getBeginToken_nonEmpty() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    AstNode node =
+        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
+    list.add(node);
+    expect(list.beginToken, same(node.beginToken));
+  }
+
+  void test_getEndToken_empty() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    expect(list.endToken, isNull);
+  }
+
+  void test_getEndToken_nonEmpty() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    AstNode node =
+        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
+    list.add(node);
+    expect(list.endToken, same(node.endToken));
+  }
+
+  void test_indexOf() {
+    List<AstNode> nodes = new List<AstNode>();
+    AstNode firstNode = AstFactory.booleanLiteral(true);
+    AstNode secondNode = AstFactory.booleanLiteral(false);
+    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    AstNode fourthNode = AstFactory.booleanLiteral(false);
+    nodes.add(firstNode);
+    nodes.add(secondNode);
+    nodes.add(thirdNode);
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    list.addAll(nodes);
+    expect(list, hasLength(3));
+    expect(list.indexOf(firstNode), 0);
+    expect(list.indexOf(secondNode), 1);
+    expect(list.indexOf(thirdNode), 2);
+    expect(list.indexOf(fourthNode), -1);
+    expect(list.indexOf(null), -1);
+  }
+
+  void test_remove() {
+    List<AstNode> nodes = new List<AstNode>();
+    AstNode firstNode = AstFactory.booleanLiteral(true);
+    AstNode secondNode = AstFactory.booleanLiteral(false);
+    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    nodes.add(firstNode);
+    nodes.add(secondNode);
+    nodes.add(thirdNode);
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    list.addAll(nodes);
+    expect(list, hasLength(3));
+    expect(list.removeAt(1), same(secondNode));
+    expect(list, hasLength(2));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(thirdNode));
+  }
+
+  void test_remove_negative() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list.removeAt(-1);
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_remove_tooBig() {
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      list.removeAt(1);
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_set() {
+    List<AstNode> nodes = new List<AstNode>();
+    AstNode firstNode = AstFactory.booleanLiteral(true);
+    AstNode secondNode = AstFactory.booleanLiteral(false);
+    AstNode thirdNode = AstFactory.booleanLiteral(true);
+    nodes.add(firstNode);
+    nodes.add(secondNode);
+    nodes.add(thirdNode);
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    list.addAll(nodes);
+    expect(list, hasLength(3));
+    AstNode fourthNode = AstFactory.integer(0);
+    expect(javaListSet(list, 1, fourthNode), same(secondNode));
+    expect(list, hasLength(3));
+    expect(list[0], same(firstNode));
+    expect(list[1], same(fourthNode));
+    expect(list[2], same(thirdNode));
+  }
+
+  void test_set_negative() {
+    AstNode node = AstFactory.booleanLiteral(true);
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      javaListSet(list, -1, node);
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+
+  void test_set_tooBig() {
+    AstNode node = AstFactory.booleanLiteral(true);
+    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
+    try {
+      javaListSet(list, 1, node);
+      fail("Expected IndexOutOfBoundsException");
+    } on RangeError {
+      // Expected
+    }
+  }
+}
+
+@reflectiveTest
+class SimpleIdentifierTest extends ParserTestCase {
+  void test_inDeclarationContext_catch_exception() {
+    SimpleIdentifier identifier =
+        AstFactory.catchClause("e").exceptionParameter;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_catch_stack() {
+    SimpleIdentifier identifier =
+        AstFactory.catchClause2("e", "s").stackTraceParameter;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_classDeclaration() {
+    SimpleIdentifier identifier =
+        AstFactory.classDeclaration(null, "C", null, null, null, null).name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_classTypeAlias() {
+    SimpleIdentifier identifier =
+        AstFactory.classTypeAlias("C", null, null, null, null, null).name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_constructorDeclaration() {
+    SimpleIdentifier identifier = AstFactory
+        .constructorDeclaration(AstFactory.identifier3("C"), "c", null, null)
+        .name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_declaredIdentifier() {
+    DeclaredIdentifier declaredIdentifier = AstFactory.declaredIdentifier3("v");
+    SimpleIdentifier identifier = declaredIdentifier.identifier;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_enumConstantDeclaration() {
+    EnumDeclaration enumDeclaration =
+        AstFactory.enumDeclaration2('MyEnum', ['CONST']);
+    SimpleIdentifier identifier = enumDeclaration.constants[0].name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_enumDeclaration() {
+    EnumDeclaration enumDeclaration =
+        AstFactory.enumDeclaration2('MyEnum', ['A', 'B', 'C']);
+    SimpleIdentifier identifier = enumDeclaration.name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_fieldFormalParameter() {
+    SimpleIdentifier identifier =
+        AstFactory.fieldFormalParameter2("p").identifier;
+    expect(identifier.inDeclarationContext(), isFalse);
+  }
+
+  void test_inDeclarationContext_functionDeclaration() {
+    SimpleIdentifier identifier =
+        AstFactory.functionDeclaration(null, null, "f", null).name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_functionTypeAlias() {
+    SimpleIdentifier identifier =
+        AstFactory.typeAlias(null, "F", null, null).name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_label_false() {
+    SimpleIdentifier identifier =
+        AstFactory.namedExpression2("l", AstFactory.integer(0)).name.label;
+    expect(identifier.inDeclarationContext(), isFalse);
+  }
+
+  void test_inDeclarationContext_label_true() {
+    Label label = AstFactory.label2("l");
+    SimpleIdentifier identifier = label.label;
+    AstFactory.labeledStatement([label], AstFactory.emptyStatement());
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_methodDeclaration() {
+    SimpleIdentifier identifier = AstFactory.identifier3("m");
+    AstFactory.methodDeclaration2(
+        null, null, null, null, identifier, null, null);
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_prefix() {
+    SimpleIdentifier identifier =
+        AstFactory.importDirective3("uri", "pref").prefix;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_simpleFormalParameter() {
+    SimpleIdentifier identifier =
+        AstFactory.simpleFormalParameter3("p").identifier;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_typeParameter_bound() {
+    TypeName bound = AstFactory.typeName4("A");
+    SimpleIdentifier identifier = bound.name as SimpleIdentifier;
+    AstFactory.typeParameter2("E", bound);
+    expect(identifier.inDeclarationContext(), isFalse);
+  }
+
+  void test_inDeclarationContext_typeParameter_name() {
+    SimpleIdentifier identifier = AstFactory.typeParameter("E").name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inDeclarationContext_variableDeclaration() {
+    SimpleIdentifier identifier = AstFactory.variableDeclaration("v").name;
+    expect(identifier.inDeclarationContext(), isTrue);
+  }
+
+  void test_inGetterContext() {
+    for (_WrapperKind wrapper in _WrapperKind.values) {
+      for (_AssignmentKind assignment in _AssignmentKind.values) {
+        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
+        if (assignment == _AssignmentKind.SIMPLE_LEFT &&
+            wrapper != _WrapperKind.PREFIXED_LEFT &&
+            wrapper != _WrapperKind.PROPERTY_LEFT) {
+          if (identifier.inGetterContext()) {
+            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
+          }
+        } else {
+          if (!identifier.inGetterContext()) {
+            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
+          }
+        }
+      }
+    }
+  }
+
+  void test_inGetterContext_forEachLoop() {
+    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    Expression iterator = AstFactory.listLiteral();
+    Statement body = AstFactory.block();
+    AstFactory.forEachStatement2(identifier, iterator, body);
+    expect(identifier.inGetterContext(), isFalse);
+  }
+
+  void test_inReferenceContext() {
+    SimpleIdentifier identifier = AstFactory.identifier3("id");
+    AstFactory.namedExpression(
+        AstFactory.label(identifier), AstFactory.identifier3("_"));
+    expect(identifier.inGetterContext(), isFalse);
+    expect(identifier.inSetterContext(), isFalse);
+  }
+
+  void test_inSetterContext() {
+    for (_WrapperKind wrapper in _WrapperKind.values) {
+      for (_AssignmentKind assignment in _AssignmentKind.values) {
+        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
+        if (wrapper == _WrapperKind.PREFIXED_LEFT ||
+            wrapper == _WrapperKind.PROPERTY_LEFT ||
+            assignment == _AssignmentKind.BINARY ||
+            assignment == _AssignmentKind.COMPOUND_RIGHT ||
+            assignment == _AssignmentKind.PREFIX_NOT ||
+            assignment == _AssignmentKind.SIMPLE_RIGHT ||
+            assignment == _AssignmentKind.NONE) {
+          if (identifier.inSetterContext()) {
+            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
+          }
+        } else {
+          if (!identifier.inSetterContext()) {
+            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
+          }
+        }
+      }
+    }
+  }
+
+  void test_inSetterContext_forEachLoop() {
+    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    Expression iterator = AstFactory.listLiteral();
+    Statement body = AstFactory.block();
+    AstFactory.forEachStatement2(identifier, iterator, body);
+    expect(identifier.inSetterContext(), isTrue);
+  }
+
+  void test_isQualified_inMethodInvocation_noTarget() {
+    MethodInvocation invocation =
+        AstFactory.methodInvocation2("test", [AstFactory.identifier3("arg0")]);
+    SimpleIdentifier identifier = invocation.methodName;
+    expect(identifier.isQualified, isFalse);
+  }
+
+  void test_isQualified_inMethodInvocation_withTarget() {
+    MethodInvocation invocation = AstFactory.methodInvocation(
+        AstFactory.identifier3("target"),
+        "test",
+        [AstFactory.identifier3("arg0")]);
+    SimpleIdentifier identifier = invocation.methodName;
+    expect(identifier.isQualified, isTrue);
+  }
+
+  void test_isQualified_inPrefixedIdentifier_name() {
+    SimpleIdentifier identifier = AstFactory.identifier3("test");
+    AstFactory.identifier4("prefix", identifier);
+    expect(identifier.isQualified, isTrue);
+  }
+
+  void test_isQualified_inPrefixedIdentifier_prefix() {
+    SimpleIdentifier identifier = AstFactory.identifier3("test");
+    AstFactory.identifier(identifier, AstFactory.identifier3("name"));
+    expect(identifier.isQualified, isFalse);
+  }
+
+  void test_isQualified_inPropertyAccess_name() {
+    SimpleIdentifier identifier = AstFactory.identifier3("test");
+    AstFactory.propertyAccess(AstFactory.identifier3("target"), identifier);
+    expect(identifier.isQualified, isTrue);
+  }
+
+  void test_isQualified_inPropertyAccess_target() {
+    SimpleIdentifier identifier = AstFactory.identifier3("test");
+    AstFactory.propertyAccess(identifier, AstFactory.identifier3("name"));
+    expect(identifier.isQualified, isFalse);
+  }
+
+  void test_isQualified_inReturnStatement() {
+    SimpleIdentifier identifier = AstFactory.identifier3("test");
+    AstFactory.returnStatement2(identifier);
+    expect(identifier.isQualified, isFalse);
+  }
+
+  SimpleIdentifier _createIdentifier(
+      _WrapperKind wrapper, _AssignmentKind assignment) {
+    SimpleIdentifier identifier = AstFactory.identifier3("a");
+    Expression expression = identifier;
+    while (true) {
+      if (wrapper == _WrapperKind.PREFIXED_LEFT) {
+        expression =
+            AstFactory.identifier(identifier, AstFactory.identifier3("_"));
+      } else if (wrapper == _WrapperKind.PREFIXED_RIGHT) {
+        expression =
+            AstFactory.identifier(AstFactory.identifier3("_"), identifier);
+      } else if (wrapper == _WrapperKind.PROPERTY_LEFT) {
+        expression = AstFactory.propertyAccess2(expression, "_");
+      } else if (wrapper == _WrapperKind.PROPERTY_RIGHT) {
+        expression =
+            AstFactory.propertyAccess(AstFactory.identifier3("_"), identifier);
+      } else if (wrapper == _WrapperKind.NONE) {}
+      break;
+    }
+    while (true) {
+      if (assignment == _AssignmentKind.BINARY) {
+        AstFactory.binaryExpression(
+            expression, TokenType.PLUS, AstFactory.identifier3("_"));
+      } else if (assignment == _AssignmentKind.COMPOUND_LEFT) {
+        AstFactory.assignmentExpression(
+            expression, TokenType.PLUS_EQ, AstFactory.identifier3("_"));
+      } else if (assignment == _AssignmentKind.COMPOUND_RIGHT) {
+        AstFactory.assignmentExpression(
+            AstFactory.identifier3("_"), TokenType.PLUS_EQ, expression);
+      } else if (assignment == _AssignmentKind.POSTFIX_INC) {
+        AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
+      } else if (assignment == _AssignmentKind.PREFIX_DEC) {
+        AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
+      } else if (assignment == _AssignmentKind.PREFIX_INC) {
+        AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
+      } else if (assignment == _AssignmentKind.PREFIX_NOT) {
+        AstFactory.prefixExpression(TokenType.BANG, expression);
+      } else if (assignment == _AssignmentKind.SIMPLE_LEFT) {
+        AstFactory.assignmentExpression(
+            expression, TokenType.EQ, AstFactory.identifier3("_"));
+      } else if (assignment == _AssignmentKind.SIMPLE_RIGHT) {
+        AstFactory.assignmentExpression(
+            AstFactory.identifier3("_"), TokenType.EQ, expression);
+      } else if (assignment == _AssignmentKind.NONE) {}
+      break;
+    }
+    return identifier;
+  }
+
+  /**
+   * Return the top-most node in the AST structure containing the given identifier.
+   *
+   * @param identifier the identifier in the AST structure being traversed
+   * @return the root of the AST structure containing the identifier
+   */
+  AstNode _topMostNode(SimpleIdentifier identifier) {
+    AstNode child = identifier;
+    AstNode parent = identifier.parent;
+    while (parent != null) {
+      child = parent;
+      parent = parent.parent;
+    }
+    return child;
+  }
+}
+
+@reflectiveTest
+class SimpleStringLiteralTest extends ParserTestCase {
+  void test_contentsEnd() {
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
+            .contentsEnd,
+        2);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString('"X"'), "X")
+            .contentsEnd,
+        2);
+
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString('"""X"""'), "X")
+            .contentsEnd,
+        4);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
+            .contentsEnd,
+        4);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("'''  \nX'''"), "X")
+            .contentsEnd,
+        7);
+
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
+            .contentsEnd,
+        3);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString('r"X"'), "X")
+            .contentsEnd,
+        3);
+
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString('r"""X"""'), "X")
+            .contentsEnd,
+        5);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
+            .contentsEnd,
+        5);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("r'''  \nX'''"), "X")
+            .contentsEnd,
+        8);
+  }
+
+  void test_contentsOffset() {
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
+            .contentsOffset,
+        1);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
+            .contentsOffset,
+        1);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
+            .contentsOffset,
+        3);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
+            .contentsOffset,
+        3);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
+            .contentsOffset,
+        2);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
+            .contentsOffset,
+        2);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
+            .contentsOffset,
+        4);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
+            .contentsOffset,
+        4);
+    // leading whitespace
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("''' \ \nX''"), "X")
+            .contentsOffset,
+        6);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString('r""" \ \nX"""'), "X")
+            .contentsOffset,
+        7);
+  }
+
+  void test_isMultiline() {
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
+            .isMultiline,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
+            .isMultiline,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
+            .isMultiline,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
+            .isMultiline,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
+            .isMultiline,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
+            .isMultiline,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
+            .isMultiline,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
+            .isMultiline,
+        isTrue);
+  }
+
+  void test_isRaw() {
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X").isRaw,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
+            .isRaw,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X")
+            .isRaw,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
+            .isRaw,
+        isFalse);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
+            .isRaw,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
+            .isRaw,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(
+                TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X")
+            .isRaw,
+        isTrue);
+    expect(
+        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
+            .isRaw,
+        isTrue);
+  }
+
+  void test_isSingleQuoted() {
+    // '
+    {
+      var token = TokenFactory.tokenFromString("'X'");
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isTrue);
+    }
+    // '''
+    {
+      var token = TokenFactory.tokenFromString("'''X'''");
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isTrue);
+    }
+    // "
+    {
+      var token = TokenFactory.tokenFromString('"X"');
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isFalse);
+    }
+    // """
+    {
+      var token = TokenFactory.tokenFromString('"""X"""');
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isFalse);
+    }
+  }
+
+  void test_isSingleQuoted_raw() {
+    // r'
+    {
+      var token = TokenFactory.tokenFromString("r'X'");
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isTrue);
+    }
+    // r'''
+    {
+      var token = TokenFactory.tokenFromString("r'''X'''");
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isTrue);
+    }
+    // r"
+    {
+      var token = TokenFactory.tokenFromString('r"X"');
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isFalse);
+    }
+    // r"""
+    {
+      var token = TokenFactory.tokenFromString('r"""X"""');
+      var node = new SimpleStringLiteral(token, null);
+      expect(node.isSingleQuoted, isFalse);
+    }
+  }
+
+  void test_simple() {
+    Token token = TokenFactory.tokenFromString("'value'");
+    SimpleStringLiteral stringLiteral = new SimpleStringLiteral(token, "value");
+    expect(stringLiteral.literal, same(token));
+    expect(stringLiteral.beginToken, same(token));
+    expect(stringLiteral.endToken, same(token));
+    expect(stringLiteral.value, "value");
+  }
+}
+
+@reflectiveTest
+class StringInterpolationTest extends ParserTestCase {
+  void test_contentsOffsetEnd() {
+    AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    // 'a${bb}ccc'
+    {
+      var ae = AstFactory.interpolationString("'a", "a");
+      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 1);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+    // '''a${bb}ccc'''
+    {
+      var ae = AstFactory.interpolationString("'''a", "a");
+      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 3);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+    // """a${bb}ccc"""
+    {
+      var ae = AstFactory.interpolationString('"""a', "a");
+      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 3);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+    // r'a${bb}ccc'
+    {
+      var ae = AstFactory.interpolationString("r'a", "a");
+      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 2);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+    // r'''a${bb}ccc'''
+    {
+      var ae = AstFactory.interpolationString("r'''a", "a");
+      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 4);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+    // r"""a${bb}ccc"""
+    {
+      var ae = AstFactory.interpolationString('r"""a', "a");
+      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
+      var cElement = new InterpolationString(cToken, 'ccc');
+      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
+      expect(node.contentsOffset, 4);
+      expect(node.contentsEnd, 10 + 4 - 1);
+    }
+  }
+
+  void test_isMultiline() {
+    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    // '
+    {
+      var a = AstFactory.interpolationString("'a", "a");
+      var c = AstFactory.interpolationString("ccc'", "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isMultiline, isFalse);
+    }
+    // '''
+    {
+      var a = AstFactory.interpolationString("'''a", "a");
+      var c = AstFactory.interpolationString("ccc'''", "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isMultiline, isTrue);
+    }
+    // "
+    {
+      var a = AstFactory.interpolationString('"a', "a");
+      var c = AstFactory.interpolationString('ccc"', "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isMultiline, isFalse);
+    }
+    // """
+    {
+      var a = AstFactory.interpolationString('"""a', "a");
+      var c = AstFactory.interpolationString('ccc"""', "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isMultiline, isTrue);
+    }
+  }
+
+  void test_isRaw() {
+    StringInterpolation node = AstFactory.string();
+    expect(node.isRaw, isFalse);
+  }
+
+  void test_isSingleQuoted() {
+    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
+    // "
+    {
+      var a = AstFactory.interpolationString('"a', "a");
+      var c = AstFactory.interpolationString('ccc"', "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isSingleQuoted, isFalse);
+    }
+    // """
+    {
+      var a = AstFactory.interpolationString('"""a', "a");
+      var c = AstFactory.interpolationString('ccc"""', "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isSingleQuoted, isFalse);
+    }
+    // '
+    {
+      var a = AstFactory.interpolationString("'a", "a");
+      var c = AstFactory.interpolationString("ccc'", "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isSingleQuoted, isTrue);
+    }
+    // '''
+    {
+      var a = AstFactory.interpolationString("'''a", "a");
+      var c = AstFactory.interpolationString("ccc'''", "ccc");
+      StringInterpolation node = AstFactory.string([a, b, c]);
+      expect(node.isSingleQuoted, isTrue);
+    }
+  }
+}
+
+@reflectiveTest
+class VariableDeclarationTest extends ParserTestCase {
+  void test_getDocumentationComment_onGrandParent() {
+    VariableDeclaration varDecl = AstFactory.variableDeclaration("a");
+    TopLevelVariableDeclaration decl =
+        AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
+    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+    expect(varDecl.documentationComment, isNull);
+    decl.documentationComment = comment;
+    expect(varDecl.documentationComment, isNotNull);
+    expect(decl.documentationComment, isNotNull);
+  }
+
+  void test_getDocumentationComment_onNode() {
+    VariableDeclaration decl = AstFactory.variableDeclaration("a");
+    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+    decl.documentationComment = comment;
+    expect(decl.documentationComment, isNotNull);
+  }
+}
+
+class _AssignmentKind {
+  static const _AssignmentKind BINARY = const _AssignmentKind('BINARY', 0);
+
+  static const _AssignmentKind COMPOUND_LEFT =
+      const _AssignmentKind('COMPOUND_LEFT', 1);
+
+  static const _AssignmentKind COMPOUND_RIGHT =
+      const _AssignmentKind('COMPOUND_RIGHT', 2);
+
+  static const _AssignmentKind POSTFIX_INC =
+      const _AssignmentKind('POSTFIX_INC', 3);
+
+  static const _AssignmentKind PREFIX_DEC =
+      const _AssignmentKind('PREFIX_DEC', 4);
+
+  static const _AssignmentKind PREFIX_INC =
+      const _AssignmentKind('PREFIX_INC', 5);
+
+  static const _AssignmentKind PREFIX_NOT =
+      const _AssignmentKind('PREFIX_NOT', 6);
+
+  static const _AssignmentKind SIMPLE_LEFT =
+      const _AssignmentKind('SIMPLE_LEFT', 7);
+
+  static const _AssignmentKind SIMPLE_RIGHT =
+      const _AssignmentKind('SIMPLE_RIGHT', 8);
+
+  static const _AssignmentKind NONE = const _AssignmentKind('NONE', 9);
+
+  static const List<_AssignmentKind> values = const [
+    BINARY,
+    COMPOUND_LEFT,
+    COMPOUND_RIGHT,
+    POSTFIX_INC,
+    PREFIX_DEC,
+    PREFIX_INC,
+    PREFIX_NOT,
+    SIMPLE_LEFT,
+    SIMPLE_RIGHT,
+    NONE
+  ];
+
+  final String name;
+
+  final int ordinal;
+
+  const _AssignmentKind(this.name, this.ordinal);
+
+  int get hashCode => ordinal;
+
+  int compareTo(_AssignmentKind other) => ordinal - other.ordinal;
+
+  String toString() => name;
+}
+
+class _WrapperKind {
+  static const _WrapperKind PREFIXED_LEFT =
+      const _WrapperKind('PREFIXED_LEFT', 0);
+
+  static const _WrapperKind PREFIXED_RIGHT =
+      const _WrapperKind('PREFIXED_RIGHT', 1);
+
+  static const _WrapperKind PROPERTY_LEFT =
+      const _WrapperKind('PROPERTY_LEFT', 2);
+
+  static const _WrapperKind PROPERTY_RIGHT =
+      const _WrapperKind('PROPERTY_RIGHT', 3);
+
+  static const _WrapperKind NONE = const _WrapperKind('NONE', 4);
+
+  static const List<_WrapperKind> values = const [
+    PREFIXED_LEFT,
+    PREFIXED_RIGHT,
+    PROPERTY_LEFT,
+    PROPERTY_RIGHT,
+    NONE
+  ];
+
+  final String name;
+
+  final int ordinal;
+
+  const _WrapperKind(this.name, this.ordinal);
+
+  int get hashCode => ordinal;
+
+  int compareTo(_WrapperKind other) => ordinal - other.ordinal;
+
+  String toString() => name;
+}
diff --git a/pkg/analyzer/test/dart/ast/test_all.dart b/pkg/analyzer/test/dart/ast/test_all.dart
new file mode 100644
index 0000000..64f8170
--- /dev/null
+++ b/pkg/analyzer/test/dart/ast/test_all.dart
@@ -0,0 +1,20 @@
+// 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.ast.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../utils.dart';
+import 'ast_test.dart' as ast;
+import 'visitor_test.dart' as visitor;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('ast tests', () {
+    ast.main();
+    visitor.main();
+  });
+}
diff --git a/pkg/analyzer/test/dart/ast/visitor_test.dart b/pkg/analyzer/test/dart/ast/visitor_test.dart
new file mode 100644
index 0000000..1645daa
--- /dev/null
+++ b/pkg/analyzer/test/dart/ast/visitor_test.dart
@@ -0,0 +1,79 @@
+// 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.ast.visitor_test;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/parser_test.dart' show ParserTestCase;
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(BreadthFirstVisitorTest);
+}
+
+@reflectiveTest
+class BreadthFirstVisitorTest extends ParserTestCase {
+  void test_it() {
+    String source = r'''
+class A {
+  bool get g => true;
+}
+class B {
+  int f() {
+    num q() {
+      return 3;
+    }
+  return q() + 4;
+  }
+}
+A f(var p) {
+  if ((p as A).g) {
+    return p;
+  } else {
+    return null;
+  }
+}''';
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(source);
+    List<AstNode> nodes = new List<AstNode>();
+    BreadthFirstVisitor<Object> visitor =
+        new _BreadthFirstVisitorTestHelper(nodes);
+    visitor.visitAllNodes(unit);
+    expect(nodes, hasLength(59));
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is CompilationUnit, CompilationUnit, nodes[0]);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is ClassDeclaration, ClassDeclaration, nodes[2]);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is FunctionDeclaration, FunctionDeclaration, nodes[3]);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is FunctionDeclarationStatement,
+        FunctionDeclarationStatement,
+        nodes[27]);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IntegerLiteral, IntegerLiteral, nodes[58]);
+    //3
+  }
+}
+
+/**
+ * A helper class used to collect the nodes that were visited and to preserve
+ * the order in which they were visited.
+ */
+class _BreadthFirstVisitorTestHelper extends BreadthFirstVisitor<Object> {
+  List<AstNode> nodes;
+
+  _BreadthFirstVisitorTestHelper(this.nodes) : super();
+
+  @override
+  Object visitNode(AstNode node) {
+    nodes.add(node);
+    return super.visitNode(node);
+  }
+}
diff --git a/pkg/analyzer/test/dart/element/test_all.dart b/pkg/analyzer/test/dart/element/test_all.dart
index 392c06a..5dac037 100644
--- a/pkg/analyzer/test/dart/element/test_all.dart
+++ b/pkg/analyzer/test/dart/element/test_all.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 analyzer.test.generated.test_all;
+library analyzer.test.dart.element.test_all;
 
 import 'package:unittest/unittest.dart';
 
@@ -12,7 +12,7 @@
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
-  group('generated tests', () {
+  group('element tests', () {
     element.main();
   });
 }
diff --git a/pkg/analyzer/test/dart/test_all.dart b/pkg/analyzer/test/dart/test_all.dart
index 669b706..df7ff55 100644
--- a/pkg/analyzer/test/dart/test_all.dart
+++ b/pkg/analyzer/test/dart/test_all.dart
@@ -7,12 +7,14 @@
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
+import 'ast/test_all.dart' as ast;
 import 'element/test_all.dart' as element;
 
 /// Utility for manually running all tests.
 main() {
   initializeTestEnvironment();
   group('dart tests', () {
+    ast.main();
     element.main();
   });
 }
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 625cf40..a61765d 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -7,6 +7,7 @@
 import 'dart:mirrors';
 
 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/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -15,7 +16,6 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:unittest/unittest.dart';
 
-import 'generated/ast_test.dart';
 import 'reflective_tests.dart';
 import 'utils.dart';
 
@@ -32,12 +32,6 @@
       ..check_explicit_values();
   }
 
-  void test_AssignmentKind() {
-    new EnumTester<AssignmentKind>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_CacheState() {
     new EnumTester<CacheState>()
       ..check_getters()
@@ -103,12 +97,6 @@
       ..check_getters()
       ..check_explicit_values();
   }
-
-  void test_WrapperKind() {
-    new EnumTester<WrapperKind>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index f8ca1dc..34b9797 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -4,11 +4,12 @@
 
 library analyzer.test.generated.all_the_rest_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart' hide ConstantEvaluator;
 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/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -25,26 +26,19 @@
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/task/dart.dart';
 import 'package:path/path.dart';
 import 'package:source_span/source_span.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
 import '../utils.dart';
-import 'engine_test.dart';
 import 'parser_test.dart';
 import 'resolver_test.dart';
 import 'test_support.dart';
 
 main() {
   initializeTestEnvironment();
-  runReflectiveTests(ConstantEvaluatorTest);
-  runReflectiveTests(ConstantFinderTest);
-  runReflectiveTests(ConstantValueComputerTest);
-  runReflectiveTests(ConstantVisitorTest);
   runReflectiveTests(ContentCacheTest);
   runReflectiveTests(CustomUriResolverTest);
   runReflectiveTests(DartObjectImplTest);
@@ -61,2120 +55,10 @@
   runReflectiveTests(ExitDetectorTest2);
   runReflectiveTests(FileBasedSourceTest);
   runReflectiveTests(FileUriResolverTest);
-  runReflectiveTests(ReferenceFinderTest);
   runReflectiveTests(SDKLibrariesReaderTest);
   runReflectiveTests(UriKindTest);
 }
 
-/**
- * Implementation of [ConstantEvaluationValidator] used during unit tests;
- * verifies that any nodes referenced during constant evaluation are present in
- * the dependency graph.
- */
-class ConstantEvaluationValidator_ForTest
-    implements ConstantEvaluationValidator {
-  ConstantValueComputer computer;
-
-  ConstantEvaluationTarget _nodeBeingEvaluated;
-
-  @override
-  void beforeComputeValue(ConstantEvaluationTarget constant) {
-    _nodeBeingEvaluated = constant;
-  }
-
-  @override
-  void beforeGetConstantInitializers(ConstructorElement constructor) {
-    // Make sure we properly recorded the dependency.
-    expect(
-        computer.referenceGraph.containsPath(_nodeBeingEvaluated, constructor),
-        isTrue);
-  }
-
-  @override
-  void beforeGetEvaluationResult(ConstantEvaluationTarget constant) {
-    // Make sure we properly recorded the dependency.
-    expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, constant),
-        isTrue);
-  }
-
-  @override
-  void beforeGetFieldEvaluationResult(FieldElementImpl field) {
-    // Make sure we properly recorded the dependency.
-    expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, field),
-        isTrue);
-  }
-
-  @override
-  void beforeGetParameterDefault(ParameterElement parameter) {
-    // Make sure we properly recorded the dependency.
-    expect(computer.referenceGraph.containsPath(_nodeBeingEvaluated, parameter),
-        isTrue);
-  }
-}
-
-@reflectiveTest
-class ConstantEvaluatorTest extends ResolverTestCase {
-  void fail_constructor() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_class() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_function() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_static() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_staticMethod() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_topLevel() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_identifier_typeParameter() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_prefixedIdentifier_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_prefixedIdentifier_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_propertyAccess_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_propertyAccess_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_simpleIdentifier_invalid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void fail_simpleIdentifier_valid() {
-    EvaluationResult result = _getExpressionValue("?");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value, null);
-  }
-
-  void test_bitAnd_int_int() {
-    _assertValue3(74 & 42, "74 & 42");
-  }
-
-  void test_bitNot() {
-    _assertValue3(~42, "~42");
-  }
-
-  void test_bitOr_int_int() {
-    _assertValue3(74 | 42, "74 | 42");
-  }
-
-  void test_bitXor_int_int() {
-    _assertValue3(74 ^ 42, "74 ^ 42");
-  }
-
-  void test_divide_double_double() {
-    _assertValue2(3.2 / 2.3, "3.2 / 2.3");
-  }
-
-  void test_divide_double_double_byZero() {
-    EvaluationResult result = _getExpressionValue("3.2 / 0.0");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value.type.name, "double");
-    expect(value.toDoubleValue().isInfinite, isTrue);
-  }
-
-  void test_divide_int_int() {
-    _assertValue2(1.5, "3 / 2");
-  }
-
-  void test_divide_int_int_byZero() {
-    EvaluationResult result = _getExpressionValue("3 / 0");
-    expect(result.isValid, isTrue);
-  }
-
-  void test_equal_boolean_boolean() {
-    _assertValue(false, "true == false");
-  }
-
-  void test_equal_int_int() {
-    _assertValue(false, "2 == 3");
-  }
-
-  void test_equal_invalidLeft() {
-    EvaluationResult result = _getExpressionValue("a == 3");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_equal_invalidRight() {
-    EvaluationResult result = _getExpressionValue("2 == a");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_equal_string_string() {
-    _assertValue(false, "'a' == 'b'");
-  }
-
-  void test_greaterThan_int_int() {
-    _assertValue(false, "2 > 3");
-  }
-
-  void test_greaterThanOrEqual_int_int() {
-    _assertValue(false, "2 >= 3");
-  }
-
-  void test_leftShift_int_int() {
-    _assertValue3(64, "16 << 2");
-  }
-
-  void test_lessThan_int_int() {
-    _assertValue(true, "2 < 3");
-  }
-
-  void test_lessThanOrEqual_int_int() {
-    _assertValue(true, "2 <= 3");
-  }
-
-  void test_literal_boolean_false() {
-    _assertValue(false, "false");
-  }
-
-  void test_literal_boolean_true() {
-    _assertValue(true, "true");
-  }
-
-  void test_literal_list() {
-    EvaluationResult result = _getExpressionValue("const ['a', 'b', 'c']");
-    expect(result.isValid, isTrue);
-  }
-
-  void test_literal_map() {
-    EvaluationResult result =
-        _getExpressionValue("const {'a' : 'm', 'b' : 'n', 'c' : 'o'}");
-    expect(result.isValid, isTrue);
-  }
-
-  void test_literal_null() {
-    EvaluationResult result = _getExpressionValue("null");
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value.isNull, isTrue);
-  }
-
-  void test_literal_number_double() {
-    _assertValue2(3.45, "3.45");
-  }
-
-  void test_literal_number_integer() {
-    _assertValue3(42, "42");
-  }
-
-  void test_literal_string_adjacent() {
-    _assertValue4("abcdef", "'abc' 'def'");
-  }
-
-  void test_literal_string_interpolation_invalid() {
-    EvaluationResult result = _getExpressionValue("'a\${f()}c'");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_literal_string_interpolation_valid() {
-    _assertValue4("a3c", "'a\${3}c'");
-  }
-
-  void test_literal_string_simple() {
-    _assertValue4("abc", "'abc'");
-  }
-
-  void test_logicalAnd() {
-    _assertValue(false, "true && false");
-  }
-
-  void test_logicalNot() {
-    _assertValue(false, "!true");
-  }
-
-  void test_logicalOr() {
-    _assertValue(true, "true || false");
-  }
-
-  void test_minus_double_double() {
-    _assertValue2(3.2 - 2.3, "3.2 - 2.3");
-  }
-
-  void test_minus_int_int() {
-    _assertValue3(1, "3 - 2");
-  }
-
-  void test_negated_boolean() {
-    EvaluationResult result = _getExpressionValue("-true");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_negated_double() {
-    _assertValue2(-42.3, "-42.3");
-  }
-
-  void test_negated_integer() {
-    _assertValue3(-42, "-42");
-  }
-
-  void test_notEqual_boolean_boolean() {
-    _assertValue(true, "true != false");
-  }
-
-  void test_notEqual_int_int() {
-    _assertValue(true, "2 != 3");
-  }
-
-  void test_notEqual_invalidLeft() {
-    EvaluationResult result = _getExpressionValue("a != 3");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_notEqual_invalidRight() {
-    EvaluationResult result = _getExpressionValue("2 != a");
-    expect(result.isValid, isFalse);
-  }
-
-  void test_notEqual_string_string() {
-    _assertValue(true, "'a' != 'b'");
-  }
-
-  void test_parenthesizedExpression() {
-    _assertValue4("a", "('a')");
-  }
-
-  void test_plus_double_double() {
-    _assertValue2(2.3 + 3.2, "2.3 + 3.2");
-  }
-
-  void test_plus_int_int() {
-    _assertValue3(5, "2 + 3");
-  }
-
-  void test_plus_string_string() {
-    _assertValue4("ab", "'a' + 'b'");
-  }
-
-  void test_remainder_double_double() {
-    _assertValue2(3.2 % 2.3, "3.2 % 2.3");
-  }
-
-  void test_remainder_int_int() {
-    _assertValue3(2, "8 % 3");
-  }
-
-  void test_rightShift() {
-    _assertValue3(16, "64 >> 2");
-  }
-
-  void test_stringLength_complex() {
-    _assertValue3(6, "('qwe' + 'rty').length");
-  }
-
-  void test_stringLength_simple() {
-    _assertValue3(6, "'Dvorak'.length");
-  }
-
-  void test_times_double_double() {
-    _assertValue2(2.3 * 3.2, "2.3 * 3.2");
-  }
-
-  void test_times_int_int() {
-    _assertValue3(6, "2 * 3");
-  }
-
-  void test_truncatingDivide_double_double() {
-    _assertValue3(1, "3.2 ~/ 2.3");
-  }
-
-  void test_truncatingDivide_int_int() {
-    _assertValue3(3, "10 ~/ 3");
-  }
-
-  void _assertValue(bool expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
-    DartObject value = result.value;
-    expect(value.type.name, "bool");
-    expect(value.toBoolValue(), expectedValue);
-  }
-
-  void _assertValue2(double expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value.type.name, "double");
-    expect(value.toDoubleValue(), expectedValue);
-  }
-
-  void _assertValue3(int expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
-    expect(result.isValid, isTrue);
-    DartObject value = result.value;
-    expect(value.type.name, "int");
-    expect(value.toIntValue(), expectedValue);
-  }
-
-  void _assertValue4(String expectedValue, String contents) {
-    EvaluationResult result = _getExpressionValue(contents);
-    DartObject value = result.value;
-    expect(value, isNotNull);
-    ParameterizedType type = value.type;
-    expect(type, isNotNull);
-    expect(type.name, "String");
-    expect(value.toStringValue(), expectedValue);
-  }
-
-  EvaluationResult _getExpressionValue(String contents) {
-    Source source = addSource("var x = $contents;");
-    LibraryElement library = resolve2(source);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(source, library);
-    expect(unit, isNotNull);
-    NodeList<CompilationUnitMember> declarations = unit.declarations;
-    expect(declarations, hasLength(1));
-    CompilationUnitMember declaration = declarations[0];
-    EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableDeclaration,
-        TopLevelVariableDeclaration, declaration);
-    NodeList<VariableDeclaration> variables =
-        (declaration as TopLevelVariableDeclaration).variables.variables;
-    expect(variables, hasLength(1));
-    ConstantEvaluator evaluator = new ConstantEvaluator(
-        source, analysisContext.typeProvider,
-        typeSystem: analysisContext.typeSystem);
-    return evaluator.evaluate(variables[0].initializer);
-  }
-}
-
-@reflectiveTest
-class ConstantFinderTest {
-  AstNode _node;
-  TypeProvider _typeProvider;
-  AnalysisContext _context;
-  Source _source;
-
-  void setUp() {
-    _typeProvider = new TestTypeProvider();
-    _context = new TestAnalysisContext_ConstantFinderTest();
-    _source = new TestSource();
-  }
-
-  /**
-   * Test an annotation that consists solely of an identifier (and hence
-   * represents a reference to a compile-time constant variable).
-   */
-  void test_visitAnnotation_constantVariable() {
-    _node = AstFactory.annotation(AstFactory.identifier3('x'));
-    expect(_findAnnotations(), contains(_node));
-  }
-
-  /**
-   * Test an annotation that represents the invocation of a constant
-   * constructor.
-   */
-  void test_visitAnnotation_invocation() {
-    _node = AstFactory.annotation2(
-        AstFactory.identifier3('A'), null, AstFactory.argumentList());
-    expect(_findAnnotations(), contains(_node));
-  }
-
-  void test_visitConstructorDeclaration_const() {
-    ConstructorElement element = _setupConstructorDeclaration("A", true);
-    expect(_findConstants(), contains(element));
-  }
-
-  void test_visitConstructorDeclaration_nonConst() {
-    _setupConstructorDeclaration("A", false);
-    expect(_findConstants(), isEmpty);
-  }
-
-  void test_visitVariableDeclaration_const() {
-    VariableElement element = _setupVariableDeclaration("v", true, true);
-    expect(_findConstants(), contains(element));
-  }
-
-  void test_visitVariableDeclaration_final_inClass() {
-    _setupFieldDeclaration('C', 'f', Keyword.FINAL);
-    expect(_findConstants(), isEmpty);
-  }
-
-  void test_visitVariableDeclaration_final_inClassWithConstConstructor() {
-    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
-        hasConstConstructor: true);
-    expect(_findConstants(), contains(field.element));
-  }
-
-  void test_visitVariableDeclaration_final_outsideClass() {
-    _setupVariableDeclaration('v', false, true, isFinal: true);
-    expect(_findConstants(), isEmpty);
-  }
-
-  void test_visitVariableDeclaration_noInitializer() {
-    _setupVariableDeclaration("v", true, false);
-    expect(_findConstants(), isEmpty);
-  }
-
-  void test_visitVariableDeclaration_nonConst() {
-    _setupVariableDeclaration("v", false, true);
-    expect(_findConstants(), isEmpty);
-  }
-
-  void test_visitVariableDeclaration_static_const_inClass() {
-    VariableDeclaration field =
-        _setupFieldDeclaration('C', 'f', Keyword.CONST, isStatic: true);
-    expect(_findConstants(), contains(field.element));
-  }
-
-  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() {
-    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
-        isStatic: true, hasConstConstructor: true);
-    expect(_findConstants(), isNot(contains(field.element)));
-  }
-
-  void test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
-    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
-        isInitialized: false, hasConstConstructor: true);
-    expect(_findConstants(), isNot(contains(field.element)));
-  }
-
-  void test_visitVariableDeclaration_uninitialized_static_const_inClass() {
-    _setupFieldDeclaration('C', 'f', Keyword.CONST,
-        isStatic: true, isInitialized: false);
-    expect(_findConstants(), isEmpty);
-  }
-
-  List<Annotation> _findAnnotations() {
-    Set<Annotation> annotations = new Set<Annotation>();
-    for (ConstantEvaluationTarget target in _findConstants()) {
-      if (target is ConstantEvaluationTarget_Annotation) {
-        expect(target.context, same(_context));
-        expect(target.source, same(_source));
-        annotations.add(target.annotation);
-      }
-    }
-    return new List<Annotation>.from(annotations);
-  }
-
-  Set<ConstantEvaluationTarget> _findConstants() {
-    ConstantFinder finder = new ConstantFinder(_context, _source, _source);
-    _node.accept(finder);
-    Set<ConstantEvaluationTarget> constants = finder.constantsToCompute;
-    expect(constants, isNotNull);
-    return constants;
-  }
-
-  ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
-    Keyword constKeyword = isConst ? Keyword.CONST : null;
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration2(
-            constKeyword,
-            null,
-            null,
-            name,
-            AstFactory.formalParameterList(),
-            null,
-            AstFactory.blockFunctionBody2());
-    ClassElement classElement = ElementFactory.classElement2(name);
-    ConstructorElement element =
-        ElementFactory.constructorElement(classElement, name, isConst);
-    constructorDeclaration.element = element;
-    _node = constructorDeclaration;
-    return element;
-  }
-
-  VariableDeclaration _setupFieldDeclaration(
-      String className, String fieldName, Keyword keyword,
-      {bool isInitialized: true,
-      bool isStatic: false,
-      bool hasConstConstructor: false}) {
-    VariableDeclaration variableDeclaration = isInitialized
-        ? AstFactory.variableDeclaration2(fieldName, AstFactory.integer(0))
-        : AstFactory.variableDeclaration(fieldName);
-    VariableElement fieldElement = ElementFactory.fieldElement(
-        fieldName,
-        isStatic,
-        keyword == Keyword.FINAL,
-        keyword == Keyword.CONST,
-        _typeProvider.intType);
-    variableDeclaration.name.staticElement = fieldElement;
-    FieldDeclaration fieldDeclaration = AstFactory.fieldDeclaration2(
-        isStatic, keyword, <VariableDeclaration>[variableDeclaration]);
-    ClassDeclaration classDeclaration =
-        AstFactory.classDeclaration(null, className, null, null, null, null);
-    classDeclaration.members.add(fieldDeclaration);
-    _node = classDeclaration;
-    ClassElementImpl classElement = ElementFactory.classElement2(className);
-    classElement.fields = <FieldElement>[fieldElement];
-    classDeclaration.name.staticElement = classElement;
-    if (hasConstConstructor) {
-      ConstructorDeclaration constructorDeclaration = AstFactory
-          .constructorDeclaration2(
-              Keyword.CONST,
-              null,
-              AstFactory.identifier3(className),
-              null,
-              AstFactory.formalParameterList(),
-              null,
-              AstFactory.blockFunctionBody2());
-      classDeclaration.members.add(constructorDeclaration);
-      ConstructorElement constructorElement =
-          ElementFactory.constructorElement(classElement, '', true);
-      constructorDeclaration.element = constructorElement;
-      classElement.constructors = <ConstructorElement>[constructorElement];
-    } else {
-      classElement.constructors = ConstructorElement.EMPTY_LIST;
-    }
-    return variableDeclaration;
-  }
-
-  VariableElement _setupVariableDeclaration(
-      String name, bool isConst, bool isInitialized,
-      {isFinal: false}) {
-    VariableDeclaration variableDeclaration = isInitialized
-        ? AstFactory.variableDeclaration2(name, AstFactory.integer(0))
-        : AstFactory.variableDeclaration(name);
-    SimpleIdentifier identifier = variableDeclaration.name;
-    VariableElement element = ElementFactory.localVariableElement(identifier);
-    identifier.staticElement = element;
-    Keyword keyword = isConst ? Keyword.CONST : isFinal ? Keyword.FINAL : null;
-    AstFactory.variableDeclarationList2(keyword, [variableDeclaration]);
-    _node = variableDeclaration;
-    return element;
-  }
-}
-
-@reflectiveTest
-class ConstantValueComputerTest extends ResolverTestCase {
-  void test_annotation_constConstructor() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  final int i;
-  const A(this.i);
-}
-
-class C {
-  @A(5)
-  f() {}
-}
-''');
-    EvaluationResultImpl result =
-        _evaluateAnnotation(compilationUnit, "C", "f");
-    Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
-    _assertIntField(annotationFields, 'i', 5);
-  }
-
-  void test_annotation_constConstructor_named() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  final int i;
-  const A.named(this.i);
-}
-
-class C {
-  @A.named(5)
-  f() {}
-}
-''');
-    EvaluationResultImpl result =
-        _evaluateAnnotation(compilationUnit, "C", "f");
-    Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
-    _assertIntField(annotationFields, 'i', 5);
-  }
-
-  void test_annotation_constConstructor_noArgs() {
-    // Failing to pass arguments to an annotation which is a constant
-    // constructor is illegal, but shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  final int i;
-  const A(this.i);
-}
-
-class C {
-  @A
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_annotation_constConstructor_noArgs_named() {
-    // Failing to pass arguments to an annotation which is a constant
-    // constructor is illegal, but shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  final int i;
-  const A.named(this.i);
-}
-
-class C {
-  @A.named
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_annotation_nonConstConstructor() {
-    // Calling a non-const constructor from an annotation that is illegal, but
-    // shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  final int i;
-  A(this.i);
-}
-
-class C {
-  @A(5)
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_annotation_staticConst() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class C {
-  static const int i = 5;
-
-  @i
-  f() {}
-}
-''');
-    EvaluationResultImpl result =
-        _evaluateAnnotation(compilationUnit, "C", "f");
-    expect(_assertValidInt(result), 5);
-  }
-
-  void test_annotation_staticConst_args() {
-    // Applying arguments to an annotation that is a static const is
-    // illegal, but shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class C {
-  static const int i = 5;
-
-  @i(1)
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_annotation_staticConst_otherClass() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  static const int i = 5;
-}
-
-class C {
-  @A.i
-  f() {}
-}
-''');
-    EvaluationResultImpl result =
-        _evaluateAnnotation(compilationUnit, "C", "f");
-    expect(_assertValidInt(result), 5);
-  }
-
-  void test_annotation_staticConst_otherClass_args() {
-    // Applying arguments to an annotation that is a static const is
-    // illegal, but shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  static const int i = 5;
-}
-
-class C {
-  @A.i(1)
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_annotation_toplevelVariable() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const int i = 5;
-class C {
-  @i
-  f() {}
-}
-''');
-    EvaluationResultImpl result =
-        _evaluateAnnotation(compilationUnit, "C", "f");
-    expect(_assertValidInt(result), 5);
-  }
-
-  void test_annotation_toplevelVariable_args() {
-    // Applying arguments to an annotation that is a toplevel variable is
-    // illegal, but shouldn't crash analysis.
-    CompilationUnit compilationUnit = resolveSource(r'''
-const int i = 5;
-class C {
-  @i(1)
-  f() {}
-}
-''');
-    _evaluateAnnotation(compilationUnit, "C", "f");
-  }
-
-  void test_computeValues_cycle() {
-    TestLogger logger = new TestLogger();
-    AnalysisEngine.instance.logger = logger;
-    try {
-      Source librarySource = addSource(r'''
-  const int a = c;
-  const int b = a;
-  const int c = b;''');
-      LibraryElement libraryElement = resolve2(librarySource);
-      CompilationUnit unit =
-          analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-      analysisContext.computeErrors(librarySource);
-      expect(unit, isNotNull);
-      ConstantValueComputer computer = _makeConstantValueComputer();
-      computer.add(unit, librarySource, librarySource);
-      computer.computeValues();
-      NodeList<CompilationUnitMember> members = unit.declarations;
-      expect(members, hasLength(3));
-      _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
-      _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
-      _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
-    } finally {
-      AnalysisEngine.instance.logger = Logger.NULL;
-    }
-  }
-
-  void test_computeValues_dependentVariables() {
-    Source librarySource = addSource(r'''
-const int b = a;
-const int a = 0;''');
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, librarySource, librarySource);
-    computer.computeValues();
-    NodeList<CompilationUnitMember> members = unit.declarations;
-    expect(members, hasLength(2));
-    _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
-    _validate(true, (members[1] as TopLevelVariableDeclaration).variables);
-  }
-
-  void test_computeValues_empty() {
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.computeValues();
-  }
-
-  void test_computeValues_multipleSources() {
-    Source librarySource = addNamedSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';
-const int c = b;
-const int a = 0;''');
-    Source partSource = addNamedSource(
-        "/part.dart",
-        r'''
-part of lib;
-const int b = a;
-const int d = c;''');
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit libraryUnit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    expect(libraryUnit, isNotNull);
-    CompilationUnit partUnit =
-        analysisContext.resolveCompilationUnit(partSource, libraryElement);
-    expect(partUnit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(libraryUnit, librarySource, librarySource);
-    computer.add(partUnit, partSource, librarySource);
-    computer.computeValues();
-    NodeList<CompilationUnitMember> libraryMembers = libraryUnit.declarations;
-    expect(libraryMembers, hasLength(2));
-    _validate(
-        true, (libraryMembers[0] as TopLevelVariableDeclaration).variables);
-    _validate(
-        true, (libraryMembers[1] as TopLevelVariableDeclaration).variables);
-    NodeList<CompilationUnitMember> partMembers = libraryUnit.declarations;
-    expect(partMembers, hasLength(2));
-    _validate(true, (partMembers[0] as TopLevelVariableDeclaration).variables);
-    _validate(true, (partMembers[1] as TopLevelVariableDeclaration).variables);
-  }
-
-  void test_computeValues_singleVariable() {
-    Source librarySource = addSource("const int a = 0;");
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, librarySource, librarySource);
-    computer.computeValues();
-    NodeList<CompilationUnitMember> members = unit.declarations;
-    expect(members, hasLength(1));
-    _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
-  }
-
-  void test_computeValues_value_depends_on_enum() {
-    Source librarySource = addSource('''
-enum E { id0, id1 }
-const E e = E.id0;
-''');
-    LibraryElement libraryElement = resolve2(librarySource);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, librarySource, librarySource);
-    computer.computeValues();
-    TopLevelVariableDeclaration declaration = unit.declarations
-        .firstWhere((member) => member is TopLevelVariableDeclaration);
-    _validate(true, declaration.variables);
-  }
-
-  void test_dependencyOnConstructor() {
-    // x depends on "const A()"
-    _assertProperDependencies(r'''
-class A {
-  const A();
-}
-const x = const A();''');
-  }
-
-  void test_dependencyOnConstructorArgument() {
-    // "const A(x)" depends on x
-    _assertProperDependencies(r'''
-class A {
-  const A(this.next);
-  final A next;
-}
-const A x = const A(null);
-const A y = const A(x);''');
-  }
-
-  void test_dependencyOnConstructorArgument_unresolvedConstructor() {
-    // "const A.a(x)" depends on x even if the constructor A.a can't be found.
-    _assertProperDependencies(
-        r'''
-class A {
-}
-const int x = 1;
-const A y = const A.a(x);''',
-        [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
-  }
-
-  void test_dependencyOnConstructorInitializer() {
-    // "const A()" depends on x
-    _assertProperDependencies(r'''
-const int x = 1;
-class A {
-  const A() : v = x;
-  final int v;
-}''');
-  }
-
-  void test_dependencyOnExplicitSuperConstructor() {
-    // b depends on B() depends on A()
-    _assertProperDependencies(r'''
-class A {
-  const A(this.x);
-  final int x;
-}
-class B extends A {
-  const B() : super(5);
-}
-const B b = const B();''');
-  }
-
-  void test_dependencyOnExplicitSuperConstructorParameters() {
-    // b depends on B() depends on i
-    _assertProperDependencies(r'''
-class A {
-  const A(this.x);
-  final int x;
-}
-class B extends A {
-  const B() : super(i);
-}
-const B b = const B();
-const int i = 5;''');
-  }
-
-  void test_dependencyOnFactoryRedirect() {
-    // a depends on A.foo() depends on A.bar()
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-class A {
-  factory const A.foo() = A.bar;
-  const A.bar();
-}''');
-  }
-
-  void test_dependencyOnFactoryRedirectWithTypeParams() {
-    _assertProperDependencies(r'''
-class A {
-  const factory A(var a) = B<int>;
-}
-
-class B<T> implements A {
-  final T x;
-  const B(this.x);
-}
-
-const A a = const A(10);''');
-  }
-
-  void test_dependencyOnImplicitSuperConstructor() {
-    // b depends on B() depends on A()
-    _assertProperDependencies(r'''
-class A {
-  const A() : x = 5;
-  final int x;
-}
-class B extends A {
-  const B();
-}
-const B b = const B();''');
-  }
-
-  void test_dependencyOnInitializedFinal() {
-    // a depends on A() depends on A.x
-    _assertProperDependencies('''
-class A {
-  const A();
-  final int x = 1;
-}
-const A a = const A();
-''');
-  }
-
-  void test_dependencyOnInitializedNonStaticConst() {
-    // Even though non-static consts are not allowed by the language, we need
-    // to handle them for error recovery purposes.
-    // a depends on A() depends on A.x
-    _assertProperDependencies(
-        '''
-class A {
-  const A();
-  const int x = 1;
-}
-const A a = const A();
-''',
-        [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
-  }
-
-  void test_dependencyOnNonFactoryRedirect() {
-    // a depends on A.foo() depends on A.bar()
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-class A {
-  const A.foo() : this.bar();
-  const A.bar();
-}''');
-  }
-
-  void test_dependencyOnNonFactoryRedirect_arg() {
-    // a depends on A.foo() depends on b
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-const int b = 1;
-class A {
-  const A.foo() : this.bar(b);
-  const A.bar(x) : y = x;
-  final int y;
-}''');
-  }
-
-  void test_dependencyOnNonFactoryRedirect_defaultValue() {
-    // a depends on A.foo() depends on A.bar() depends on b
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-const int b = 1;
-class A {
-  const A.foo() : this.bar();
-  const A.bar([x = b]) : y = x;
-  final int y;
-}''');
-  }
-
-  void test_dependencyOnNonFactoryRedirect_toMissing() {
-    // a depends on A.foo() which depends on nothing, since A.bar() is
-    // missing.
-    _assertProperDependencies(
-        r'''
-const A a = const A.foo();
-class A {
-  const A.foo() : this.bar();
-}''',
-        [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
-  }
-
-  void test_dependencyOnNonFactoryRedirect_toNonConst() {
-    // a depends on A.foo() which depends on nothing, since A.bar() is
-    // non-const.
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-class A {
-  const A.foo() : this.bar();
-  A.bar();
-}''');
-  }
-
-  void test_dependencyOnNonFactoryRedirect_unnamed() {
-    // a depends on A.foo() depends on A()
-    _assertProperDependencies(r'''
-const A a = const A.foo();
-class A {
-  const A.foo() : this();
-  const A();
-}''');
-  }
-
-  void test_dependencyOnOptionalParameterDefault() {
-    // a depends on A() depends on B()
-    _assertProperDependencies(r'''
-class A {
-  const A([x = const B()]) : b = x;
-  final B b;
-}
-class B {
-  const B();
-}
-const A a = const A();''');
-  }
-
-  void test_dependencyOnVariable() {
-    // x depends on y
-    _assertProperDependencies(r'''
-const x = y + 1;
-const y = 2;''');
-  }
-
-  void test_final_initialized_at_declaration() {
-    CompilationUnit compilationUnit = resolveSource('''
-class A {
-  final int i = 123;
-  const A();
-}
-
-const A a = const A();
-''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, 'a');
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "i", 123);
-  }
-
-  void test_fromEnvironment_bool_default_false() {
-    expect(_assertValidBool(_check_fromEnvironment_bool(null, "false")), false);
-  }
-
-  void test_fromEnvironment_bool_default_overridden() {
-    expect(
-        _assertValidBool(_check_fromEnvironment_bool("false", "true")), false);
-  }
-
-  void test_fromEnvironment_bool_default_parseError() {
-    expect(_assertValidBool(_check_fromEnvironment_bool("parseError", "true")),
-        true);
-  }
-
-  void test_fromEnvironment_bool_default_true() {
-    expect(_assertValidBool(_check_fromEnvironment_bool(null, "true")), true);
-  }
-
-  void test_fromEnvironment_bool_false() {
-    expect(_assertValidBool(_check_fromEnvironment_bool("false", null)), false);
-  }
-
-  void test_fromEnvironment_bool_parseError() {
-    expect(_assertValidBool(_check_fromEnvironment_bool("parseError", null)),
-        false);
-  }
-
-  void test_fromEnvironment_bool_true() {
-    expect(_assertValidBool(_check_fromEnvironment_bool("true", null)), true);
-  }
-
-  void test_fromEnvironment_bool_undeclared() {
-    _assertValidUnknown(_check_fromEnvironment_bool(null, null));
-  }
-
-  void test_fromEnvironment_int_default_overridden() {
-    expect(_assertValidInt(_check_fromEnvironment_int("234", "123")), 234);
-  }
-
-  void test_fromEnvironment_int_default_parseError() {
-    expect(
-        _assertValidInt(_check_fromEnvironment_int("parseError", "123")), 123);
-  }
-
-  void test_fromEnvironment_int_default_undeclared() {
-    expect(_assertValidInt(_check_fromEnvironment_int(null, "123")), 123);
-  }
-
-  void test_fromEnvironment_int_ok() {
-    expect(_assertValidInt(_check_fromEnvironment_int("234", null)), 234);
-  }
-
-  void test_fromEnvironment_int_parseError() {
-    _assertValidNull(_check_fromEnvironment_int("parseError", null));
-  }
-
-  void test_fromEnvironment_int_parseError_nullDefault() {
-    _assertValidNull(_check_fromEnvironment_int("parseError", "null"));
-  }
-
-  void test_fromEnvironment_int_undeclared() {
-    _assertValidUnknown(_check_fromEnvironment_int(null, null));
-  }
-
-  void test_fromEnvironment_int_undeclared_nullDefault() {
-    _assertValidNull(_check_fromEnvironment_int(null, "null"));
-  }
-
-  void test_fromEnvironment_string_default_overridden() {
-    expect(_assertValidString(_check_fromEnvironment_string("abc", "'def'")),
-        "abc");
-  }
-
-  void test_fromEnvironment_string_default_undeclared() {
-    expect(_assertValidString(_check_fromEnvironment_string(null, "'def'")),
-        "def");
-  }
-
-  void test_fromEnvironment_string_empty() {
-    expect(_assertValidString(_check_fromEnvironment_string("", null)), "");
-  }
-
-  void test_fromEnvironment_string_ok() {
-    expect(
-        _assertValidString(_check_fromEnvironment_string("abc", null)), "abc");
-  }
-
-  void test_fromEnvironment_string_undeclared() {
-    _assertValidUnknown(_check_fromEnvironment_string(null, null));
-  }
-
-  void test_fromEnvironment_string_undeclared_nullDefault() {
-    _assertValidNull(_check_fromEnvironment_string(null, "null"));
-  }
-
-  void test_instanceCreationExpression_computedField() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A(4, 5);
-class A {
-  const A(int i, int j) : k = 2 * i + j;
-  final int k;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "k", 13);
-  }
-
-  void test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
-    _checkInstanceCreationOptionalParams(false, true, true);
-  }
-
-  void test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
-    _checkInstanceCreationOptionalParams(false, true, false);
-  }
-
-  void test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
-    _checkInstanceCreationOptionalParams(false, false, true);
-  }
-
-  void test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
-    _checkInstanceCreationOptionalParams(false, false, false);
-  }
-
-  void test_instanceCreationExpression_computedField_usesConstConstructor() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A(3);
-class A {
-  const A(int i) : b = const B(4);
-  final int b;
-}
-class B {
-  const B(this.k);
-  final int k;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fieldsOfA = _assertType(result, "A");
-    expect(fieldsOfA, hasLength(1));
-    Map<String, DartObjectImpl> fieldsOfB =
-        _assertFieldType(fieldsOfA, "b", "B");
-    expect(fieldsOfB, hasLength(1));
-    _assertIntField(fieldsOfB, "k", 4);
-  }
-
-  void test_instanceCreationExpression_computedField_usesStaticConst() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A(3);
-class A {
-  const A(int i) : k = i + B.bar;
-  final int k;
-}
-class B {
-  static const bar = 4;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "k", 7);
-  }
-
-  void test_instanceCreationExpression_computedField_usesToplevelConst() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A(3);
-const bar = 4;
-class A {
-  const A(int i) : k = i + bar;
-  final int k;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "k", 7);
-  }
-
-  void test_instanceCreationExpression_explicitSuper() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const B(4, 5);
-class A {
-  const A(this.x);
-  final int x;
-}
-class B extends A {
-  const B(int x, this.y) : super(x * 2);
-  final int y;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "B");
-    expect(fields, hasLength(2));
-    _assertIntField(fields, "y", 5);
-    Map<String, DartObjectImpl> superclassFields =
-        _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
-    expect(superclassFields, hasLength(1));
-    _assertIntField(superclassFields, "x", 8);
-  }
-
-  void test_instanceCreationExpression_fieldFormalParameter() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A(42);
-class A {
-  int x;
-  const A(this.x)
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "x", 42);
-  }
-
-  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
-    _checkInstanceCreationOptionalParams(true, true, true);
-  }
-
-  void test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
-    _checkInstanceCreationOptionalParams(true, true, false);
-  }
-
-  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
-    _checkInstanceCreationOptionalParams(true, false, true);
-  }
-
-  void test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
-    _checkInstanceCreationOptionalParams(true, false, false);
-  }
-
-  void test_instanceCreationExpression_implicitSuper() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const B(4);
-class A {
-  const A() : x = 3;
-  final int x;
-}
-class B extends A {
-  const B(this.y);
-  final int y;
-}''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    Map<String, DartObjectImpl> fields = _assertType(result, "B");
-    expect(fields, hasLength(2));
-    _assertIntField(fields, "y", 4);
-    Map<String, DartObjectImpl> superclassFields =
-        _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
-    expect(superclassFields, hasLength(1));
-    _assertIntField(superclassFields, "x", 3);
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1();
-class A {
-  const A.a1() : this.a2();
-  const A.a2() : x = 5;
-  final int x;
-}''');
-    Map<String, DartObjectImpl> aFields =
-        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-    _assertIntField(aFields, 'x', 5);
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_arg() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1(1);
-class A {
-  const A.a1(x) : this.a2(x + 100);
-  const A.a2(x) : y = x + 10;
-  final int y;
-}''');
-    Map<String, DartObjectImpl> aFields =
-        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-    _assertIntField(aFields, 'y', 111);
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_cycle() {
-    // It is an error to have a cycle in non-factory redirects; however, we
-    // need to make sure that even if the error occurs, attempting to evaluate
-    // the constant will terminate.
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A();
-class A {
-  const A() : this.b();
-  const A.b() : this();
-}''');
-    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_defaultArg() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1();
-class A {
-  const A.a1() : this.a2();
-  const A.a2([x = 100]) : y = x + 10;
-  final int y;
-}''');
-    Map<String, DartObjectImpl> aFields =
-        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-    _assertIntField(aFields, 'y', 110);
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_toMissing() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1();
-class A {
-  const A.a1() : this.a2();
-}''');
-    // We don't care what value foo evaluates to (since there is a compile
-    // error), but we shouldn't crash, and we should figure
-    // out that it evaluates to an instance of class A.
-    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_toNonConst() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1();
-class A {
-  const A.a1() : this.a2();
-  A.a2();
-}''');
-    // We don't care what value foo evaluates to (since there is a compile
-    // error), but we shouldn't crash, and we should figure
-    // out that it evaluates to an instance of class A.
-    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-  }
-
-  void test_instanceCreationExpression_nonFactoryRedirect_unnamed() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A.a1();
-class A {
-  const A.a1() : this();
-  const A() : x = 5;
-  final int x;
-}''');
-    Map<String, DartObjectImpl> aFields =
-        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
-    _assertIntField(aFields, 'x', 5);
-  }
-
-  void test_instanceCreationExpression_redirect() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A();
-class A {
-  const factory A() = B;
-}
-class B implements A {
-  const B();
-}''');
-    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "B");
-  }
-
-  void test_instanceCreationExpression_redirect_cycle() {
-    // It is an error to have a cycle in factory redirects; however, we need
-    // to make sure that even if the error occurs, attempting to evaluate the
-    // constant will terminate.
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A();
-class A {
-  const factory A() = A.b;
-  const factory A.b() = A;
-}''');
-    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
-  }
-
-  void test_instanceCreationExpression_redirect_extern() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A();
-class A {
-  external const factory A();
-}''');
-    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
-  }
-
-  void test_instanceCreationExpression_redirect_nonConst() {
-    // It is an error for a const factory constructor redirect to a non-const
-    // constructor; however, we need to make sure that even if the error
-    // attempting to evaluate the constant won't cause a crash.
-    CompilationUnit compilationUnit = resolveSource(r'''
-const foo = const A();
-class A {
-  const factory A() = A.b;
-  A.b();
-}''');
-    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
-  }
-
-  void test_instanceCreationExpression_redirectWithTypeParams() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A {
-  const factory A(var a) = B<int>;
-}
-
-class B<T> implements A {
-  final T x;
-  const B(this.x);
-}
-
-const A a = const A(10);''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "a");
-    Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "x", 10);
-  }
-
-  void test_instanceCreationExpression_redirectWithTypeSubstitution() {
-    // To evaluate the redirection of A<int>,
-    // A's template argument (T=int) must be substituted
-    // into B's template argument (B<U> where U=T) to get B<int>.
-    CompilationUnit compilationUnit = resolveSource(r'''
-class A<T> {
-  const factory A(var a) = B<T>;
-}
-
-class B<U> implements A {
-  final U x;
-  const B(this.x);
-}
-
-const A<int> a = const A<int>(10);''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, "a");
-    Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "x", 10);
-  }
-
-  void test_instanceCreationExpression_symbol() {
-    CompilationUnit compilationUnit =
-        resolveSource("const foo = const Symbol('a');");
-    EvaluationResultImpl evaluationResult =
-        _evaluateTopLevelVariable(compilationUnit, "foo");
-    expect(evaluationResult.value, isNotNull);
-    DartObjectImpl value = evaluationResult.value;
-    expect(value.type, typeProvider.symbolType);
-    expect(value.toSymbolValue(), "a");
-  }
-
-  void test_instanceCreationExpression_withSupertypeParams_explicit() {
-    _checkInstanceCreation_withSupertypeParams(true);
-  }
-
-  void test_instanceCreationExpression_withSupertypeParams_implicit() {
-    _checkInstanceCreation_withSupertypeParams(false);
-  }
-
-  void test_instanceCreationExpression_withTypeParams() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-class C<E> {
-  const C();
-}
-const c_int = const C<int>();
-const c_num = const C<num>();''');
-    EvaluationResultImpl c_int =
-        _evaluateTopLevelVariable(compilationUnit, "c_int");
-    _assertType(c_int, "C<int>");
-    DartObjectImpl c_int_value = c_int.value;
-    EvaluationResultImpl c_num =
-        _evaluateTopLevelVariable(compilationUnit, "c_num");
-    _assertType(c_num, "C<num>");
-    DartObjectImpl c_num_value = c_num.value;
-    expect(c_int_value == c_num_value, isFalse);
-  }
-
-  void test_isValidSymbol() {
-    expect(ConstantEvaluationEngine.isValidPublicSymbol(""), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$bar"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("iff"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("gif"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("if\$"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("\$if"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo="), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar="), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.+"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("void"), isTrue);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo.bar"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo._bar"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("if"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("if.foo"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.if"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo=.bar"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo."), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("+.foo"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("void.foo"), isFalse);
-    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.void"), isFalse);
-  }
-
-  void test_length_of_improperly_typed_string_expression() {
-    // Since type annotations are ignored in unchecked mode, the improper
-    // types on s1 and s2 shouldn't prevent us from evaluating i to
-    // 'alpha'.length.
-    CompilationUnit compilationUnit = resolveSource('''
-const int s1 = 'alpha';
-const int s2 = 'beta';
-const int i = (true ? s1 : s2).length;
-''');
-    ConstTopLevelVariableElementImpl element =
-        findTopLevelDeclaration(compilationUnit, 'i').element;
-    EvaluationResultImpl result = element.evaluationResult;
-    expect(_assertValidInt(result), 5);
-  }
-
-  void test_length_of_improperly_typed_string_identifier() {
-    // Since type annotations are ignored in unchecked mode, the improper type
-    // on s shouldn't prevent us from evaluating i to 'alpha'.length.
-    CompilationUnit compilationUnit = resolveSource('''
-const int s = 'alpha';
-const int i = s.length;
-''');
-    ConstTopLevelVariableElementImpl element =
-        findTopLevelDeclaration(compilationUnit, 'i').element;
-    EvaluationResultImpl result = element.evaluationResult;
-    expect(_assertValidInt(result), 5);
-  }
-
-  void test_non_static_const_initialized_at_declaration() {
-    // Even though non-static consts are not allowed by the language, we need
-    // to handle them for error recovery purposes.
-    CompilationUnit compilationUnit = resolveSource('''
-class A {
-  const int i = 123;
-  const A();
-}
-
-const A a = const A();
-''');
-    EvaluationResultImpl result =
-        _evaluateTopLevelVariable(compilationUnit, 'a');
-    Map<String, DartObjectImpl> fields = _assertType(result, "A");
-    expect(fields, hasLength(1));
-    _assertIntField(fields, "i", 123);
-  }
-
-  void test_symbolLiteral_void() {
-    CompilationUnit compilationUnit =
-        resolveSource("const voidSymbol = #void;");
-    VariableDeclaration voidSymbol =
-        findTopLevelDeclaration(compilationUnit, "voidSymbol");
-    EvaluationResultImpl voidSymbolResult =
-        (voidSymbol.element as VariableElementImpl).evaluationResult;
-    DartObjectImpl value = voidSymbolResult.value;
-    expect(value.type, typeProvider.symbolType);
-    expect(value.toSymbolValue(), "void");
-  }
-
-  Map<String, DartObjectImpl> _assertFieldType(
-      Map<String, DartObjectImpl> fields,
-      String fieldName,
-      String expectedType) {
-    DartObjectImpl field = fields[fieldName];
-    expect(field.type.displayName, expectedType);
-    return field.fields;
-  }
-
-  void _assertIntField(
-      Map<String, DartObjectImpl> fields, String fieldName, int expectedValue) {
-    DartObjectImpl field = fields[fieldName];
-    expect(field.type.name, "int");
-    expect(field.toIntValue(), expectedValue);
-  }
-
-  void _assertNullField(Map<String, DartObjectImpl> fields, String fieldName) {
-    DartObjectImpl field = fields[fieldName];
-    expect(field.isNull, isTrue);
-  }
-
-  void _assertProperDependencies(String sourceText,
-      [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
-    Source source = addSource(sourceText);
-    LibraryElement element = resolve2(source);
-    CompilationUnit unit =
-        analysisContext.resolveCompilationUnit(source, element);
-    expect(unit, isNotNull);
-    ConstantValueComputer computer = _makeConstantValueComputer();
-    computer.add(unit, source, source);
-    computer.computeValues();
-    assertErrors(source, expectedErrorCodes);
-  }
-
-  Map<String, DartObjectImpl> _assertType(
-      EvaluationResultImpl result, String typeName) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.type.displayName, typeName);
-    return value.fields;
-  }
-
-  bool _assertValidBool(EvaluationResultImpl result) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.type, typeProvider.boolType);
-    bool boolValue = value.toBoolValue();
-    expect(boolValue, isNotNull);
-    return boolValue;
-  }
-
-  int _assertValidInt(EvaluationResultImpl result) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.type, typeProvider.intType);
-    return value.toIntValue();
-  }
-
-  void _assertValidNull(EvaluationResultImpl result) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.type, typeProvider.nullType);
-  }
-
-  String _assertValidString(EvaluationResultImpl result) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.type, typeProvider.stringType);
-    return value.toStringValue();
-  }
-
-  void _assertValidUnknown(EvaluationResultImpl result) {
-    expect(result.value, isNotNull);
-    DartObjectImpl value = result.value;
-    expect(value.isUnknown, isTrue);
-  }
-
-  EvaluationResultImpl _check_fromEnvironment_bool(
-      String valueInEnvironment, String defaultExpr) {
-    String envVarName = "x";
-    String varName = "foo";
-    if (valueInEnvironment != null) {
-      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
-    }
-    String defaultArg =
-        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
-    CompilationUnit compilationUnit = resolveSource(
-        "const $varName = const bool.fromEnvironment('$envVarName'$defaultArg);");
-    return _evaluateTopLevelVariable(compilationUnit, varName);
-  }
-
-  EvaluationResultImpl _check_fromEnvironment_int(
-      String valueInEnvironment, String defaultExpr) {
-    String envVarName = "x";
-    String varName = "foo";
-    if (valueInEnvironment != null) {
-      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
-    }
-    String defaultArg =
-        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
-    CompilationUnit compilationUnit = resolveSource(
-        "const $varName = const int.fromEnvironment('$envVarName'$defaultArg);");
-    return _evaluateTopLevelVariable(compilationUnit, varName);
-  }
-
-  EvaluationResultImpl _check_fromEnvironment_string(
-      String valueInEnvironment, String defaultExpr) {
-    String envVarName = "x";
-    String varName = "foo";
-    if (valueInEnvironment != null) {
-      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
-    }
-    String defaultArg =
-        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
-    CompilationUnit compilationUnit = resolveSource(
-        "const $varName = const String.fromEnvironment('$envVarName'$defaultArg);");
-    return _evaluateTopLevelVariable(compilationUnit, varName);
-  }
-
-  void _checkInstanceCreation_withSupertypeParams(bool isExplicit) {
-    String superCall = isExplicit ? " : super()" : "";
-    CompilationUnit compilationUnit = resolveSource("""
-class A<T> {
-  const A();
-}
-class B<T, U> extends A<T> {
-  const B()$superCall;
-}
-class C<T, U> extends A<U> {
-  const C()$superCall;
-}
-const b_int_num = const B<int, num>();
-const c_int_num = const C<int, num>();""");
-    EvaluationResultImpl b_int_num =
-        _evaluateTopLevelVariable(compilationUnit, "b_int_num");
-    Map<String, DartObjectImpl> b_int_num_fields =
-        _assertType(b_int_num, "B<int, num>");
-    _assertFieldType(b_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<int>");
-    EvaluationResultImpl c_int_num =
-        _evaluateTopLevelVariable(compilationUnit, "c_int_num");
-    Map<String, DartObjectImpl> c_int_num_fields =
-        _assertType(c_int_num, "C<int, num>");
-    _assertFieldType(c_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<num>");
-  }
-
-  void _checkInstanceCreationOptionalParams(
-      bool isFieldFormal, bool isNamed, bool hasDefault) {
-    String fieldName = "j";
-    String paramName = isFieldFormal ? fieldName : "i";
-    String formalParam =
-        "${isFieldFormal ? "this." : "int "}$paramName${hasDefault ? " = 3" : ""}";
-    CompilationUnit compilationUnit = resolveSource("""
-const x = const A();
-const y = const A(${isNamed ? '$paramName: ' : ''}10);
-class A {
-  const A(${isNamed ? "{$formalParam}" : "[$formalParam]"})${isFieldFormal ? "" : " : $fieldName = $paramName"};
-  final int $fieldName;
-}""");
-    EvaluationResultImpl x = _evaluateTopLevelVariable(compilationUnit, "x");
-    Map<String, DartObjectImpl> fieldsOfX = _assertType(x, "A");
-    expect(fieldsOfX, hasLength(1));
-    if (hasDefault) {
-      _assertIntField(fieldsOfX, fieldName, 3);
-    } else {
-      _assertNullField(fieldsOfX, fieldName);
-    }
-    EvaluationResultImpl y = _evaluateTopLevelVariable(compilationUnit, "y");
-    Map<String, DartObjectImpl> fieldsOfY = _assertType(y, "A");
-    expect(fieldsOfY, hasLength(1));
-    _assertIntField(fieldsOfY, fieldName, 10);
-  }
-
-  /**
-   * Search [compilationUnit] for a class named [className], containing a
-   * method [methodName], with exactly one annotation.  Return the constant
-   * value of the annotation.
-   */
-  EvaluationResultImpl _evaluateAnnotation(
-      CompilationUnit compilationUnit, String className, String memberName) {
-    for (CompilationUnitMember member in compilationUnit.declarations) {
-      if (member is ClassDeclaration && member.name.name == className) {
-        for (ClassMember classMember in member.members) {
-          if (classMember is MethodDeclaration &&
-              classMember.name.name == memberName) {
-            expect(classMember.metadata, hasLength(1));
-            ElementAnnotationImpl elementAnnotation =
-                classMember.metadata[0].elementAnnotation;
-            return elementAnnotation.evaluationResult;
-          }
-        }
-      }
-    }
-    fail('Class member not found');
-    return null;
-  }
-
-  EvaluationResultImpl _evaluateTopLevelVariable(
-      CompilationUnit compilationUnit, String name) {
-    VariableDeclaration varDecl =
-        findTopLevelDeclaration(compilationUnit, name);
-    ConstTopLevelVariableElementImpl varElement = varDecl.element;
-    return varElement.evaluationResult;
-  }
-
-  ConstantValueComputer _makeConstantValueComputer() {
-    ConstantEvaluationValidator_ForTest validator =
-        new ConstantEvaluationValidator_ForTest();
-    validator.computer = new ConstantValueComputer(
-        analysisContext2,
-        analysisContext2.typeProvider,
-        analysisContext2.declaredVariables,
-        validator,
-        analysisContext2.typeSystem);
-    return validator.computer;
-  }
-
-  void _validate(bool shouldBeValid, VariableDeclarationList declarationList) {
-    for (VariableDeclaration declaration in declarationList.variables) {
-      VariableElementImpl element = declaration.element as VariableElementImpl;
-      expect(element, isNotNull);
-      EvaluationResultImpl result = element.evaluationResult;
-      if (shouldBeValid) {
-        expect(result.value, isNotNull);
-      } else {
-        expect(result.value, isNull);
-      }
-    }
-  }
-}
-
-@reflectiveTest
-class ConstantVisitorTest extends ResolverTestCase {
-  void test_visitConditionalExpression_false() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(false), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    _assertValue(
-        0,
-        expression.accept(new ConstantVisitor(
-            new ConstantEvaluationEngine(
-                new TestTypeProvider(), new DeclaredVariables(),
-                typeSystem: new TypeSystemImpl()),
-            errorReporter)));
-    errorListener.assertNoErrors();
-  }
-
-  void test_visitConditionalExpression_nonBooleanCondition() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    NullLiteral conditionExpression = AstFactory.nullLiteral();
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        conditionExpression, thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(
-            new TestTypeProvider(), new DeclaredVariables(),
-            typeSystem: new TypeSystemImpl()),
-        errorReporter));
-    expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
-  }
-
-  void test_visitConditionalExpression_nonConstantElse() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.identifier3("x");
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(
-            new TestTypeProvider(), new DeclaredVariables(),
-            typeSystem: new TypeSystemImpl()),
-        errorReporter));
-    expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
-  }
-
-  void test_visitConditionalExpression_nonConstantThen() {
-    Expression thenExpression = AstFactory.identifier3("x");
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    DartObjectImpl result = expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(
-            new TestTypeProvider(), new DeclaredVariables(),
-            typeSystem: new TypeSystemImpl()),
-        errorReporter));
-    expect(result, isNull);
-    errorListener
-        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
-  }
-
-  void test_visitConditionalExpression_true() {
-    Expression thenExpression = AstFactory.integer(1);
-    Expression elseExpression = AstFactory.integer(0);
-    ConditionalExpression expression = AstFactory.conditionalExpression(
-        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter =
-        new ErrorReporter(errorListener, _dummySource());
-    _assertValue(
-        1,
-        expression.accept(new ConstantVisitor(
-            new ConstantEvaluationEngine(
-                new TestTypeProvider(), new DeclaredVariables(),
-                typeSystem: new TypeSystemImpl()),
-            errorReporter)));
-    errorListener.assertNoErrors();
-  }
-
-  void test_visitSimpleIdentifier_className() {
-    CompilationUnit compilationUnit = resolveSource('''
-const a = C;
-class C {}
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
-    expect(result.type, typeProvider.typeType);
-    expect(result.toTypeValue().name, 'C');
-  }
-
-  void test_visitSimpleIdentifier_dynamic() {
-    CompilationUnit compilationUnit = resolveSource('''
-const a = dynamic;
-''');
-    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
-    expect(result.type, typeProvider.typeType);
-    expect(result.toTypeValue(), typeProvider.dynamicType);
-  }
-
-  void test_visitSimpleIdentifier_inEnvironment() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const a = b;
-const b = 3;''');
-    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
-    DartObjectImpl six =
-        new DartObjectImpl(typeProvider.intType, new IntState(6));
-    environment["b"] = six;
-    _assertValue(6, _evaluateConstant(compilationUnit, "a", environment));
-  }
-
-  void test_visitSimpleIdentifier_notInEnvironment() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const a = b;
-const b = 3;''');
-    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
-    DartObjectImpl six =
-        new DartObjectImpl(typeProvider.intType, new IntState(6));
-    environment["c"] = six;
-    _assertValue(3, _evaluateConstant(compilationUnit, "a", environment));
-  }
-
-  void test_visitSimpleIdentifier_withoutEnvironment() {
-    CompilationUnit compilationUnit = resolveSource(r'''
-const a = b;
-const b = 3;''');
-    _assertValue(3, _evaluateConstant(compilationUnit, "a", null));
-  }
-
-  void _assertValue(int expectedValue, DartObjectImpl result) {
-    expect(result, isNotNull);
-    expect(result.type.name, "int");
-    expect(result.toIntValue(), expectedValue);
-  }
-
-  NonExistingSource _dummySource() {
-    String path = '/test.dart';
-    return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
-  }
-
-  DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
-      Map<String, DartObjectImpl> lexicalEnvironment) {
-    Source source = compilationUnit.element.source;
-    Expression expression =
-        findTopLevelConstantExpression(compilationUnit, name);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-    DartObjectImpl result = expression.accept(new ConstantVisitor(
-        new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
-            typeSystem: typeSystem),
-        errorReporter,
-        lexicalEnvironment: lexicalEnvironment));
-    errorListener.assertNoErrors();
-    return result;
-  }
-}
-
 @reflectiveTest
 class ContentCacheTest {
   void test_setContents() {
@@ -4603,7 +2487,25 @@
 }
 
 @reflectiveTest
-class ElementBuilderTest extends EngineTestCase {
+class ElementBuilderTest extends ParserTestCase {
+  void fail_visitMethodDeclaration_setter_duplicate() {
+    // https://github.com/dart-lang/sdk/issues/25601
+    String code = r'''
+class C {
+  set zzz(x) {}
+  set zzz(y) {}
+}
+''';
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(code);
+    ElementHolder holder = new ElementHolder();
+    ElementBuilder builder = new ElementBuilder(holder);
+    unit.accept(builder);
+    ClassElement classElement = holder.types[0];
+    for (PropertyAccessorElement accessor in classElement.accessors) {
+      expect(accessor.variable.setter, same(accessor));
+    }
+  }
+
   void test_visitCatchClause() {
     // } catch (e, s) {
     ElementHolder holder = new ElementHolder();
@@ -4857,8 +2759,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),
@@ -4886,8 +2788,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),
@@ -4913,8 +2815,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),
@@ -4946,8 +2848,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),
@@ -4975,8 +2877,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),
@@ -5056,8 +2958,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);
@@ -6462,7 +4364,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,
@@ -6477,7 +4380,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,
@@ -6584,8 +4488,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");
@@ -6602,8 +4506,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");
@@ -8052,98 +5956,6 @@
 }
 
 @reflectiveTest
-class ReferenceFinderTest {
-  DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
-  VariableElement _head;
-  Element _tail;
-
-  void setUp() {
-    _referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
-    _head = ElementFactory.topLevelVariableElement2("v1");
-  }
-
-  void test_visitSimpleIdentifier_const() {
-    _visitNode(_makeTailVariable("v2", true));
-    _assertOneArc(_tail);
-  }
-
-  void test_visitSimpleIdentifier_nonConst() {
-    _visitNode(_makeTailVariable("v2", false));
-    _assertOneArc(_tail);
-  }
-
-  void test_visitSuperConstructorInvocation_const() {
-    _visitNode(_makeTailSuperConstructorInvocation("A", true));
-    _assertOneArc(_tail);
-  }
-
-  void test_visitSuperConstructorInvocation_nonConst() {
-    _visitNode(_makeTailSuperConstructorInvocation("A", false));
-    _assertOneArc(_tail);
-  }
-
-  void test_visitSuperConstructorInvocation_unresolved() {
-    SuperConstructorInvocation superConstructorInvocation =
-        AstFactory.superConstructorInvocation();
-    _visitNode(superConstructorInvocation);
-    _assertNoArcs();
-  }
-
-  void _assertNoArcs() {
-    Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
-    expect(tails, hasLength(0));
-  }
-
-  void _assertOneArc(Element tail) {
-    Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
-    expect(tails, hasLength(1));
-    expect(tails.first, same(tail));
-  }
-
-  ReferenceFinder _createReferenceFinder(ConstantEvaluationTarget source) =>
-      new ReferenceFinder((ConstantEvaluationTarget dependency) {
-        _referenceGraph.addEdge(source, dependency);
-      });
-  SuperConstructorInvocation _makeTailSuperConstructorInvocation(
-      String name, bool isConst) {
-    List<ConstructorInitializer> initializers =
-        new List<ConstructorInitializer>();
-    ConstructorDeclaration constructorDeclaration = AstFactory
-        .constructorDeclaration(AstFactory.identifier3(name), null,
-            AstFactory.formalParameterList(), initializers);
-    if (isConst) {
-      constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
-    }
-    ClassElementImpl classElement = ElementFactory.classElement2(name);
-    SuperConstructorInvocation superConstructorInvocation =
-        AstFactory.superConstructorInvocation();
-    ConstructorElementImpl constructorElement =
-        ElementFactory.constructorElement(classElement, name, isConst);
-    _tail = constructorElement;
-    superConstructorInvocation.staticElement = constructorElement;
-    return superConstructorInvocation;
-  }
-
-  SimpleIdentifier _makeTailVariable(String name, bool isConst) {
-    VariableDeclaration variableDeclaration =
-        AstFactory.variableDeclaration(name);
-    ConstLocalVariableElementImpl variableElement =
-        ElementFactory.constLocalVariableElement(name);
-    _tail = variableElement;
-    variableElement.const3 = isConst;
-    AstFactory.variableDeclarationList2(
-        isConst ? Keyword.CONST : Keyword.VAR, [variableDeclaration]);
-    SimpleIdentifier identifier = AstFactory.identifier3(name);
-    identifier.staticElement = variableElement;
-    return identifier;
-  }
-
-  void _visitNode(AstNode node) {
-    node.accept(_createReferenceFinder(_head));
-  }
-}
-
-@reflectiveTest
 class SDKLibrariesReaderTest extends EngineTestCase {
   void test_readFrom_dart2js() {
     LibraryMap libraryMap = new SdkLibrariesReader(true).readFromFile(
@@ -8218,16 +6030,6 @@
   }
 }
 
-class TestAnalysisContext_ConstantFinderTest extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_ConstantFinderTest();
-
-  @override
-  InternalAnalysisContext getContextFor(Source source) {
-    return this;
-  }
-}
-
 @reflectiveTest
 class UriKindTest {
   void test_fromEncoding() {
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 5f2abf5..15ef8ad 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -897,7 +897,8 @@
     // TODO(paulberry): the error CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE is
     // redundant and ought to be suppressed.
     assertErrors(source, [
-      CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
+      CompileTimeErrorCode
+          .CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
       CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
     ]);
     verify([source]);
@@ -1265,6 +1266,20 @@
     verify([source]);
   }
 
+  void test_constInitializedWithNonConstValue_finalField() {
+    // Regression test for bug #25526 which previously
+    // caused two errors to be reported.
+    Source source = addSource(r'''
+class Foo {
+  final field = [];
+  foo([int x = field]) {}
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALUE]);
+    verify([source]);
+  }
+
   void test_constInitializedWithNonConstValue_missingConstInListLiteral() {
     Source source = addSource("const List L = [0];");
     computeLibrarySourceErrors(source);
@@ -1291,7 +1306,8 @@
 import 'lib1.dart' deferred as a;
 const B = a.V;'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
     ]);
   }
 
@@ -1305,7 +1321,8 @@
 import 'lib1.dart' deferred as a;
 const B = a.V + 1;'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY
     ]);
   }
 
@@ -1827,7 +1844,8 @@
     verify([source]);
   }
 
-  void test_duplicateDefinitionInheritance_instanceGetterAbstract_staticGetter() {
+  void
+      test_duplicateDefinitionInheritance_instanceGetterAbstract_staticGetter() {
     Source source = addSource(r'''
 abstract class A {
   int get x;
@@ -1855,7 +1873,8 @@
     verify([source]);
   }
 
-  void test_duplicateDefinitionInheritance_instanceMethodAbstract_staticMethod() {
+  void
+      test_duplicateDefinitionInheritance_instanceMethodAbstract_staticMethod() {
     Source source = addSource(r'''
 abstract class A {
   x();
@@ -1883,7 +1902,8 @@
     verify([source]);
   }
 
-  void test_duplicateDefinitionInheritance_instanceSetterAbstract_staticSetter() {
+  void
+      test_duplicateDefinitionInheritance_instanceSetterAbstract_staticSetter() {
     Source source = addSource(r'''
 abstract class A {
   set x(value);
@@ -1967,9 +1987,7 @@
   void test_extendsDisallowedClass_class_double() {
     Source source = addSource("class A extends double {}");
     computeLibrarySourceErrors(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
-    ]);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
     verify([source]);
   }
 
@@ -1996,9 +2014,7 @@
   void test_extendsDisallowedClass_class_num() {
     Source source = addSource("class A extends num {}");
     computeLibrarySourceErrors(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS
-    ]);
+    assertErrors(source, [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]);
     verify([source]);
   }
 
@@ -2638,7 +2654,8 @@
     verify([source]);
   }
 
-  void test_implicitThisReferenceInInitializer_redirectingConstructorInvocation() {
+  void
+      test_implicitThisReferenceInInitializer_redirectingConstructorInvocation() {
     Source source = addSource(r'''
 class A {
   A(p) {}
@@ -3004,7 +3021,8 @@
     verify([source]);
   }
 
-  void test_invalidAnnotation_importWithPrefix_notVariableOrConstructorInvocation() {
+  void
+      test_invalidAnnotation_importWithPrefix_notVariableOrConstructorInvocation() {
     addNamedSource(
         "/lib.dart",
         r'''
@@ -4653,7 +4671,8 @@
   const A() : x = a.c;
 }'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
     ]);
   }
 
@@ -4670,7 +4689,8 @@
   const A() : x = a.c + 1;
 }'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
     ]);
   }
 
@@ -4687,7 +4707,8 @@
   const A() : this.named(a.c);
 }'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
     ]);
   }
 
@@ -4706,7 +4727,8 @@
   const B() : super(a.c);
 }'''
     ], <ErrorCode>[
-      CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
+      CompileTimeErrorCode
+          .NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
new file mode 100644
index 0000000..04592ff
--- /dev/null
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -0,0 +1,2290 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.constant_test;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:path/path.dart';
+import 'package:unittest/unittest.dart';
+
+import '../reflective_tests.dart';
+import '../utils.dart';
+import 'engine_test.dart';
+import 'resolver_test.dart';
+import 'test_support.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(ConstantEvaluatorTest);
+  runReflectiveTests(ConstantFinderTest);
+  runReflectiveTests(ConstantValueComputerTest);
+  runReflectiveTests(ConstantVisitorTest);
+  runReflectiveTests(ReferenceFinderTest);
+}
+
+/**
+ * Implementation of [ConstantEvaluationValidator] used during unit tests;
+ * verifies that any nodes referenced during constant evaluation are present in
+ * the dependency graph.
+ */
+class ConstantEvaluationValidator_ForTest
+    implements ConstantEvaluationValidator {
+  final InternalAnalysisContext context;
+  ConstantValueComputer computer;
+  ConstantEvaluationTarget _nodeBeingEvaluated;
+
+  ConstantEvaluationValidator_ForTest(this.context);
+
+  @override
+  void beforeComputeValue(ConstantEvaluationTarget constant) {
+    _nodeBeingEvaluated = constant;
+  }
+
+  @override
+  void beforeGetConstantInitializers(ConstructorElement constructor) =>
+      _checkPathTo(constructor);
+
+  @override
+  void beforeGetEvaluationResult(ConstantEvaluationTarget constant) =>
+      _checkPathTo(constant);
+
+  @override
+  void beforeGetFieldEvaluationResult(FieldElementImpl field) =>
+      _checkPathTo(field);
+
+  @override
+  void beforeGetParameterDefault(ParameterElement parameter) =>
+      _checkPathTo(parameter);
+
+  void _checkPathTo(ConstantEvaluationTarget target) {
+    if (computer.referenceGraph.containsPath(_nodeBeingEvaluated, target)) {
+      return; // pass
+    }
+    // print a nice error message on failure
+    StringBuffer out = new StringBuffer();
+    out.writeln("missing path in constant dependency graph");
+    out.writeln("from $_nodeBeingEvaluated to $target");
+    for (var s in context.analysisCache.sources) {
+      String text = context.getContents(s).data;
+      if (text != "") {
+        out.writeln('''
+=== ${s.shortName}
+$text''');
+      }
+    }
+    fail(out.toString());
+  }
+}
+
+@reflectiveTest
+class ConstantEvaluatorTest extends ResolverTestCase {
+  void fail_constructor() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_class() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_function() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_static() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_staticMethod() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_topLevel() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_identifier_typeParameter() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_prefixedIdentifier_invalid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_prefixedIdentifier_valid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_propertyAccess_invalid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_propertyAccess_valid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_simpleIdentifier_invalid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void fail_simpleIdentifier_valid() {
+    EvaluationResult result = _getExpressionValue("?");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value, null);
+  }
+
+  void test_bitAnd_int_int() {
+    _assertValue3(74 & 42, "74 & 42");
+  }
+
+  void test_bitNot() {
+    _assertValue3(~42, "~42");
+  }
+
+  void test_bitOr_int_int() {
+    _assertValue3(74 | 42, "74 | 42");
+  }
+
+  void test_bitXor_int_int() {
+    _assertValue3(74 ^ 42, "74 ^ 42");
+  }
+
+  void test_divide_double_double() {
+    _assertValue2(3.2 / 2.3, "3.2 / 2.3");
+  }
+
+  void test_divide_double_double_byZero() {
+    EvaluationResult result = _getExpressionValue("3.2 / 0.0");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value.type.name, "double");
+    expect(value.toDoubleValue().isInfinite, isTrue);
+  }
+
+  void test_divide_int_int() {
+    _assertValue2(1.5, "3 / 2");
+  }
+
+  void test_divide_int_int_byZero() {
+    EvaluationResult result = _getExpressionValue("3 / 0");
+    expect(result.isValid, isTrue);
+  }
+
+  void test_equal_boolean_boolean() {
+    _assertValue(false, "true == false");
+  }
+
+  void test_equal_int_int() {
+    _assertValue(false, "2 == 3");
+  }
+
+  void test_equal_invalidLeft() {
+    EvaluationResult result = _getExpressionValue("a == 3");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_equal_invalidRight() {
+    EvaluationResult result = _getExpressionValue("2 == a");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_equal_string_string() {
+    _assertValue(false, "'a' == 'b'");
+  }
+
+  void test_greaterThan_int_int() {
+    _assertValue(false, "2 > 3");
+  }
+
+  void test_greaterThanOrEqual_int_int() {
+    _assertValue(false, "2 >= 3");
+  }
+
+  void test_leftShift_int_int() {
+    _assertValue3(64, "16 << 2");
+  }
+
+  void test_lessThan_int_int() {
+    _assertValue(true, "2 < 3");
+  }
+
+  void test_lessThanOrEqual_int_int() {
+    _assertValue(true, "2 <= 3");
+  }
+
+  void test_literal_boolean_false() {
+    _assertValue(false, "false");
+  }
+
+  void test_literal_boolean_true() {
+    _assertValue(true, "true");
+  }
+
+  void test_literal_list() {
+    EvaluationResult result = _getExpressionValue("const ['a', 'b', 'c']");
+    expect(result.isValid, isTrue);
+  }
+
+  void test_literal_map() {
+    EvaluationResult result =
+        _getExpressionValue("const {'a' : 'm', 'b' : 'n', 'c' : 'o'}");
+    expect(result.isValid, isTrue);
+  }
+
+  void test_literal_null() {
+    EvaluationResult result = _getExpressionValue("null");
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value.isNull, isTrue);
+  }
+
+  void test_literal_number_double() {
+    _assertValue2(3.45, "3.45");
+  }
+
+  void test_literal_number_integer() {
+    _assertValue3(42, "42");
+  }
+
+  void test_literal_string_adjacent() {
+    _assertValue4("abcdef", "'abc' 'def'");
+  }
+
+  void test_literal_string_interpolation_invalid() {
+    EvaluationResult result = _getExpressionValue("'a\${f()}c'");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_literal_string_interpolation_valid() {
+    _assertValue4("a3c", "'a\${3}c'");
+  }
+
+  void test_literal_string_simple() {
+    _assertValue4("abc", "'abc'");
+  }
+
+  void test_logicalAnd() {
+    _assertValue(false, "true && false");
+  }
+
+  void test_logicalNot() {
+    _assertValue(false, "!true");
+  }
+
+  void test_logicalOr() {
+    _assertValue(true, "true || false");
+  }
+
+  void test_minus_double_double() {
+    _assertValue2(3.2 - 2.3, "3.2 - 2.3");
+  }
+
+  void test_minus_int_int() {
+    _assertValue3(1, "3 - 2");
+  }
+
+  void test_negated_boolean() {
+    EvaluationResult result = _getExpressionValue("-true");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_negated_double() {
+    _assertValue2(-42.3, "-42.3");
+  }
+
+  void test_negated_integer() {
+    _assertValue3(-42, "-42");
+  }
+
+  void test_notEqual_boolean_boolean() {
+    _assertValue(true, "true != false");
+  }
+
+  void test_notEqual_int_int() {
+    _assertValue(true, "2 != 3");
+  }
+
+  void test_notEqual_invalidLeft() {
+    EvaluationResult result = _getExpressionValue("a != 3");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_notEqual_invalidRight() {
+    EvaluationResult result = _getExpressionValue("2 != a");
+    expect(result.isValid, isFalse);
+  }
+
+  void test_notEqual_string_string() {
+    _assertValue(true, "'a' != 'b'");
+  }
+
+  void test_parenthesizedExpression() {
+    _assertValue4("a", "('a')");
+  }
+
+  void test_plus_double_double() {
+    _assertValue2(2.3 + 3.2, "2.3 + 3.2");
+  }
+
+  void test_plus_int_int() {
+    _assertValue3(5, "2 + 3");
+  }
+
+  void test_plus_string_string() {
+    _assertValue4("ab", "'a' + 'b'");
+  }
+
+  void test_remainder_double_double() {
+    _assertValue2(3.2 % 2.3, "3.2 % 2.3");
+  }
+
+  void test_remainder_int_int() {
+    _assertValue3(2, "8 % 3");
+  }
+
+  void test_rightShift() {
+    _assertValue3(16, "64 >> 2");
+  }
+
+  void test_stringLength_complex() {
+    _assertValue3(6, "('qwe' + 'rty').length");
+  }
+
+  void test_stringLength_simple() {
+    _assertValue3(6, "'Dvorak'.length");
+  }
+
+  void test_times_double_double() {
+    _assertValue2(2.3 * 3.2, "2.3 * 3.2");
+  }
+
+  void test_times_int_int() {
+    _assertValue3(6, "2 * 3");
+  }
+
+  void test_truncatingDivide_double_double() {
+    _assertValue3(1, "3.2 ~/ 2.3");
+  }
+
+  void test_truncatingDivide_int_int() {
+    _assertValue3(3, "10 ~/ 3");
+  }
+
+  void _assertValue(bool expectedValue, String contents) {
+    EvaluationResult result = _getExpressionValue(contents);
+    DartObject value = result.value;
+    expect(value.type.name, "bool");
+    expect(value.toBoolValue(), expectedValue);
+  }
+
+  void _assertValue2(double expectedValue, String contents) {
+    EvaluationResult result = _getExpressionValue(contents);
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value.type.name, "double");
+    expect(value.toDoubleValue(), expectedValue);
+  }
+
+  void _assertValue3(int expectedValue, String contents) {
+    EvaluationResult result = _getExpressionValue(contents);
+    expect(result.isValid, isTrue);
+    DartObject value = result.value;
+    expect(value.type.name, "int");
+    expect(value.toIntValue(), expectedValue);
+  }
+
+  void _assertValue4(String expectedValue, String contents) {
+    EvaluationResult result = _getExpressionValue(contents);
+    DartObject value = result.value;
+    expect(value, isNotNull);
+    ParameterizedType type = value.type;
+    expect(type, isNotNull);
+    expect(type.name, "String");
+    expect(value.toStringValue(), expectedValue);
+  }
+
+  EvaluationResult _getExpressionValue(String contents) {
+    Source source = addSource("var x = $contents;");
+    LibraryElement library = resolve2(source);
+    CompilationUnit unit =
+        analysisContext.resolveCompilationUnit(source, library);
+    expect(unit, isNotNull);
+    NodeList<CompilationUnitMember> declarations = unit.declarations;
+    expect(declarations, hasLength(1));
+    CompilationUnitMember declaration = declarations[0];
+    EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableDeclaration,
+        TopLevelVariableDeclaration, declaration);
+    NodeList<VariableDeclaration> variables =
+        (declaration as TopLevelVariableDeclaration).variables.variables;
+    expect(variables, hasLength(1));
+    ConstantEvaluator evaluator = new ConstantEvaluator(
+        source, analysisContext.typeProvider,
+        typeSystem: analysisContext.typeSystem);
+    return evaluator.evaluate(variables[0].initializer);
+  }
+}
+
+@reflectiveTest
+class ConstantFinderTest {
+  AstNode _node;
+  TypeProvider _typeProvider;
+  AnalysisContext _context;
+  Source _source;
+
+  void setUp() {
+    _typeProvider = new TestTypeProvider();
+    _context = new _TestAnalysisContext();
+    _source = new TestSource();
+  }
+
+  /**
+   * Test an annotation that consists solely of an identifier (and hence
+   * represents a reference to a compile-time constant variable).
+   */
+  void test_visitAnnotation_constantVariable() {
+    _node = AstFactory.annotation(AstFactory.identifier3('x'));
+    expect(_findAnnotations(), contains(_node));
+  }
+
+  /**
+   * Test an annotation that represents the invocation of a constant
+   * constructor.
+   */
+  void test_visitAnnotation_invocation() {
+    _node = AstFactory.annotation2(
+        AstFactory.identifier3('A'), null, AstFactory.argumentList());
+    expect(_findAnnotations(), contains(_node));
+  }
+
+  void test_visitConstructorDeclaration_const() {
+    ConstructorElement element = _setupConstructorDeclaration("A", true);
+    expect(_findConstants(), contains(element));
+  }
+
+  void test_visitConstructorDeclaration_nonConst() {
+    _setupConstructorDeclaration("A", false);
+    expect(_findConstants(), isEmpty);
+  }
+
+  void test_visitVariableDeclaration_const() {
+    VariableElement element = _setupVariableDeclaration("v", true, true);
+    expect(_findConstants(), contains(element));
+  }
+
+  void test_visitVariableDeclaration_final_inClass() {
+    _setupFieldDeclaration('C', 'f', Keyword.FINAL);
+    expect(_findConstants(), isEmpty);
+  }
+
+  void test_visitVariableDeclaration_final_inClassWithConstConstructor() {
+    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+        hasConstConstructor: true);
+    expect(_findConstants(), contains(field.element));
+  }
+
+  void test_visitVariableDeclaration_final_outsideClass() {
+    _setupVariableDeclaration('v', false, true, isFinal: true);
+    expect(_findConstants(), isEmpty);
+  }
+
+  void test_visitVariableDeclaration_noInitializer() {
+    _setupVariableDeclaration("v", true, false);
+    expect(_findConstants(), isEmpty);
+  }
+
+  void test_visitVariableDeclaration_nonConst() {
+    _setupVariableDeclaration("v", false, true);
+    expect(_findConstants(), isEmpty);
+  }
+
+  void test_visitVariableDeclaration_static_const_inClass() {
+    VariableDeclaration field =
+        _setupFieldDeclaration('C', 'f', Keyword.CONST, isStatic: true);
+    expect(_findConstants(), contains(field.element));
+  }
+
+  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() {
+    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+        isStatic: true, hasConstConstructor: true);
+    expect(_findConstants(), isNot(contains(field.element)));
+  }
+
+  void
+      test_visitVariableDeclaration_uninitialized_final_inClassWithConstConstructor() {
+    VariableDeclaration field = _setupFieldDeclaration('C', 'f', Keyword.FINAL,
+        isInitialized: false, hasConstConstructor: true);
+    expect(_findConstants(), isNot(contains(field.element)));
+  }
+
+  void test_visitVariableDeclaration_uninitialized_static_const_inClass() {
+    _setupFieldDeclaration('C', 'f', Keyword.CONST,
+        isStatic: true, isInitialized: false);
+    expect(_findConstants(), isEmpty);
+  }
+
+  List<Annotation> _findAnnotations() {
+    Set<Annotation> annotations = new Set<Annotation>();
+    for (ConstantEvaluationTarget target in _findConstants()) {
+      if (target is ConstantEvaluationTarget_Annotation) {
+        expect(target.context, same(_context));
+        expect(target.source, same(_source));
+        annotations.add(target.annotation);
+      }
+    }
+    return new List<Annotation>.from(annotations);
+  }
+
+  Set<ConstantEvaluationTarget> _findConstants() {
+    ConstantFinder finder = new ConstantFinder(_context, _source, _source);
+    _node.accept(finder);
+    Set<ConstantEvaluationTarget> constants = finder.constantsToCompute;
+    expect(constants, isNotNull);
+    return constants;
+  }
+
+  ConstructorElement _setupConstructorDeclaration(String name, bool isConst) {
+    Keyword constKeyword = isConst ? Keyword.CONST : null;
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration2(
+            constKeyword,
+            null,
+            null,
+            name,
+            AstFactory.formalParameterList(),
+            null,
+            AstFactory.blockFunctionBody2());
+    ClassElement classElement = ElementFactory.classElement2(name);
+    ConstructorElement element =
+        ElementFactory.constructorElement(classElement, name, isConst);
+    constructorDeclaration.element = element;
+    _node = constructorDeclaration;
+    return element;
+  }
+
+  VariableDeclaration _setupFieldDeclaration(
+      String className, String fieldName, Keyword keyword,
+      {bool isInitialized: true,
+      bool isStatic: false,
+      bool hasConstConstructor: false}) {
+    VariableDeclaration variableDeclaration = isInitialized
+        ? AstFactory.variableDeclaration2(fieldName, AstFactory.integer(0))
+        : AstFactory.variableDeclaration(fieldName);
+    VariableElement fieldElement = ElementFactory.fieldElement(
+        fieldName,
+        isStatic,
+        keyword == Keyword.FINAL,
+        keyword == Keyword.CONST,
+        _typeProvider.intType);
+    variableDeclaration.name.staticElement = fieldElement;
+    FieldDeclaration fieldDeclaration = AstFactory.fieldDeclaration2(
+        isStatic, keyword, <VariableDeclaration>[variableDeclaration]);
+    ClassDeclaration classDeclaration =
+        AstFactory.classDeclaration(null, className, null, null, null, null);
+    classDeclaration.members.add(fieldDeclaration);
+    _node = classDeclaration;
+    ClassElementImpl classElement = ElementFactory.classElement2(className);
+    classElement.fields = <FieldElement>[fieldElement];
+    classDeclaration.name.staticElement = classElement;
+    if (hasConstConstructor) {
+      ConstructorDeclaration constructorDeclaration =
+          AstFactory.constructorDeclaration2(
+              Keyword.CONST,
+              null,
+              AstFactory.identifier3(className),
+              null,
+              AstFactory.formalParameterList(),
+              null,
+              AstFactory.blockFunctionBody2());
+      classDeclaration.members.add(constructorDeclaration);
+      ConstructorElement constructorElement =
+          ElementFactory.constructorElement(classElement, '', true);
+      constructorDeclaration.element = constructorElement;
+      classElement.constructors = <ConstructorElement>[constructorElement];
+    } else {
+      classElement.constructors = ConstructorElement.EMPTY_LIST;
+    }
+    return variableDeclaration;
+  }
+
+  VariableElement _setupVariableDeclaration(
+      String name, bool isConst, bool isInitialized,
+      {isFinal: false}) {
+    VariableDeclaration variableDeclaration = isInitialized
+        ? AstFactory.variableDeclaration2(name, AstFactory.integer(0))
+        : AstFactory.variableDeclaration(name);
+    SimpleIdentifier identifier = variableDeclaration.name;
+    VariableElement element = ElementFactory.localVariableElement(identifier);
+    identifier.staticElement = element;
+    Keyword keyword = isConst ? Keyword.CONST : isFinal ? Keyword.FINAL : null;
+    AstFactory.variableDeclarationList2(keyword, [variableDeclaration]);
+    _node = variableDeclaration;
+    return element;
+  }
+}
+
+@reflectiveTest
+class ConstantValueComputerTest extends ResolverTestCase {
+  void test_annotation_constConstructor() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  final int i;
+  const A(this.i);
+}
+
+class C {
+  @A(5)
+  f() {}
+}
+''');
+    EvaluationResultImpl result =
+        _evaluateAnnotation(compilationUnit, "C", "f");
+    Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
+    _assertIntField(annotationFields, 'i', 5);
+  }
+
+  void test_annotation_constConstructor_named() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  final int i;
+  const A.named(this.i);
+}
+
+class C {
+  @A.named(5)
+  f() {}
+}
+''');
+    EvaluationResultImpl result =
+        _evaluateAnnotation(compilationUnit, "C", "f");
+    Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
+    _assertIntField(annotationFields, 'i', 5);
+  }
+
+  void test_annotation_constConstructor_noArgs() {
+    // Failing to pass arguments to an annotation which is a constant
+    // constructor is illegal, but shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  final int i;
+  const A(this.i);
+}
+
+class C {
+  @A
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_annotation_constConstructor_noArgs_named() {
+    // Failing to pass arguments to an annotation which is a constant
+    // constructor is illegal, but shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  final int i;
+  const A.named(this.i);
+}
+
+class C {
+  @A.named
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_annotation_nonConstConstructor() {
+    // Calling a non-const constructor from an annotation that is illegal, but
+    // shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  final int i;
+  A(this.i);
+}
+
+class C {
+  @A(5)
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_annotation_staticConst() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class C {
+  static const int i = 5;
+
+  @i
+  f() {}
+}
+''');
+    EvaluationResultImpl result =
+        _evaluateAnnotation(compilationUnit, "C", "f");
+    expect(_assertValidInt(result), 5);
+  }
+
+  void test_annotation_staticConst_args() {
+    // Applying arguments to an annotation that is a static const is
+    // illegal, but shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class C {
+  static const int i = 5;
+
+  @i(1)
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_annotation_staticConst_otherClass() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  static const int i = 5;
+}
+
+class C {
+  @A.i
+  f() {}
+}
+''');
+    EvaluationResultImpl result =
+        _evaluateAnnotation(compilationUnit, "C", "f");
+    expect(_assertValidInt(result), 5);
+  }
+
+  void test_annotation_staticConst_otherClass_args() {
+    // Applying arguments to an annotation that is a static const is
+    // illegal, but shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  static const int i = 5;
+}
+
+class C {
+  @A.i(1)
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_annotation_toplevelVariable() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const int i = 5;
+class C {
+  @i
+  f() {}
+}
+''');
+    EvaluationResultImpl result =
+        _evaluateAnnotation(compilationUnit, "C", "f");
+    expect(_assertValidInt(result), 5);
+  }
+
+  void test_annotation_toplevelVariable_args() {
+    // Applying arguments to an annotation that is a toplevel variable is
+    // illegal, but shouldn't crash analysis.
+    CompilationUnit compilationUnit = resolveSource(r'''
+const int i = 5;
+class C {
+  @i(1)
+  f() {}
+}
+''');
+    _evaluateAnnotation(compilationUnit, "C", "f");
+  }
+
+  void test_computeValues_cycle() {
+    TestLogger logger = new TestLogger();
+    AnalysisEngine.instance.logger = logger;
+    try {
+      Source source = addSource(r'''
+  const int a = c;
+  const int b = a;
+  const int c = b;''');
+      LibraryElement libraryElement = resolve2(source);
+      CompilationUnit unit =
+          analysisContext.resolveCompilationUnit(source, libraryElement);
+      analysisContext.computeErrors(source);
+      expect(unit, isNotNull);
+      ConstantValueComputer computer = _makeConstantValueComputer();
+      computer.add(unit, source, source);
+      computer.computeValues();
+      NodeList<CompilationUnitMember> members = unit.declarations;
+      expect(members, hasLength(3));
+      _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
+      _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
+    } finally {
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
+  }
+
+  void test_computeValues_dependentVariables() {
+    Source source = addSource(r'''
+const int b = a;
+const int a = 0;''');
+    LibraryElement libraryElement = resolve2(source);
+    CompilationUnit unit =
+        analysisContext.resolveCompilationUnit(source, libraryElement);
+    expect(unit, isNotNull);
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.add(unit, source, source);
+    computer.computeValues();
+    NodeList<CompilationUnitMember> members = unit.declarations;
+    expect(members, hasLength(2));
+    _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
+    _validate(true, (members[1] as TopLevelVariableDeclaration).variables);
+  }
+
+  void test_computeValues_empty() {
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.computeValues();
+  }
+
+  void test_computeValues_multipleSources() {
+    Source librarySource = addNamedSource(
+        "/lib.dart",
+        r'''
+library lib;
+part 'part.dart';
+const int c = b;
+const int a = 0;''');
+    Source partSource = addNamedSource(
+        "/part.dart",
+        r'''
+part of lib;
+const int b = a;
+const int d = c;''');
+    LibraryElement libraryElement = resolve2(librarySource);
+    CompilationUnit libraryUnit =
+        analysisContext.resolveCompilationUnit(librarySource, libraryElement);
+    expect(libraryUnit, isNotNull);
+    CompilationUnit partUnit =
+        analysisContext.resolveCompilationUnit(partSource, libraryElement);
+    expect(partUnit, isNotNull);
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.add(libraryUnit, librarySource, librarySource);
+    computer.add(partUnit, partSource, librarySource);
+    computer.computeValues();
+    NodeList<CompilationUnitMember> libraryMembers = libraryUnit.declarations;
+    expect(libraryMembers, hasLength(2));
+    _validate(
+        true, (libraryMembers[0] as TopLevelVariableDeclaration).variables);
+    _validate(
+        true, (libraryMembers[1] as TopLevelVariableDeclaration).variables);
+    NodeList<CompilationUnitMember> partMembers = libraryUnit.declarations;
+    expect(partMembers, hasLength(2));
+    _validate(true, (partMembers[0] as TopLevelVariableDeclaration).variables);
+    _validate(true, (partMembers[1] as TopLevelVariableDeclaration).variables);
+  }
+
+  void test_computeValues_singleVariable() {
+    Source source = addSource("const int a = 0;");
+    LibraryElement libraryElement = resolve2(source);
+    CompilationUnit unit =
+        analysisContext.resolveCompilationUnit(source, libraryElement);
+    expect(unit, isNotNull);
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.add(unit, source, source);
+    computer.computeValues();
+    NodeList<CompilationUnitMember> members = unit.declarations;
+    expect(members, hasLength(1));
+    _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
+  }
+
+  void test_computeValues_value_depends_on_enum() {
+    Source source = addSource('''
+enum E { id0, id1 }
+const E e = E.id0;
+''');
+    LibraryElement libraryElement = resolve2(source);
+    CompilationUnit unit =
+        analysisContext.resolveCompilationUnit(source, libraryElement);
+    expect(unit, isNotNull);
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.add(unit, source, source);
+    computer.computeValues();
+    TopLevelVariableDeclaration declaration = unit.declarations
+        .firstWhere((member) => member is TopLevelVariableDeclaration);
+    _validate(true, declaration.variables);
+  }
+
+  void test_dependencyOnConstructor() {
+    // x depends on "const A()"
+    _assertProperDependencies(r'''
+class A {
+  const A();
+}
+const x = const A();''');
+  }
+
+  void test_dependencyOnConstructorArgument() {
+    // "const A(x)" depends on x
+    _assertProperDependencies(r'''
+class A {
+  const A(this.next);
+  final A next;
+}
+const A x = const A(null);
+const A y = const A(x);''');
+  }
+
+  void test_dependencyOnConstructorArgument_unresolvedConstructor() {
+    // "const A.a(x)" depends on x even if the constructor A.a can't be found.
+    _assertProperDependencies(
+        r'''
+class A {
+}
+const int x = 1;
+const A y = const A.a(x);''',
+        [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
+  }
+
+  void test_dependencyOnConstructorInitializer() {
+    // "const A()" depends on x
+    _assertProperDependencies(r'''
+const int x = 1;
+class A {
+  const A() : v = x;
+  final int v;
+}''');
+  }
+
+  void test_dependencyOnExplicitSuperConstructor() {
+    // b depends on B() depends on A()
+    _assertProperDependencies(r'''
+class A {
+  const A(this.x);
+  final int x;
+}
+class B extends A {
+  const B() : super(5);
+}
+const B b = const B();''');
+  }
+
+  void test_dependencyOnExplicitSuperConstructorParameters() {
+    // b depends on B() depends on i
+    _assertProperDependencies(r'''
+class A {
+  const A(this.x);
+  final int x;
+}
+class B extends A {
+  const B() : super(i);
+}
+const B b = const B();
+const int i = 5;''');
+  }
+
+  void test_dependencyOnFactoryRedirect() {
+    // a depends on A.foo() depends on A.bar()
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+  factory const A.foo() = A.bar;
+  const A.bar();
+}''');
+  }
+
+  void test_dependencyOnFactoryRedirectWithTypeParams() {
+    _assertProperDependencies(r'''
+class A {
+  const factory A(var a) = B<int>;
+}
+
+class B<T> implements A {
+  final T x;
+  const B(this.x);
+}
+
+const A a = const A(10);''');
+  }
+
+  void test_dependencyOnImplicitSuperConstructor() {
+    // b depends on B() depends on A()
+    _assertProperDependencies(r'''
+class A {
+  const A() : x = 5;
+  final int x;
+}
+class B extends A {
+  const B();
+}
+const B b = const B();''');
+  }
+
+  void test_dependencyOnInitializedFinal() {
+    // a depends on A() depends on A.x
+    _assertProperDependencies('''
+class A {
+  const A();
+  final int x = 1;
+}
+const A a = const A();
+''');
+  }
+
+  void test_dependencyOnInitializedNonStaticConst() {
+    // Even though non-static consts are not allowed by the language, we need
+    // to handle them for error recovery purposes.
+    // a depends on A() depends on A.x
+    _assertProperDependencies(
+        '''
+class A {
+  const A();
+  const int x = 1;
+}
+const A a = const A();
+''',
+        [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
+  }
+
+  void test_dependencyOnNonFactoryRedirect() {
+    // a depends on A.foo() depends on A.bar()
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+  const A.foo() : this.bar();
+  const A.bar();
+}''');
+  }
+
+  void test_dependencyOnNonFactoryRedirect_arg() {
+    // a depends on A.foo() depends on b
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+const int b = 1;
+class A {
+  const A.foo() : this.bar(b);
+  const A.bar(x) : y = x;
+  final int y;
+}''');
+  }
+
+  void test_dependencyOnNonFactoryRedirect_defaultValue() {
+    // a depends on A.foo() depends on A.bar() depends on b
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+const int b = 1;
+class A {
+  const A.foo() : this.bar();
+  const A.bar([x = b]) : y = x;
+  final int y;
+}''');
+  }
+
+  void test_dependencyOnNonFactoryRedirect_toMissing() {
+    // a depends on A.foo() which depends on nothing, since A.bar() is
+    // missing.
+    _assertProperDependencies(
+        r'''
+const A a = const A.foo();
+class A {
+  const A.foo() : this.bar();
+}''',
+        [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
+  }
+
+  void test_dependencyOnNonFactoryRedirect_toNonConst() {
+    // a depends on A.foo() which depends on nothing, since A.bar() is
+    // non-const.
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+  const A.foo() : this.bar();
+  A.bar();
+}''');
+  }
+
+  void test_dependencyOnNonFactoryRedirect_unnamed() {
+    // a depends on A.foo() depends on A()
+    _assertProperDependencies(r'''
+const A a = const A.foo();
+class A {
+  const A.foo() : this();
+  const A();
+}''');
+  }
+
+  void test_dependencyOnOptionalParameterDefault() {
+    // a depends on A() depends on B()
+    _assertProperDependencies(r'''
+class A {
+  const A([x = const B()]) : b = x;
+  final B b;
+}
+class B {
+  const B();
+}
+const A a = const A();''');
+  }
+
+  void test_dependencyOnVariable() {
+    // x depends on y
+    _assertProperDependencies(r'''
+const x = y + 1;
+const y = 2;''');
+  }
+
+  void test_final_initialized_at_declaration() {
+    CompilationUnit compilationUnit = resolveSource('''
+class A {
+  final int i = 123;
+  const A();
+}
+
+const A a = const A();
+''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, 'a');
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "i", 123);
+  }
+
+  void test_fromEnvironment_bool_default_false() {
+    expect(_assertValidBool(_check_fromEnvironment_bool(null, "false")), false);
+  }
+
+  void test_fromEnvironment_bool_default_overridden() {
+    expect(
+        _assertValidBool(_check_fromEnvironment_bool("false", "true")), false);
+  }
+
+  void test_fromEnvironment_bool_default_parseError() {
+    expect(_assertValidBool(_check_fromEnvironment_bool("parseError", "true")),
+        true);
+  }
+
+  void test_fromEnvironment_bool_default_true() {
+    expect(_assertValidBool(_check_fromEnvironment_bool(null, "true")), true);
+  }
+
+  void test_fromEnvironment_bool_false() {
+    expect(_assertValidBool(_check_fromEnvironment_bool("false", null)), false);
+  }
+
+  void test_fromEnvironment_bool_parseError() {
+    expect(_assertValidBool(_check_fromEnvironment_bool("parseError", null)),
+        false);
+  }
+
+  void test_fromEnvironment_bool_true() {
+    expect(_assertValidBool(_check_fromEnvironment_bool("true", null)), true);
+  }
+
+  void test_fromEnvironment_bool_undeclared() {
+    _assertValidUnknown(_check_fromEnvironment_bool(null, null));
+  }
+
+  void test_fromEnvironment_int_default_overridden() {
+    expect(_assertValidInt(_check_fromEnvironment_int("234", "123")), 234);
+  }
+
+  void test_fromEnvironment_int_default_parseError() {
+    expect(
+        _assertValidInt(_check_fromEnvironment_int("parseError", "123")), 123);
+  }
+
+  void test_fromEnvironment_int_default_undeclared() {
+    expect(_assertValidInt(_check_fromEnvironment_int(null, "123")), 123);
+  }
+
+  void test_fromEnvironment_int_ok() {
+    expect(_assertValidInt(_check_fromEnvironment_int("234", null)), 234);
+  }
+
+  void test_fromEnvironment_int_parseError() {
+    _assertValidNull(_check_fromEnvironment_int("parseError", null));
+  }
+
+  void test_fromEnvironment_int_parseError_nullDefault() {
+    _assertValidNull(_check_fromEnvironment_int("parseError", "null"));
+  }
+
+  void test_fromEnvironment_int_undeclared() {
+    _assertValidUnknown(_check_fromEnvironment_int(null, null));
+  }
+
+  void test_fromEnvironment_int_undeclared_nullDefault() {
+    _assertValidNull(_check_fromEnvironment_int(null, "null"));
+  }
+
+  void test_fromEnvironment_string_default_overridden() {
+    expect(_assertValidString(_check_fromEnvironment_string("abc", "'def'")),
+        "abc");
+  }
+
+  void test_fromEnvironment_string_default_undeclared() {
+    expect(_assertValidString(_check_fromEnvironment_string(null, "'def'")),
+        "def");
+  }
+
+  void test_fromEnvironment_string_empty() {
+    expect(_assertValidString(_check_fromEnvironment_string("", null)), "");
+  }
+
+  void test_fromEnvironment_string_ok() {
+    expect(
+        _assertValidString(_check_fromEnvironment_string("abc", null)), "abc");
+  }
+
+  void test_fromEnvironment_string_undeclared() {
+    _assertValidUnknown(_check_fromEnvironment_string(null, null));
+  }
+
+  void test_fromEnvironment_string_undeclared_nullDefault() {
+    _assertValidNull(_check_fromEnvironment_string(null, "null"));
+  }
+
+  void test_instanceCreationExpression_computedField() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(4, 5);
+class A {
+  const A(int i, int j) : k = 2 * i + j;
+  final int k;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "k", 13);
+  }
+
+  void
+      test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
+    _checkInstanceCreationOptionalParams(false, true, true);
+  }
+
+  void
+      test_instanceCreationExpression_computedField_namedOptionalWithoutDefault() {
+    _checkInstanceCreationOptionalParams(false, true, false);
+  }
+
+  void
+      test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
+    _checkInstanceCreationOptionalParams(false, false, true);
+  }
+
+  void
+      test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefault() {
+    _checkInstanceCreationOptionalParams(false, false, false);
+  }
+
+  void test_instanceCreationExpression_computedField_usesConstConstructor() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+class A {
+  const A(int i) : b = const B(4);
+  final int b;
+}
+class B {
+  const B(this.k);
+  final int k;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fieldsOfA = _assertType(result, "A");
+    expect(fieldsOfA, hasLength(1));
+    Map<String, DartObjectImpl> fieldsOfB =
+        _assertFieldType(fieldsOfA, "b", "B");
+    expect(fieldsOfB, hasLength(1));
+    _assertIntField(fieldsOfB, "k", 4);
+  }
+
+  void test_instanceCreationExpression_computedField_usesStaticConst() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+class A {
+  const A(int i) : k = i + B.bar;
+  final int k;
+}
+class B {
+  static const bar = 4;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "k", 7);
+  }
+
+  void test_instanceCreationExpression_computedField_usesToplevelConst() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(3);
+const bar = 4;
+class A {
+  const A(int i) : k = i + bar;
+  final int k;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "k", 7);
+  }
+
+  void test_instanceCreationExpression_explicitSuper() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const B(4, 5);
+class A {
+  const A(this.x);
+  final int x;
+}
+class B extends A {
+  const B(int x, this.y) : super(x * 2);
+  final int y;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "B");
+    expect(fields, hasLength(2));
+    _assertIntField(fields, "y", 5);
+    Map<String, DartObjectImpl> superclassFields =
+        _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
+    expect(superclassFields, hasLength(1));
+    _assertIntField(superclassFields, "x", 8);
+  }
+
+  void test_instanceCreationExpression_fieldFormalParameter() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A(42);
+class A {
+  int x;
+  const A(this.x)
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "x", 42);
+  }
+
+  void
+      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefault() {
+    _checkInstanceCreationOptionalParams(true, true, true);
+  }
+
+  void
+      test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutDefault() {
+    _checkInstanceCreationOptionalParams(true, true, false);
+  }
+
+  void
+      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDefault() {
+    _checkInstanceCreationOptionalParams(true, false, true);
+  }
+
+  void
+      test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithoutDefault() {
+    _checkInstanceCreationOptionalParams(true, false, false);
+  }
+
+  void test_instanceCreationExpression_implicitSuper() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const B(4);
+class A {
+  const A() : x = 3;
+  final int x;
+}
+class B extends A {
+  const B(this.y);
+  final int y;
+}''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    Map<String, DartObjectImpl> fields = _assertType(result, "B");
+    expect(fields, hasLength(2));
+    _assertIntField(fields, "y", 4);
+    Map<String, DartObjectImpl> superclassFields =
+        _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
+    expect(superclassFields, hasLength(1));
+    _assertIntField(superclassFields, "x", 3);
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+  const A.a1() : this.a2();
+  const A.a2() : x = 5;
+  final int x;
+}''');
+    Map<String, DartObjectImpl> aFields =
+        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+    _assertIntField(aFields, 'x', 5);
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_arg() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1(1);
+class A {
+  const A.a1(x) : this.a2(x + 100);
+  const A.a2(x) : y = x + 10;
+  final int y;
+}''');
+    Map<String, DartObjectImpl> aFields =
+        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+    _assertIntField(aFields, 'y', 111);
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_cycle() {
+    // It is an error to have a cycle in non-factory redirects; however, we
+    // need to make sure that even if the error occurs, attempting to evaluate
+    // the constant will terminate.
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+  const A() : this.b();
+  const A.b() : this();
+}''');
+    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_defaultArg() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+  const A.a1() : this.a2();
+  const A.a2([x = 100]) : y = x + 10;
+  final int y;
+}''');
+    Map<String, DartObjectImpl> aFields =
+        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+    _assertIntField(aFields, 'y', 110);
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_toMissing() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+  const A.a1() : this.a2();
+}''');
+    // We don't care what value foo evaluates to (since there is a compile
+    // error), but we shouldn't crash, and we should figure
+    // out that it evaluates to an instance of class A.
+    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_toNonConst() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+  const A.a1() : this.a2();
+  A.a2();
+}''');
+    // We don't care what value foo evaluates to (since there is a compile
+    // error), but we shouldn't crash, and we should figure
+    // out that it evaluates to an instance of class A.
+    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+  }
+
+  void test_instanceCreationExpression_nonFactoryRedirect_unnamed() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A.a1();
+class A {
+  const A.a1() : this();
+  const A() : x = 5;
+  final int x;
+}''');
+    Map<String, DartObjectImpl> aFields =
+        _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
+    _assertIntField(aFields, 'x', 5);
+  }
+
+  void test_instanceCreationExpression_redirect() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+  const factory A() = B;
+}
+class B implements A {
+  const B();
+}''');
+    _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "B");
+  }
+
+  void test_instanceCreationExpression_redirect_cycle() {
+    // It is an error to have a cycle in factory redirects; however, we need
+    // to make sure that even if the error occurs, attempting to evaluate the
+    // constant will terminate.
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+  const factory A() = A.b;
+  const factory A.b() = A;
+}''');
+    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+  }
+
+  void test_instanceCreationExpression_redirect_extern() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+  external const factory A();
+}''');
+    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+  }
+
+  void test_instanceCreationExpression_redirect_nonConst() {
+    // It is an error for a const factory constructor redirect to a non-const
+    // constructor; however, we need to make sure that even if the error
+    // attempting to evaluate the constant won't cause a crash.
+    CompilationUnit compilationUnit = resolveSource(r'''
+const foo = const A();
+class A {
+  const factory A() = A.b;
+  A.b();
+}''');
+    _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
+  }
+
+  void test_instanceCreationExpression_redirectWithTypeParams() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A {
+  const factory A(var a) = B<int>;
+}
+
+class B<T> implements A {
+  final T x;
+  const B(this.x);
+}
+
+const A a = const A(10);''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "a");
+    Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "x", 10);
+  }
+
+  void test_instanceCreationExpression_redirectWithTypeSubstitution() {
+    // To evaluate the redirection of A<int>,
+    // A's template argument (T=int) must be substituted
+    // into B's template argument (B<U> where U=T) to get B<int>.
+    CompilationUnit compilationUnit = resolveSource(r'''
+class A<T> {
+  const factory A(var a) = B<T>;
+}
+
+class B<U> implements A {
+  final U x;
+  const B(this.x);
+}
+
+const A<int> a = const A<int>(10);''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, "a");
+    Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "x", 10);
+  }
+
+  void test_instanceCreationExpression_symbol() {
+    CompilationUnit compilationUnit =
+        resolveSource("const foo = const Symbol('a');");
+    EvaluationResultImpl evaluationResult =
+        _evaluateTopLevelVariable(compilationUnit, "foo");
+    expect(evaluationResult.value, isNotNull);
+    DartObjectImpl value = evaluationResult.value;
+    expect(value.type, typeProvider.symbolType);
+    expect(value.toSymbolValue(), "a");
+  }
+
+  void test_instanceCreationExpression_withSupertypeParams_explicit() {
+    _checkInstanceCreation_withSupertypeParams(true);
+  }
+
+  void test_instanceCreationExpression_withSupertypeParams_implicit() {
+    _checkInstanceCreation_withSupertypeParams(false);
+  }
+
+  void test_instanceCreationExpression_withTypeParams() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+class C<E> {
+  const C();
+}
+const c_int = const C<int>();
+const c_num = const C<num>();''');
+    EvaluationResultImpl c_int =
+        _evaluateTopLevelVariable(compilationUnit, "c_int");
+    _assertType(c_int, "C<int>");
+    DartObjectImpl c_int_value = c_int.value;
+    EvaluationResultImpl c_num =
+        _evaluateTopLevelVariable(compilationUnit, "c_num");
+    _assertType(c_num, "C<num>");
+    DartObjectImpl c_num_value = c_num.value;
+    expect(c_int_value == c_num_value, isFalse);
+  }
+
+  void test_isValidSymbol() {
+    expect(ConstantEvaluationEngine.isValidPublicSymbol(""), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$bar"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("iff"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("gif"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("if\$"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("\$if"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo="), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar="), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.+"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("void"), isTrue);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo.bar"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo._bar"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("if"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("if.foo"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.if"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo=.bar"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo."), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("+.foo"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("void.foo"), isFalse);
+    expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.void"), isFalse);
+  }
+
+  void test_length_of_improperly_typed_string_expression() {
+    // Since type annotations are ignored in unchecked mode, the improper
+    // types on s1 and s2 shouldn't prevent us from evaluating i to
+    // 'alpha'.length.
+    CompilationUnit compilationUnit = resolveSource('''
+const int s1 = 'alpha';
+const int s2 = 'beta';
+const int i = (true ? s1 : s2).length;
+''');
+    ConstTopLevelVariableElementImpl element =
+        findTopLevelDeclaration(compilationUnit, 'i').element;
+    EvaluationResultImpl result = element.evaluationResult;
+    expect(_assertValidInt(result), 5);
+  }
+
+  void test_length_of_improperly_typed_string_identifier() {
+    // Since type annotations are ignored in unchecked mode, the improper type
+    // on s shouldn't prevent us from evaluating i to 'alpha'.length.
+    CompilationUnit compilationUnit = resolveSource('''
+const int s = 'alpha';
+const int i = s.length;
+''');
+    ConstTopLevelVariableElementImpl element =
+        findTopLevelDeclaration(compilationUnit, 'i').element;
+    EvaluationResultImpl result = element.evaluationResult;
+    expect(_assertValidInt(result), 5);
+  }
+
+  void test_non_static_const_initialized_at_declaration() {
+    // Even though non-static consts are not allowed by the language, we need
+    // to handle them for error recovery purposes.
+    CompilationUnit compilationUnit = resolveSource('''
+class A {
+  const int i = 123;
+  const A();
+}
+
+const A a = const A();
+''');
+    EvaluationResultImpl result =
+        _evaluateTopLevelVariable(compilationUnit, 'a');
+    Map<String, DartObjectImpl> fields = _assertType(result, "A");
+    expect(fields, hasLength(1));
+    _assertIntField(fields, "i", 123);
+  }
+
+  void test_symbolLiteral_void() {
+    CompilationUnit compilationUnit =
+        resolveSource("const voidSymbol = #void;");
+    VariableDeclaration voidSymbol =
+        findTopLevelDeclaration(compilationUnit, "voidSymbol");
+    EvaluationResultImpl voidSymbolResult =
+        (voidSymbol.element as VariableElementImpl).evaluationResult;
+    DartObjectImpl value = voidSymbolResult.value;
+    expect(value.type, typeProvider.symbolType);
+    expect(value.toSymbolValue(), "void");
+  }
+
+  Map<String, DartObjectImpl> _assertFieldType(
+      Map<String, DartObjectImpl> fields,
+      String fieldName,
+      String expectedType) {
+    DartObjectImpl field = fields[fieldName];
+    expect(field.type.displayName, expectedType);
+    return field.fields;
+  }
+
+  void _assertIntField(
+      Map<String, DartObjectImpl> fields, String fieldName, int expectedValue) {
+    DartObjectImpl field = fields[fieldName];
+    expect(field.type.name, "int");
+    expect(field.toIntValue(), expectedValue);
+  }
+
+  void _assertNullField(Map<String, DartObjectImpl> fields, String fieldName) {
+    DartObjectImpl field = fields[fieldName];
+    expect(field.isNull, isTrue);
+  }
+
+  void _assertProperDependencies(String sourceText,
+      [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
+    Source source = addSource(sourceText);
+    LibraryElement element = resolve2(source);
+    CompilationUnit unit =
+        analysisContext.resolveCompilationUnit(source, element);
+    expect(unit, isNotNull);
+    ConstantValueComputer computer = _makeConstantValueComputer();
+    computer.add(unit, source, source);
+    computer.computeValues();
+    assertErrors(source, expectedErrorCodes);
+  }
+
+  Map<String, DartObjectImpl> _assertType(
+      EvaluationResultImpl result, String typeName) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.type.displayName, typeName);
+    return value.fields;
+  }
+
+  bool _assertValidBool(EvaluationResultImpl result) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.type, typeProvider.boolType);
+    bool boolValue = value.toBoolValue();
+    expect(boolValue, isNotNull);
+    return boolValue;
+  }
+
+  int _assertValidInt(EvaluationResultImpl result) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.type, typeProvider.intType);
+    return value.toIntValue();
+  }
+
+  void _assertValidNull(EvaluationResultImpl result) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.type, typeProvider.nullType);
+  }
+
+  String _assertValidString(EvaluationResultImpl result) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.type, typeProvider.stringType);
+    return value.toStringValue();
+  }
+
+  void _assertValidUnknown(EvaluationResultImpl result) {
+    expect(result.value, isNotNull);
+    DartObjectImpl value = result.value;
+    expect(value.isUnknown, isTrue);
+  }
+
+  EvaluationResultImpl _check_fromEnvironment_bool(
+      String valueInEnvironment, String defaultExpr) {
+    String envVarName = "x";
+    String varName = "foo";
+    if (valueInEnvironment != null) {
+      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+    }
+    String defaultArg =
+        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+    CompilationUnit compilationUnit = resolveSource(
+        "const $varName = const bool.fromEnvironment('$envVarName'$defaultArg);");
+    return _evaluateTopLevelVariable(compilationUnit, varName);
+  }
+
+  EvaluationResultImpl _check_fromEnvironment_int(
+      String valueInEnvironment, String defaultExpr) {
+    String envVarName = "x";
+    String varName = "foo";
+    if (valueInEnvironment != null) {
+      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+    }
+    String defaultArg =
+        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+    CompilationUnit compilationUnit = resolveSource(
+        "const $varName = const int.fromEnvironment('$envVarName'$defaultArg);");
+    return _evaluateTopLevelVariable(compilationUnit, varName);
+  }
+
+  EvaluationResultImpl _check_fromEnvironment_string(
+      String valueInEnvironment, String defaultExpr) {
+    String envVarName = "x";
+    String varName = "foo";
+    if (valueInEnvironment != null) {
+      analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
+    }
+    String defaultArg =
+        defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
+    CompilationUnit compilationUnit = resolveSource(
+        "const $varName = const String.fromEnvironment('$envVarName'$defaultArg);");
+    return _evaluateTopLevelVariable(compilationUnit, varName);
+  }
+
+  void _checkInstanceCreation_withSupertypeParams(bool isExplicit) {
+    String superCall = isExplicit ? " : super()" : "";
+    CompilationUnit compilationUnit = resolveSource("""
+class A<T> {
+  const A();
+}
+class B<T, U> extends A<T> {
+  const B()$superCall;
+}
+class C<T, U> extends A<U> {
+  const C()$superCall;
+}
+const b_int_num = const B<int, num>();
+const c_int_num = const C<int, num>();""");
+    EvaluationResultImpl b_int_num =
+        _evaluateTopLevelVariable(compilationUnit, "b_int_num");
+    Map<String, DartObjectImpl> b_int_num_fields =
+        _assertType(b_int_num, "B<int, num>");
+    _assertFieldType(b_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<int>");
+    EvaluationResultImpl c_int_num =
+        _evaluateTopLevelVariable(compilationUnit, "c_int_num");
+    Map<String, DartObjectImpl> c_int_num_fields =
+        _assertType(c_int_num, "C<int, num>");
+    _assertFieldType(c_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<num>");
+  }
+
+  void _checkInstanceCreationOptionalParams(
+      bool isFieldFormal, bool isNamed, bool hasDefault) {
+    String fieldName = "j";
+    String paramName = isFieldFormal ? fieldName : "i";
+    String formalParam =
+        "${isFieldFormal ? "this." : "int "}$paramName${hasDefault ? " = 3" : ""}";
+    CompilationUnit compilationUnit = resolveSource("""
+const x = const A();
+const y = const A(${isNamed ? '$paramName: ' : ''}10);
+class A {
+  const A(${isNamed ? "{$formalParam}" : "[$formalParam]"})${isFieldFormal ? "" : " : $fieldName = $paramName"};
+  final int $fieldName;
+}""");
+    EvaluationResultImpl x = _evaluateTopLevelVariable(compilationUnit, "x");
+    Map<String, DartObjectImpl> fieldsOfX = _assertType(x, "A");
+    expect(fieldsOfX, hasLength(1));
+    if (hasDefault) {
+      _assertIntField(fieldsOfX, fieldName, 3);
+    } else {
+      _assertNullField(fieldsOfX, fieldName);
+    }
+    EvaluationResultImpl y = _evaluateTopLevelVariable(compilationUnit, "y");
+    Map<String, DartObjectImpl> fieldsOfY = _assertType(y, "A");
+    expect(fieldsOfY, hasLength(1));
+    _assertIntField(fieldsOfY, fieldName, 10);
+  }
+
+  /**
+   * Search [compilationUnit] for a class named [className], containing a
+   * method [methodName], with exactly one annotation.  Return the constant
+   * value of the annotation.
+   */
+  EvaluationResultImpl _evaluateAnnotation(
+      CompilationUnit compilationUnit, String className, String memberName) {
+    for (CompilationUnitMember member in compilationUnit.declarations) {
+      if (member is ClassDeclaration && member.name.name == className) {
+        for (ClassMember classMember in member.members) {
+          if (classMember is MethodDeclaration &&
+              classMember.name.name == memberName) {
+            expect(classMember.metadata, hasLength(1));
+            ElementAnnotationImpl elementAnnotation =
+                classMember.metadata[0].elementAnnotation;
+            return elementAnnotation.evaluationResult;
+          }
+        }
+      }
+    }
+    fail('Class member not found');
+    return null;
+  }
+
+  EvaluationResultImpl _evaluateTopLevelVariable(
+      CompilationUnit compilationUnit, String name) {
+    VariableDeclaration varDecl =
+        findTopLevelDeclaration(compilationUnit, name);
+    ConstTopLevelVariableElementImpl varElement = varDecl.element;
+    return varElement.evaluationResult;
+  }
+
+  ConstantValueComputer _makeConstantValueComputer() {
+    ConstantEvaluationValidator_ForTest validator =
+        new ConstantEvaluationValidator_ForTest(analysisContext2);
+    validator.computer = new ConstantValueComputer(
+        analysisContext2,
+        analysisContext2.typeProvider,
+        analysisContext2.declaredVariables,
+        validator,
+        analysisContext2.typeSystem);
+    return validator.computer;
+  }
+
+  void _validate(bool shouldBeValid, VariableDeclarationList declarationList) {
+    for (VariableDeclaration declaration in declarationList.variables) {
+      VariableElementImpl element = declaration.element as VariableElementImpl;
+      expect(element, isNotNull);
+      EvaluationResultImpl result = element.evaluationResult;
+      if (shouldBeValid) {
+        expect(result.value, isNotNull);
+      } else {
+        expect(result.value, isNull);
+      }
+    }
+  }
+}
+
+@reflectiveTest
+class ConstantVisitorTest extends ResolverTestCase {
+  void test_visitBinaryExpression_questionQuestion_notNull_notNull() {
+    Expression left = AstFactory.string2('a');
+    Expression right = AstFactory.string2('b');
+    Expression expression =
+        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNotNull);
+    expect(result.isNull, isFalse);
+    expect(result.toStringValue(), 'a');
+    errorListener.assertNoErrors();
+  }
+
+  void test_visitBinaryExpression_questionQuestion_null_notNull() {
+    Expression left = AstFactory.nullLiteral();
+    Expression right = AstFactory.string2('b');
+    Expression expression =
+        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNotNull);
+    expect(result.isNull, isFalse);
+    expect(result.toStringValue(), 'b');
+    errorListener.assertNoErrors();
+  }
+
+  void test_visitBinaryExpression_questionQuestion_null_null() {
+    Expression left = AstFactory.nullLiteral();
+    Expression right = AstFactory.nullLiteral();
+    Expression expression =
+        AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
+
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNotNull);
+    expect(result.isNull, isTrue);
+    errorListener.assertNoErrors();
+  }
+
+  void test_visitConditionalExpression_false() {
+    Expression thenExpression = AstFactory.integer(1);
+    Expression elseExpression = AstFactory.integer(0);
+    ConditionalExpression expression = AstFactory.conditionalExpression(
+        AstFactory.booleanLiteral(false), thenExpression, elseExpression);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    _assertValue(0, _evaluate(expression, errorReporter));
+    errorListener.assertNoErrors();
+  }
+
+  void test_visitConditionalExpression_nonBooleanCondition() {
+    Expression thenExpression = AstFactory.integer(1);
+    Expression elseExpression = AstFactory.integer(0);
+    NullLiteral conditionExpression = AstFactory.nullLiteral();
+    ConditionalExpression expression = AstFactory.conditionalExpression(
+        conditionExpression, thenExpression, elseExpression);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNull);
+    errorListener
+        .assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
+  }
+
+  void test_visitConditionalExpression_nonConstantElse() {
+    Expression thenExpression = AstFactory.integer(1);
+    Expression elseExpression = AstFactory.identifier3("x");
+    ConditionalExpression expression = AstFactory.conditionalExpression(
+        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNull);
+    errorListener
+        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
+  }
+
+  void test_visitConditionalExpression_nonConstantThen() {
+    Expression thenExpression = AstFactory.identifier3("x");
+    Expression elseExpression = AstFactory.integer(0);
+    ConditionalExpression expression = AstFactory.conditionalExpression(
+        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    DartObjectImpl result = _evaluate(expression, errorReporter);
+    expect(result, isNull);
+    errorListener
+        .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
+  }
+
+  void test_visitConditionalExpression_true() {
+    Expression thenExpression = AstFactory.integer(1);
+    Expression elseExpression = AstFactory.integer(0);
+    ConditionalExpression expression = AstFactory.conditionalExpression(
+        AstFactory.booleanLiteral(true), thenExpression, elseExpression);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter =
+        new ErrorReporter(errorListener, _dummySource());
+    _assertValue(1, _evaluate(expression, errorReporter));
+    errorListener.assertNoErrors();
+  }
+
+  void test_visitSimpleIdentifier_className() {
+    CompilationUnit compilationUnit = resolveSource('''
+const a = C;
+class C {}
+''');
+    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+    expect(result.type, typeProvider.typeType);
+    expect(result.toTypeValue().name, 'C');
+  }
+
+  void test_visitSimpleIdentifier_dynamic() {
+    CompilationUnit compilationUnit = resolveSource('''
+const a = dynamic;
+''');
+    DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
+    expect(result.type, typeProvider.typeType);
+    expect(result.toTypeValue(), typeProvider.dynamicType);
+  }
+
+  void test_visitSimpleIdentifier_inEnvironment() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
+    DartObjectImpl six =
+        new DartObjectImpl(typeProvider.intType, new IntState(6));
+    environment["b"] = six;
+    _assertValue(6, _evaluateConstant(compilationUnit, "a", environment));
+  }
+
+  void test_visitSimpleIdentifier_notInEnvironment() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+    Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
+    DartObjectImpl six =
+        new DartObjectImpl(typeProvider.intType, new IntState(6));
+    environment["c"] = six;
+    _assertValue(3, _evaluateConstant(compilationUnit, "a", environment));
+  }
+
+  void test_visitSimpleIdentifier_withoutEnvironment() {
+    CompilationUnit compilationUnit = resolveSource(r'''
+const a = b;
+const b = 3;''');
+    _assertValue(3, _evaluateConstant(compilationUnit, "a", null));
+  }
+
+  void _assertValue(int expectedValue, DartObjectImpl result) {
+    expect(result, isNotNull);
+    expect(result.type.name, "int");
+    expect(result.toIntValue(), expectedValue);
+  }
+
+  NonExistingSource _dummySource() {
+    String path = '/test.dart';
+    return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
+  }
+
+  DartObjectImpl _evaluate(Expression expression, ErrorReporter errorReporter) {
+    return expression.accept(new ConstantVisitor(
+        new ConstantEvaluationEngine(
+            new TestTypeProvider(), new DeclaredVariables(),
+            typeSystem: new TypeSystemImpl()),
+        errorReporter));
+  }
+
+  DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
+      Map<String, DartObjectImpl> lexicalEnvironment) {
+    Source source = compilationUnit.element.source;
+    Expression expression =
+        findTopLevelConstantExpression(compilationUnit, name);
+    GatheringErrorListener errorListener = new GatheringErrorListener();
+    ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
+    DartObjectImpl result = expression.accept(new ConstantVisitor(
+        new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
+            typeSystem: typeSystem),
+        errorReporter,
+        lexicalEnvironment: lexicalEnvironment));
+    errorListener.assertNoErrors();
+    return result;
+  }
+}
+
+@reflectiveTest
+class ReferenceFinderTest {
+  DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
+  VariableElement _head;
+  Element _tail;
+
+  void setUp() {
+    _referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
+    _head = ElementFactory.topLevelVariableElement2("v1");
+  }
+
+  void test_visitSimpleIdentifier_const() {
+    _visitNode(_makeTailVariable("v2", true));
+    _assertOneArc(_tail);
+  }
+
+  void test_visitSuperConstructorInvocation_const() {
+    _visitNode(_makeTailSuperConstructorInvocation("A", true));
+    _assertOneArc(_tail);
+  }
+
+  void test_visitSuperConstructorInvocation_nonConst() {
+    _visitNode(_makeTailSuperConstructorInvocation("A", false));
+    _assertOneArc(_tail);
+  }
+
+  void test_visitSuperConstructorInvocation_unresolved() {
+    SuperConstructorInvocation superConstructorInvocation =
+        AstFactory.superConstructorInvocation();
+    _visitNode(superConstructorInvocation);
+    _assertNoArcs();
+  }
+
+  void _assertNoArcs() {
+    Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
+    expect(tails, hasLength(0));
+  }
+
+  void _assertOneArc(Element tail) {
+    Set<ConstantEvaluationTarget> tails = _referenceGraph.getTails(_head);
+    expect(tails, hasLength(1));
+    expect(tails.first, same(tail));
+  }
+
+  ReferenceFinder _createReferenceFinder(ConstantEvaluationTarget source) =>
+      new ReferenceFinder((ConstantEvaluationTarget dependency) {
+        _referenceGraph.addEdge(source, dependency);
+      });
+  SuperConstructorInvocation _makeTailSuperConstructorInvocation(
+      String name, bool isConst) {
+    List<ConstructorInitializer> initializers =
+        new List<ConstructorInitializer>();
+    ConstructorDeclaration constructorDeclaration =
+        AstFactory.constructorDeclaration(AstFactory.identifier3(name), null,
+            AstFactory.formalParameterList(), initializers);
+    if (isConst) {
+      constructorDeclaration.constKeyword = new KeywordToken(Keyword.CONST, 0);
+    }
+    ClassElementImpl classElement = ElementFactory.classElement2(name);
+    SuperConstructorInvocation superConstructorInvocation =
+        AstFactory.superConstructorInvocation();
+    ConstructorElementImpl constructorElement =
+        ElementFactory.constructorElement(classElement, name, isConst);
+    _tail = constructorElement;
+    superConstructorInvocation.staticElement = constructorElement;
+    return superConstructorInvocation;
+  }
+
+  SimpleIdentifier _makeTailVariable(String name, bool isConst) {
+    VariableDeclaration variableDeclaration =
+        AstFactory.variableDeclaration(name);
+    ConstLocalVariableElementImpl variableElement =
+        ElementFactory.constLocalVariableElement(name);
+    _tail = variableElement;
+    variableElement.const3 = isConst;
+    AstFactory.variableDeclarationList2(
+        isConst ? Keyword.CONST : Keyword.VAR, [variableDeclaration]);
+    SimpleIdentifier identifier = AstFactory.identifier3(name);
+    identifier.staticElement = variableElement;
+    return identifier;
+  }
+
+  void _visitNode(AstNode node) {
+    node.accept(_createReferenceFinder(_head));
+  }
+}
+
+class _TestAnalysisContext extends TestAnalysisContext {
+  @override
+  InternalAnalysisContext getContextFor(Source source) => this;
+}
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index 3dfae2b..188cc26 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -4,8 +4,9 @@
 
 library engine.declaration_resolver_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:unittest/unittest.dart';
@@ -35,6 +36,27 @@
 
 @reflectiveTest
 class DeclarationResolverTest extends ResolverTestCase {
+  void fail_visitMethodDeclaration_setter_duplicate() {
+    // https://github.com/dart-lang/sdk/issues/25601
+    String code = r'''
+class C {
+  set zzz(x) {}
+  set zzz(y) {}
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    PropertyAccessorElement firstElement =
+        _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement;
+    PropertyAccessorElement secondElement =
+        _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement;
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
+    SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)');
+    expect(firstName.staticElement, same(firstElement));
+    expect(secondName.staticElement, same(secondElement));
+  }
+
   @override
   void setUp() {
     super.setUp();
@@ -97,6 +119,47 @@
     SimpleIdentifier setterName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
     expect(setterName.staticElement, same(setterElement));
   }
+
+  void test_visitMethodDeclaration_getter_duplicate() {
+    String code = r'''
+class C {
+  int get zzz => 1;
+  String get zzz => null;
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    PropertyAccessorElement firstElement =
+        _findSimpleIdentifier(unit, code, 'zzz => 1').staticElement;
+    PropertyAccessorElement secondElement =
+        _findSimpleIdentifier(unit, code, 'zzz => null').staticElement;
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz => 1');
+    SimpleIdentifier secondName =
+        _findSimpleIdentifier(unit2, code, 'zzz => null');
+    expect(firstName.staticElement, same(firstElement));
+    expect(secondName.staticElement, same(secondElement));
+  }
+
+  void test_visitMethodDeclaration_method_duplicate() {
+    String code = r'''
+class C {
+  void zzz(x) {}
+  void zzz(y) {}
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    MethodElement firstElement =
+        _findSimpleIdentifier(unit, code, 'zzz(x)').staticElement;
+    MethodElement secondElement =
+        _findSimpleIdentifier(unit, code, 'zzz(y)').staticElement;
+    // re-resolve
+    CompilationUnit unit2 = _cloneResolveUnit(unit);
+    SimpleIdentifier firstName = _findSimpleIdentifier(unit2, code, 'zzz(x)');
+    SimpleIdentifier secondName = _findSimpleIdentifier(unit2, code, 'zzz(y)');
+    expect(firstName.staticElement, same(firstElement));
+    expect(secondName.staticElement, same(secondElement));
+  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index e2b20b3..ce630b1 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -6,10 +6,11 @@
 
 import 'dart:async';
 
+import 'package:analyzer/dart/ast/ast.dart';
 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/context/context.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -192,6 +193,9 @@
  */
 class TestAnalysisContext implements InternalAnalysisContext {
   @override
+  ResultProvider resultProvider;
+
+  @override
   AnalysisCache get analysisCache {
     fail("Unexpected invocation of analysisCache");
     return null;
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 6a52fce..3f3390b 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4,13 +4,14 @@
 
 library analyzer.test.generated.incremental_resolver_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.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;
+import 'package:analyzer/src/generated/incremental_logger.dart' as logging;
 import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
 import 'package:analyzer/src/generated/incremental_resolver.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -495,6 +496,20 @@
 ''');
   }
 
+  void test_false_constructor_parameters_name() {
+    _assertDoesNotMatch(
+        r'''
+class A {
+  A(int a);
+}
+''',
+        r'''
+class A {
+  A(int b);
+}
+''');
+  }
+
   void test_false_constructor_parameters_type_edit() {
     _assertDoesNotMatch(
         r'''
@@ -835,6 +850,22 @@
 ''');
   }
 
+  void test_false_fieldFormalParameter_changeName_wasUnresolvedField() {
+    _assertDoesNotMatch(
+        r'''
+class A {
+  final fff;
+  A(this.unresolved);
+}
+''',
+        r'''
+class A {
+  final fff;
+  A(this.fff);
+}
+''');
+  }
+
   void test_false_fieldFormalParameter_differentField() {
     _assertDoesNotMatch(
         r'''
@@ -2506,22 +2537,6 @@
 ''');
   }
 
-  void test_true_fieldFormalParameter_changeName_wasUnresolvedField() {
-    _assertMatches(
-        r'''
-class A {
-  final fff;
-  A(this.unresolved);
-}
-''',
-        r'''
-class A {
-  final fff;
-  A(this.fff);
-}
-''');
-  }
-
   void test_true_fieldFormalParameter_function() {
     _assertMatches(
         r'''
@@ -3092,7 +3107,7 @@
   void setUp() {
     super.setUp();
     test_resolveApiChanges = true;
-    log.logger = log.NULL_LOGGER;
+    logging.logger = logging.NULL_LOGGER;
   }
 
   void test_classMemberAccessor_body() {
@@ -3170,15 +3185,6 @@
     _resolve(_editString('+', '*'), _isExpression);
   }
 
-  void test_fieldFormalParameter() {
-    _resolveUnit(r'''
-class A {
-  int xy;
-  A(this.x);
-}''');
-    _resolve(_editString('this.x', 'this.xy'), _isDeclaration);
-  }
-
   void test_function_localFunction_add() {
     _resolveUnit(r'''
 int main() {
@@ -3523,6 +3529,8 @@
  */
 @reflectiveTest
 class PoorMansIncrementalResolutionTest extends ResolverTestCase {
+  final _TestLogger logger = new _TestLogger();
+
   Source source;
   String code;
   LibraryElement oldLibrary;
@@ -3800,23 +3808,6 @@
 ''');
   }
 
-  void test_endOfLineComment_localFunction_inTopLevelVariable() {
-    _resolveUnit(r'''
-typedef int Binary(one, two, three);
-
-int Global = f((a, b, c) {
-  return 0; // Some comment
-});
-''');
-    _updateAndValidate(r'''
-typedef int Binary(one, two, three);
-
-int Global = f((a, b, c) {
-  return 0; // Some  comment
-});
-''');
-  }
-
   void test_endOfLineComment_outBody_add() {
     _resolveUnit(r'''
 main() {
@@ -3886,6 +3877,25 @@
 ''');
   }
 
+  void test_endOfLineComment_toDartDoc() {
+    _resolveUnit(r'''
+class A {
+  // text
+  main() {
+    print(42);
+  }
+}''');
+    _updateAndValidate(
+        r'''
+class A {
+  /// text
+  main() {
+    print(42);
+  }
+}''',
+        expectedSuccess: false);
+  }
+
   void test_false_constConstructor_initializer() {
     _resolveUnit(r'''
 class C {
@@ -3911,6 +3921,74 @@
         expectedSuccess: false);
   }
 
+  void test_false_constructor_initializer_damage() {
+    _resolveUnit(r'''
+class Problem {
+  final Map location;
+  final String message;
+
+  Problem(Map json)
+      : location = json["location"],
+        message = json["message"];
+}''');
+    _updateAndValidate(
+        r'''
+class Problem {
+  final Map location;
+  final String message;
+
+  Problem(Map json)
+      : location = json["location],
+        message = json["message"];
+}''',
+        expectedSuccess: false);
+  }
+
+  void test_false_constructor_initializer_remove() {
+    _resolveUnit(r'''
+class Problem {
+  final String severity;
+  final Map location;
+  final String message;
+
+  Problem(Map json)
+      : severity = json["severity"],
+        location = json["location"],
+        message = json["message"];
+}''');
+    _updateAndValidate(
+        r'''
+class Problem {
+  final String severity;
+  final Map location;
+  final String message;
+
+  Problem(Map json)
+      : severity = json["severity"],
+        message = json["message"];
+}''',
+        expectedSuccess: false);
+  }
+
+  void test_false_endOfLineComment_localFunction_inTopLevelVariable() {
+    _resolveUnit(r'''
+typedef int Binary(one, two, three);
+
+int Global = f((a, b, c) {
+  return 0; // Some comment
+});
+''');
+    _updateAndValidate(
+        r'''
+typedef int Binary(one, two, three);
+
+int Global = f((a, b, c) {
+  return 0; // Some  comment
+});
+''',
+        expectedSuccess: false);
+  }
+
   void test_false_expressionBody() {
     _resolveUnit(r'''
 class A {
@@ -3926,6 +4004,44 @@
         expectedSuccess: false);
   }
 
+  void test_false_expressionBody2() {
+    _resolveUnit(r'''
+class A {
+  int m() => 10 * 10;
+}
+''');
+    _updateAndValidate(
+        r'''
+class A {
+  int m() => 10 * 100;
+}
+''',
+        expectedSuccess: false);
+  }
+
+  void test_false_inBody_functionExpression() {
+    _resolveUnit(r'''
+class C extends D {
+  static final f = () {
+    var x = 0;
+  }();
+}
+
+class D {}
+''');
+    _updateAndValidate(
+        r'''
+class C extends D {
+  static final f = () {
+    var x = 01;
+  }();
+}
+
+class D {}
+''',
+        expectedSuccess: false);
+  }
+
   void test_false_topLevelFunction_name() {
     _resolveUnit(r'''
 a() {}
@@ -3995,6 +4111,25 @@
         expectedSuccess: false);
   }
 
+  void test_false_wholeConstructor() {
+    _resolveUnit(r'''
+class A {
+  A(int a) {
+    print(a);
+  }
+}
+''');
+    _updateAndValidate(
+        r'''
+class A {
+  A(int b) {
+    print(b);
+  }
+}
+''',
+        expectedSuccess: false);
+  }
+
   void test_fieldClassField_propagatedType() {
     _resolveUnit(r'''
 class A {
@@ -4045,27 +4180,6 @@
 ''');
   }
 
-  void test_inBody_functionExpression() {
-    _resolveUnit(r'''
-class C extends D {
-  static final f = () {
-    var x = 0;
-  }();
-}
-
-class D {}
-''');
-    _updateAndValidate(r'''
-class C extends D {
-  static final f = () {
-    var x = 01;
-  }();
-}
-
-class D {}
-''');
-  }
-
   void test_inBody_insertStatement() {
     _resolveUnit(r'''
 main() {
@@ -4238,23 +4352,6 @@
     _assertEqualErrors(newErrors, oldErrors);
   }
 
-  void test_true_wholeConstructor() {
-    _resolveUnit(r'''
-class A {
-  A(int a) {
-    print(a);
-  }
-}
-''');
-    _updateAndValidate(r'''
-class A {
-  A(int b) {
-    print(b);
-  }
-}
-''');
-  }
-
   void test_true_wholeConstructor_addInitializer() {
     _resolveUnit(r'''
 class A {
@@ -4697,8 +4794,7 @@
     AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
     analysisOptions.incremental = enable;
     analysisOptions.incrementalApi = enable;
-//    log.logger = log.PRINT_LOGGER;
-    log.logger = log.NULL_LOGGER;
+    logging.logger = logger;
     analysisContext2.analysisOptions = analysisOptions;
   }
 
@@ -4730,6 +4826,7 @@
     _resetWithIncremental(true);
     analysisContext2.setContents(source, newCode);
     CompilationUnit newUnit = resolveCompilationUnit(source, oldLibrary);
+    expect(logger.hasError, isFalse);
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
     LineInfo newLineInfo = analysisContext.getLineInfo(source);
     // check for expected failure
@@ -5022,3 +5119,26 @@
   final String replacement;
   _Edit(this.offset, this.length, this.replacement);
 }
+
+class _TestLogger implements logging.Logger {
+  bool hasError = false;
+
+  @override
+  void enter(String name) {}
+
+  @override
+  void exit() {}
+
+  @override
+  void log(Object obj) {}
+
+  @override
+  void logException(Object exception, [Object stackTrace]) {
+    hasError = true;
+  }
+
+  @override
+  logging.LoggingTimer startTimer() {
+    return new logging.LoggingTimer(this);
+  }
+}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 6792467..9ce75c6 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/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -35,24 +35,6 @@
     verify([source]);
   }
 
-  void test_class_type_alias_documentationComment() {
-    Source source = addSource('''
-/**
- * Documentation
- */
-class C = D with E;
-
-class D {}
-class E {}''');
-    computeLibrarySourceErrors(source);
-    computeLibrarySourceErrors(source);
-    assertNoErrors(source);
-    verify([source]);
-    CompilationUnit unit = _getResolvedLibraryUnit(source);
-    ClassElement classC = unit.element.getType('C');
-    expect(classC.documentationComment, isNotNull);
-  }
-
   void test_ambiguousExport() {
     Source source = addSource(r'''
 library L;
@@ -932,6 +914,24 @@
     verify([source]);
   }
 
+  void test_class_type_alias_documentationComment() {
+    Source source = addSource('''
+/**
+ * Documentation
+ */
+class C = D with E;
+
+class D {}
+class E {}''');
+    computeLibrarySourceErrors(source);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+    CompilationUnit unit = _getResolvedLibraryUnit(source);
+    ClassElement classC = unit.element.getType('C');
+    expect(classC.documentationComment, isNotNull);
+  }
+
   void test_commentReference_beforeConstructor() {
     String code = r'''
 abstract class A {
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 5d304c7..2855c21 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -4,10 +4,12 @@
 
 library analyzer.test.generated.parser_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_scanner.dart';
@@ -937,21 +939,42 @@
         [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
 
+  void test_emptyEnumBody() {
+    parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
+        "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
+  }
+
   void test_enableAsync_false_1() {
     parseAsync = false;
-    parse4("parseFunctionDeclarationStatement",
-        "foo() async {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+    FunctionDeclarationStatement stmt = parse4(
+        "parseFunctionDeclarationStatement",
+        "foo() async {}",
+        [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+    FunctionExpression expr = stmt.functionDeclaration.functionExpression;
+    expect(expr.body.isAsynchronous, isTrue);
+    expect(expr.body.isGenerator, isFalse);
   }
 
   void test_enableAsync_false_2() {
     parseAsync = false;
-    parse4("parseFunctionDeclarationStatement",
-        "foo() sync* {}", [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+    FunctionDeclarationStatement stmt = parse4(
+        "parseFunctionDeclarationStatement",
+        "foo() async => 0;",
+        [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+    FunctionExpression expr = stmt.functionDeclaration.functionExpression;
+    expect(expr.body.isAsynchronous, isTrue);
+    expect(expr.body.isGenerator, isFalse);
   }
 
-  void test_emptyEnumBody() {
-    parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
-        "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
+  void test_enableAsync_false_3() {
+    parseAsync = false;
+    FunctionDeclarationStatement stmt = parse4(
+        "parseFunctionDeclarationStatement",
+        "foo() sync* {}",
+        [ParserErrorCode.ASYNC_NOT_SUPPORTED]);
+    FunctionExpression expr = stmt.functionDeclaration.functionExpression;
+    expect(expr.body.isAsynchronous, isFalse);
+    expect(expr.body.isGenerator, isTrue);
   }
 
   void test_enumInClass() {
@@ -3687,6 +3710,55 @@
     expect(statement.toSource(), 'List<String> v;');
   }
 
+  void test_incompleteTypeArguments_field() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(
+        r'''
+class C {
+  final List<int f;
+}''',
+        [ParserErrorCode.EXPECTED_TOKEN]);
+    // one class
+    List<CompilationUnitMember> declarations = unit.declarations;
+    expect(declarations, hasLength(1));
+    ClassDeclaration classDecl = declarations[0] as ClassDeclaration;
+    // one field declaration
+    List<ClassMember> members = classDecl.members;
+    expect(members, hasLength(1));
+    FieldDeclaration fieldDecl = members[0] as FieldDeclaration;
+    // one field
+    VariableDeclarationList fieldList = fieldDecl.fields;
+    List<VariableDeclaration> fields = fieldList.variables;
+    expect(fields, hasLength(1));
+    VariableDeclaration field = fields[0];
+    expect(field.name.name, 'f');
+    // validate the type
+    TypeArgumentList typeArguments = fieldList.type.typeArguments;
+    expect(typeArguments.arguments, hasLength(1));
+    // synthetic '>'
+    Token token = typeArguments.endToken;
+    expect(token.type, TokenType.GT);
+    expect(token.isSynthetic, isTrue);
+  }
+
+  void test_incompleteTypeParameters() {
+    CompilationUnit unit = ParserTestCase.parseCompilationUnit(
+        r'''
+class C<K {
+}''',
+        [ParserErrorCode.EXPECTED_TOKEN]);
+    // one class
+    List<CompilationUnitMember> declarations = unit.declarations;
+    expect(declarations, hasLength(1));
+    ClassDeclaration classDecl = declarations[0] as ClassDeclaration;
+    // validate the type parameters
+    TypeParameterList typeParameters = classDecl.typeParameters;
+    expect(typeParameters.typeParameters, hasLength(1));
+    // synthetic '>'
+    Token token = typeParameters.endToken;
+    expect(token.type, TokenType.GT);
+    expect(token.isSynthetic, isTrue);
+  }
+
   void test_invalidFunctionBodyModifier() {
     ParserTestCase.parseCompilationUnit(
         "f() sync {}", [ParserErrorCode.MISSING_STAR_AFTER_SYNC]);
@@ -7334,6 +7406,16 @@
     expect(literal.rightBracket, isNotNull);
   }
 
+  void test_parseConstExpression_listLiteral_typed_genericComment() {
+    enableGenericMethodComments = true;
+    ListLiteral literal = parse4("parseConstExpression", "const /*<A>*/ []");
+    expect(literal.constKeyword, isNotNull);
+    expect(literal.typeArguments, isNotNull);
+    expect(literal.leftBracket, isNotNull);
+    expect(literal.elements, hasLength(0));
+    expect(literal.rightBracket, isNotNull);
+  }
+
   void test_parseConstExpression_listLiteral_untyped() {
     ListLiteral literal = parse4("parseConstExpression", "const []");
     expect(literal.constKeyword, isNotNull);
@@ -7351,6 +7433,15 @@
     expect(literal.typeArguments, isNotNull);
   }
 
+  void test_parseConstExpression_mapLiteral_typed_genericComment() {
+    enableGenericMethodComments = true;
+    MapLiteral literal = parse4("parseConstExpression", "const /*<A, B>*/ {}");
+    expect(literal.leftBracket, isNotNull);
+    expect(literal.entries, hasLength(0));
+    expect(literal.rightBracket, isNotNull);
+    expect(literal.typeArguments, isNotNull);
+  }
+
   void test_parseConstExpression_mapLiteral_untyped() {
     MapLiteral literal = parse4("parseConstExpression", "const {}");
     expect(literal.leftBracket, isNotNull);
@@ -9856,6 +9947,13 @@
     expect(literal.typeArguments.arguments, hasLength(1));
   }
 
+  void test_parsePrimaryExpression_listLiteral_typed_genericComment() {
+    enableGenericMethodComments = true;
+    ListLiteral literal = parse4("parsePrimaryExpression", "/*<A>*/[ ]");
+    expect(literal.typeArguments, isNotNull);
+    expect(literal.typeArguments.arguments, hasLength(1));
+  }
+
   void test_parsePrimaryExpression_mapLiteral() {
     MapLiteral literal = parse4("parsePrimaryExpression", "{}");
     expect(literal, isNotNull);
@@ -9867,6 +9965,13 @@
     expect(literal.typeArguments.arguments, hasLength(2));
   }
 
+  void test_parsePrimaryExpression_mapLiteral_typed_genericComment() {
+    enableGenericMethodComments = true;
+    MapLiteral literal = parse4("parsePrimaryExpression", "/*<A, B>*/{}");
+    expect(literal.typeArguments, isNotNull);
+    expect(literal.typeArguments.arguments, hasLength(2));
+  }
+
   void test_parsePrimaryExpression_new() {
     InstanceCreationExpression expression =
         parse4("parsePrimaryExpression", "new A()");
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 4722a65..fe755ed8 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -6,13 +6,14 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/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_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -43,6 +44,7 @@
   initializeTestEnvironment();
   runReflectiveTests(AnalysisDeltaTest);
   runReflectiveTests(ChangeSetTest);
+  runReflectiveTests(DisableAsyncTestCase);
   runReflectiveTests(EnclosedScopeTest);
   runReflectiveTests(LibraryImportScopeTest);
   runReflectiveTests(LibraryScopeTest);
@@ -108,11 +110,14 @@
   static InternalAnalysisContext initContextWithCore(
       InternalAnalysisContext context) {
     DirectoryBasedDartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
-        new JavaFile("/fake/sdk"));
+        new JavaFile("/fake/sdk"),
+        enableAsync: context.analysisOptions.enableAsync);
     SourceFactory sourceFactory =
         new SourceFactory([new DartUriResolver(sdk), new FileUriResolver()]);
     context.sourceFactory = sourceFactory;
     AnalysisContext coreContext = sdk.context;
+    (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode =
+        context.analysisOptions.strongMode;
     //
     // dart:core
     //
@@ -124,8 +129,9 @@
     coreUnit.librarySource = coreUnit.source = coreSource;
     ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy");
     proxyClassElement.constructors = <ConstructorElement>[
-      ElementFactory.constructorElement(proxyClassElement, null, true)
+      ElementFactory.constructorElement(proxyClassElement, '', true)
         ..isCycleFree = true
+        ..constantInitializers = <ConstructorInitializer>[]
     ];
     ClassElement objectClassElement = provider.objectType.element;
     coreUnit.types = <ClassElement>[
@@ -158,11 +164,18 @@
     ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt =
         ElementFactory.topLevelVariableElement3(
             "deprecated", true, false, provider.deprecatedType);
-    deprecatedTopLevelVariableElt.constantInitializer = AstFactory
-        .instanceCreationExpression2(
-            Keyword.CONST,
-            AstFactory.typeName(provider.deprecatedType.element),
-            [AstFactory.string2('next release')]);
+    {
+      ClassElement deprecatedElement = provider.deprecatedType.element;
+      InstanceCreationExpression initializer = AstFactory
+          .instanceCreationExpression2(
+              Keyword.CONST,
+              AstFactory.typeName(deprecatedElement),
+              [AstFactory.string2('next release')]);
+      ConstructorElement constructor = deprecatedElement.constructors.single;
+      initializer.staticElement = constructor;
+      initializer.constructorName.staticElement = constructor;
+      deprecatedTopLevelVariableElt.constantInitializer = initializer;
+    }
     coreUnit.accessors = <PropertyAccessorElement>[
       proxyTopLevelVariableElt.getter,
       deprecatedTopLevelVariableElt.getter
@@ -177,89 +190,97 @@
     //
     // dart:async
     //
-    CompilationUnitElementImpl asyncUnit =
-        new CompilationUnitElementImpl("async.dart");
-    Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
-    coreContext.setContents(asyncSource, "");
-    asyncUnit.librarySource = asyncUnit.source = asyncSource;
-    // Future
-    ClassElementImpl futureElement =
-        ElementFactory.classElement2("Future", ["T"]);
-    //   factory Future.value([value])
-    ConstructorElementImpl futureConstructor =
-        ElementFactory.constructorElement2(futureElement, "value");
-    futureConstructor.parameters = <ParameterElement>[
-      ElementFactory.positionalParameter2("value", provider.dynamicType)
-    ];
-    futureConstructor.factory = true;
-    futureElement.constructors = <ConstructorElement>[futureConstructor];
-    //   Future then(onValue(T value), { Function onError });
-    TypeDefiningElement futureThenR = DynamicElementImpl.instance;
-    if (context.analysisOptions.strongMode) {
-      futureThenR = ElementFactory.typeParameterWithType('R');
+    Source asyncSource;
+    LibraryElementImpl asyncLibrary;
+    if (context.analysisOptions.enableAsync) {
+      asyncLibrary = new LibraryElementImpl.forNode(
+          coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
+      CompilationUnitElementImpl asyncUnit =
+          new CompilationUnitElementImpl("async.dart");
+      asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+      coreContext.setContents(asyncSource, "");
+      asyncUnit.librarySource = asyncUnit.source = asyncSource;
+      asyncLibrary.definingCompilationUnit = asyncUnit;
+      // Future
+      ClassElementImpl futureElement =
+          ElementFactory.classElement2("Future", ["T"]);
+      futureElement.enclosingElement = asyncUnit;
+      //   factory Future.value([value])
+      ConstructorElementImpl futureConstructor =
+          ElementFactory.constructorElement2(futureElement, "value");
+      futureConstructor.parameters = <ParameterElement>[
+        ElementFactory.positionalParameter2("value", provider.dynamicType)
+      ];
+      futureConstructor.factory = true;
+      futureElement.constructors = <ConstructorElement>[futureConstructor];
+      //   Future then(onValue(T value), { Function onError });
+      TypeDefiningElement futureThenR = DynamicElementImpl.instance;
+      if (context.analysisOptions.strongMode) {
+        futureThenR = ElementFactory.typeParameterWithType('R');
+      }
+      FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
+          'onValue', futureThenR, [futureElement.typeParameters[0]], null);
+
+      DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
+      MethodElementImpl thenMethod = ElementFactory
+          .methodElementWithParameters(futureElement, "then", futureRType, [
+        ElementFactory.requiredParameter2("onValue", thenOnValue.type),
+        ElementFactory.namedParameter2("onError", provider.functionType)
+      ]);
+      if (!futureThenR.type.isDynamic) {
+        thenMethod.typeParameters = [futureThenR];
+      }
+      thenOnValue.enclosingElement = thenMethod;
+      thenOnValue.type = new FunctionTypeImpl(thenOnValue);
+      (thenMethod.parameters[0] as ParameterElementImpl).type =
+          thenOnValue.type;
+      thenMethod.type = new FunctionTypeImpl(thenMethod);
+
+      futureElement.methods = <MethodElement>[thenMethod];
+      // Completer
+      ClassElementImpl completerElement =
+          ElementFactory.classElement2("Completer", ["T"]);
+      ConstructorElementImpl completerConstructor =
+          ElementFactory.constructorElement2(completerElement, null);
+      completerElement.constructors = <ConstructorElement>[
+        completerConstructor
+      ];
+      // StreamSubscription
+      ClassElementImpl streamSubscriptionElement =
+          ElementFactory.classElement2("StreamSubscription", ["T"]);
+      // Stream
+      ClassElementImpl streamElement =
+          ElementFactory.classElement2("Stream", ["T"]);
+      streamElement.constructors = <ConstructorElement>[
+        ElementFactory.constructorElement2(streamElement, null)
+      ];
+      DartType returnType = streamSubscriptionElement.type
+          .substitute4(streamElement.type.typeArguments);
+      List<DartType> parameterTypes = <DartType>[
+        ElementFactory
+            .functionElement3('onData', VoidTypeImpl.instance.element,
+                <TypeDefiningElement>[streamElement.typeParameters[0]], null)
+            .type,
+      ];
+      // TODO(brianwilkerson) This is missing the optional parameters.
+      MethodElementImpl listenMethod =
+          ElementFactory.methodElement('listen', returnType, parameterTypes);
+      streamElement.methods = <MethodElement>[listenMethod];
+      listenMethod.type = new FunctionTypeImpl(listenMethod);
+
+      FunctionElementImpl listenParamFunction = parameterTypes[0].element;
+      listenParamFunction.enclosingElement = listenMethod;
+      listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
+      ParameterElementImpl listenParam = listenMethod.parameters[0];
+      listenParam.type = listenParamFunction.type;
+
+      asyncUnit.types = <ClassElement>[
+        completerElement,
+        futureElement,
+        streamElement,
+        streamSubscriptionElement
+      ];
     }
-    FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
-        'onValue', futureThenR, [futureElement.typeParameters[0]], null);
-
-    DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
-    MethodElementImpl thenMethod = ElementFactory
-        .methodElementWithParameters(futureElement, "then", futureRType, [
-      ElementFactory.requiredParameter2("onValue", thenOnValue.type),
-      ElementFactory.namedParameter2("onError", provider.functionType)
-    ]);
-    if (!futureThenR.type.isDynamic) {
-      thenMethod.typeParameters = [futureThenR];
-    }
-    thenOnValue.enclosingElement = thenMethod;
-    thenOnValue.type = new FunctionTypeImpl(thenOnValue);
-    (thenMethod.parameters[0] as ParameterElementImpl).type = thenOnValue.type;
-    thenMethod.type = new FunctionTypeImpl(thenMethod);
-
-    futureElement.methods = <MethodElement>[thenMethod];
-    // Completer
-    ClassElementImpl completerElement =
-        ElementFactory.classElement2("Completer", ["T"]);
-    ConstructorElementImpl completerConstructor =
-        ElementFactory.constructorElement2(completerElement, null);
-    completerElement.constructors = <ConstructorElement>[completerConstructor];
-    // StreamSubscription
-    ClassElementImpl streamSubscriptionElement =
-        ElementFactory.classElement2("StreamSubscription", ["T"]);
-    // Stream
-    ClassElementImpl streamElement =
-        ElementFactory.classElement2("Stream", ["T"]);
-    streamElement.constructors = <ConstructorElement>[
-      ElementFactory.constructorElement2(streamElement, null)
-    ];
-    DartType returnType = streamSubscriptionElement.type
-        .substitute4(streamElement.type.typeArguments);
-    List<DartType> parameterTypes = <DartType>[
-      ElementFactory
-          .functionElement3('onData', VoidTypeImpl.instance.element,
-              <TypeDefiningElement>[streamElement.typeParameters[0]], null)
-          .type,
-    ];
-    // TODO(brianwilkerson) This is missing the optional parameters.
-    MethodElementImpl listenMethod =
-        ElementFactory.methodElement('listen', returnType, parameterTypes);
-    streamElement.methods = <MethodElement>[listenMethod];
-    listenMethod.type = new FunctionTypeImpl(listenMethod);
-
-    FunctionElementImpl listenParamFunction = parameterTypes[0].element;
-    listenParamFunction.enclosingElement = listenMethod;
-    listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
-    ParameterElementImpl listenParam = listenMethod.parameters[0];
-    listenParam.type = listenParamFunction.type;
-
-    asyncUnit.types = <ClassElement>[
-      completerElement,
-      futureElement,
-      streamElement,
-      streamSubscriptionElement
-    ];
-    LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
-        coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
-    asyncLibrary.definingCompilationUnit = asyncUnit;
     //
     // dart:html
     //
@@ -395,7 +416,9 @@
     HashMap<Source, LibraryElement> elementMap =
         new HashMap<Source, LibraryElement>();
     elementMap[coreSource] = coreLibrary;
-    elementMap[asyncSource] = asyncLibrary;
+    if (asyncSource != null) {
+      elementMap[asyncSource] = asyncLibrary;
+    }
     elementMap[htmlSource] = htmlLibrary;
     elementMap[mathSource] = mathLibrary;
     //
@@ -407,6 +430,10 @@
           library.publicNamespace = new PublicNamespaceBuilder().build(library);
     }
     context.recordLibraryElements(elementMap);
+    // Create the synthetic element for `loadLibrary`.
+    for (LibraryElementImpl library in elementMap.values) {
+      library.createLoadLibraryFunction(context.typeProvider);
+    }
     return context;
   }
 }
@@ -1206,6 +1233,51 @@
 }
 
 @reflectiveTest
+class DisableAsyncTestCase extends ResolverTestCase {
+  @override
+  void setUp() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableAsync = false;
+    resetWithOptions(options);
+  }
+
+  void test_resolve() {
+    Source source = addSource(r'''
+class C {
+  foo() {
+    bar();
+  }
+  bar() {
+    //
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, []);
+  }
+
+  void test_resolve_async() {
+    Source source = addSource(r'''
+class C {
+  Future foo() async {
+    await bar();
+    return null;
+  }
+  Future bar() {
+    return new Future.delayed(new Duration(milliseconds: 10));
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.UNDEFINED_CLASS,
+      StaticWarningCode.UNDEFINED_CLASS,
+      StaticWarningCode.UNDEFINED_CLASS,
+      StaticWarningCode.UNDEFINED_CLASS,
+      ParserErrorCode.ASYNC_NOT_SUPPORTED
+    ]);
+  }
+}
+
+@reflectiveTest
 class ElementResolverTest extends EngineTestCase {
   /**
    * The error listener to which errors will be reported.
@@ -2272,6 +2344,44 @@
   }
 }
 
+/**
+ * Tests for generic method and function resolution that do not use strong mode.
+ */
+@reflectiveTest
+class GenericMethodResolverTest extends _StaticTypeAnalyzer2TestShared {
+  void setUp() {
+    super.setUp();
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableGenericMethods = true;
+    resetWithOptions(options);
+  }
+
+  void test_genericMethod_propagatedType_promotion() {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25340
+    //
+    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
+    // strong mode example won't work, as we now compute a static type and
+    // therefore discard the propagated type.
+    //
+    // So this test does not use strong mode.
+    _resolveTestUnit(r'''
+abstract class Iter {
+  List<S> map<S>(S f(x));
+}
+class C {}
+C toSpan(dynamic element) {
+  if (element is Iter) {
+    var y = element.map(toSpan);
+  }
+  return null;
+}''');
+    SimpleIdentifier y = _findIdentifier('y = ');
+    expect(y.staticType.toString(), 'dynamic');
+    expect(y.propagatedType.toString(), 'List<dynamic>');
+  }
+}
+
 @reflectiveTest
 class HintCodeTest extends ResolverTestCase {
   void fail_deadCode_statementAfterRehrow() {
@@ -6546,6 +6656,18 @@
     verify([source]);
   }
 
+  void test_deprecatedAnnotationUse_classWithConstructor() {
+    Source source = addSource(r'''
+@deprecated
+class C {
+  C();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_divisionOptimization() {
     Source source = addSource(r'''
 f(int x, int y) {
@@ -9274,14 +9396,30 @@
   void test_isValidMixin_badSuperclass() {
     Source source = addSource(r'''
 class A extends B {}
-class B {}''');
+class B {}
+class C = Object with A;''');
     LibraryElement library = resolve2(source);
     expect(library, isNotNull);
     CompilationUnitElement unit = library.definingCompilationUnit;
     expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(2));
-    expect(classes[0].isValidMixin, isFalse);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isFalse);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]);
+    verify([source]);
+  }
+
+  void test_isValidMixin_badSuperclass_withSuperMixins() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource(r'''
+class A extends B {}
+class B {}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
     assertNoErrors(source);
     verify([source]);
   }
@@ -9290,14 +9428,64 @@
     Source source = addSource(r'''
 class A {
   A() {}
-}''');
+}
+class C = Object with A;''');
     LibraryElement library = resolve2(source);
     expect(library, isNotNull);
     CompilationUnitElement unit = library.definingCompilationUnit;
     expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    expect(classes[0].isValidMixin, isFalse);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isFalse);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  void test_isValidMixin_constructor_withSuperMixins() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource(r'''
+class A {
+  A() {}
+}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isFalse);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]);
+    verify([source]);
+  }
+
+  void test_isValidMixin_factoryConstructor() {
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_isValidMixin_factoryConstructor_withSuperMixins() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource(r'''
+class A {
+  factory A() => null;
+}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
     assertNoErrors(source);
     verify([source]);
   }
@@ -9308,27 +9496,62 @@
   toString() {
     return super.toString();
   }
-}''');
+}
+class C = Object with A;''');
     LibraryElement library = resolve2(source);
     expect(library, isNotNull);
     CompilationUnitElement unit = library.definingCompilationUnit;
     expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    expect(classes[0].isValidMixin, isFalse);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isFalse);
+    assertErrors(source, [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]);
+    verify([source]);
+  }
+
+  void test_isValidMixin_super_withSuperMixins() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource(r'''
+class A {
+  toString() {
+    return super.toString();
+  }
+}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
     assertNoErrors(source);
     verify([source]);
   }
 
   void test_isValidMixin_valid() {
-    Source source = addSource("class A {}");
+    Source source = addSource('''
+class A {}
+class C = Object with A;''');
     LibraryElement library = resolve2(source);
     expect(library, isNotNull);
     CompilationUnitElement unit = library.definingCompilationUnit;
     expect(unit, isNotNull);
-    List<ClassElement> classes = unit.types;
-    expect(classes, hasLength(1));
-    expect(classes[0].isValidMixin, isTrue);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_isValidMixin_valid_withSuperMixins() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource('''
+class A {}
+class C = Object with A;''');
+    LibraryElement library = resolve2(source);
+    expect(library, isNotNull);
+    CompilationUnitElement unit = library.definingCompilationUnit;
+    expect(unit, isNotNull);
+    ClassElement a = unit.getType('A');
+    expect(a.isValidMixin, isTrue);
     assertNoErrors(source);
     verify([source]);
   }
@@ -10019,6 +10242,11 @@
    */
   TestTypeProvider _typeProvider;
 
+  /**
+   * The type system used to analyze the test cases.
+   */
+  TypeSystem get _typeSystem => _visitor.typeSystem;
+
   void fail_visitFunctionExpressionInvocation() {
     fail("Not yet tested");
     _listener.assertNoErrors();
@@ -10038,7 +10266,6 @@
   void setUp() {
     super.setUp();
     _listener = new GatheringErrorListener();
-    _typeProvider = new TestTypeProvider();
     _analyzer = _createAnalyzer();
   }
 
@@ -11304,6 +11531,7 @@
     LibraryElementImpl definingLibrary =
         new LibraryElementImpl.forNode(context, null);
     definingLibrary.definingCompilationUnit = definingCompilationUnit;
+    _typeProvider = new TestTypeProvider(context);
     _visitor = new ResolverVisitor(
         definingLibrary, source, _typeProvider, _listener,
         nameScope: new LibraryScope(definingLibrary, _listener));
@@ -11316,8 +11544,7 @@
     }
   }
 
-  DartType _flatten(DartType type) =>
-      StaticTypeAnalyzer.flattenFutures(_typeProvider, type);
+  DartType _flatten(DartType type) => type.flattenFutures(_typeSystem);
 
   /**
    * Return a simple identifier that has been resolved to a variable element with the given type.
@@ -13030,105 +13257,6 @@
  */
 @reflectiveTest
 class StrongModeStaticTypeAnalyzer2Test extends _StaticTypeAnalyzer2TestShared {
-  void test_genericMethod_functionExpressionInvocation_explicit() {
-    _resolveTestUnit(r'''
-class C<E> {
-  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
-  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
-  static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
-  var c = new C<int>();
-  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
-
-  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
-  var methodCall = (c.f)/*<int>*/(3);
-  var staticCall = (C.g)/*<int>*/(3);
-  var staticFieldCall = (C.h)/*<int>*/(3);
-  var topFunCall = (topF)/*<int>*/(3);
-  var topFieldCall = (topG)/*<int>*/(3);
-  var localCall = (lf)/*<int>*/(3);
-  var paramCall = (pf)/*<int>*/(3);
-}
-''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
-    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
-  }
-
-  void fail_genericMethod_functionExpressionInvocation_inferred() {
-    _resolveTestUnit(r'''
-class C<E> {
-  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
-  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
-  static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
-  var c = new C<int>();
-  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
-
-  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
-  var methodCall = (c.f)(3);
-  var staticCall = (C.g)(3);
-  var staticFieldCall = (C.h)(3);
-  var topFunCall = (topF)(3);
-  var topFieldCall = (topG)(3);
-  var localCall = (lf)(3);
-  var paramCall = (pf)(3);
-}
-''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
-    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
-  }
-
-  void fail_genericMethod_functionInvocation_inferred() {
-    _resolveTestUnit(r'''
-class C<E> {
-  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
-  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
-  static final h = g;
-}
-
-/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
-var topG = topF;
-void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
-  var c = new C<int>();
-  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
-  var methodCall = c.f(3);
-  var staticCall = C.g(3);
-  var staticFieldCall = C.h(3);
-  var topFunCall = topF(3);
-  var topFieldCall = topG(3);
-  var localCall = lf(3);
-  var paramCall = pf(3);
-}
-''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
-  }
-
   void fail_genericMethod_tearoff_instantiated() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13384,6 +13512,74 @@
         typeProvider.listType.substitute4([typeProvider.intType]));
   }
 
+  void test_genericMethod_functionExpressionInvocation_explicit() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
+  var methodCall = (c.f)/*<int>*/(3);
+  var staticCall = (C.g)/*<int>*/(3);
+  var staticFieldCall = (C.h)/*<int>*/(3);
+  var topFunCall = (topF)/*<int>*/(3);
+  var topFieldCall = (topG)/*<int>*/(3);
+  var localCall = (lf)/*<int>*/(3);
+  var paramCall = (pf)/*<int>*/(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
+  void test_genericMethod_functionExpressionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+
+  var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
+  var methodCall = (c.f)(3);
+  var staticCall = (C.g)(3);
+  var staticFieldCall = (C.h)(3);
+  var topFunCall = (topF)(3);
+  var topFieldCall = (topG)(3);
+  var localCall = (lf)(3);
+  var paramCall = (pf)(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+  }
+
   void test_genericMethod_functionInvocation_explicit() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13415,6 +13611,37 @@
     expect(_findIdentifier('paramCall').staticType.toString(), "int");
   }
 
+  void test_genericMethod_functionInvocation_inferred() {
+    _resolveTestUnit(r'''
+class C<E> {
+  /*=T*/ f/*<T>*/(/*=T*/ e) => null;
+  static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
+  static final h = g;
+}
+
+/*=T*/ topF/*<T>*/(/*=T*/ e) => null;
+var topG = topF;
+void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
+  var c = new C<int>();
+  /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
+  var methodCall = c.f(3);
+  var staticCall = C.g(3);
+  var staticFieldCall = C.h(3);
+  var topFunCall = topF(3);
+  var topFieldCall = topG(3);
+  var localCall = lf(3);
+  var paramCall = pf(3);
+}
+''');
+    expect(_findIdentifier('methodCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticCall').staticType.toString(), "int");
+    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
+    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
+    expect(_findIdentifier('localCall').staticType.toString(), "int");
+    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+  }
+
   void test_genericMethod_functionTypedParameter() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13456,15 +13683,95 @@
     SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
     MethodInvocation m1 = map1.parent;
     expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
-    expect(map1.staticType, isNull);
+    expect(map1.staticType.toString(), '<T>((dynamic) → T) → T');
     expect(map1.propagatedType, isNull);
     SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
     MethodInvocation m2 = map2.parent;
     expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
-    expect(map2.staticType, isNull);
+    expect(map2.staticType.toString(), '<T>((dynamic) → T) → T');
     expect(map2.propagatedType, isNull);
   }
 
+  void test_genericMethod_max_doubleDouble() {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1.0, 2.0);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'double');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_genericMethod_max_doubleDouble_prefixed() {
+    String code = r'''
+import 'dart:math' as math;
+main() {
+  var foo = math.max(1.0, 2.0);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'double');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_genericMethod_max_doubleInt() {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1.0, 2);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'num');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_genericMethod_max_intDouble() {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1, 2.0);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'num');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_genericMethod_max_intInt() {
+    String code = r'''
+import 'dart:math';
+main() {
+  var foo = max(1, 2);
+}
+''';
+    _resolveTestUnit(code);
+
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'int');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
   void test_genericMethod_nestedCapture() {
     _resolveTestUnit(r'''
 class C<T> {
@@ -13564,10 +13871,11 @@
     // TODO(jmesserly): this is modified code from assertErrors, which we can't
     // use directly because STRONG_MODE_* errors don't have working equality.
     List<AnalysisError> errors = analysisContext2.computeErrors(source);
-    expect(errors.map((e) => e.errorCode.name), [
-      'STRONG_MODE_INVALID_METHOD_OVERRIDE',
-      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'
-    ]);
+    List errorNames = errors.map((e) => e.errorCode.name).toList();
+    expect(errorNames, hasLength(2));
+    expect(errorNames, contains('STRONG_MODE_INVALID_METHOD_OVERRIDE'));
+    expect(
+        errorNames, contains('INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'));
     verify([source]);
   }
 
@@ -13589,6 +13897,30 @@
     verify([source]);
   }
 
+  void test_genericMethod_propagatedType_promotion() {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25340
+
+    // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
+    // example won't work, as we now compute a static type and therefore discard
+    // the propagated type. So a new test was created that doesn't run under
+    // strong mode.
+    _resolveTestUnit(r'''
+abstract class Iter {
+  List/*<S>*/ map/*<S>*/(/*=S*/ f(x));
+}
+class C {}
+C toSpan(dynamic element) {
+  if (element is Iter) {
+    var y = element.map(toSpan);
+  }
+  return null;
+}''');
+    SimpleIdentifier y = _findIdentifier('y = ');
+    expect(y.staticType.toString(), 'List<C>');
+    expect(y.propagatedType, isNull);
+  }
+
   void test_genericMethod_tearoff() {
     _resolveTestUnit(r'''
 class C<E> {
@@ -13625,87 +13957,7 @@
     expect(_findIdentifier('paramTearOff').staticType.toString(), "<T>(T) → T");
   }
 
-  void test_pseudoGeneric_max_doubleDouble() {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1.0, 2.0);
-}
-''';
-    _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'double');
-    expect(declaration.initializer.propagatedType, isNull);
-  }
-
-  void test_pseudoGeneric_max_doubleDouble_prefixed() {
-    String code = r'''
-import 'dart:math' as math;
-main() {
-  var foo = math.max(1.0, 2.0);
-}
-''';
-    _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'double');
-    expect(declaration.initializer.propagatedType, isNull);
-  }
-
-  void test_pseudoGeneric_max_doubleInt() {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1.0, 2);
-}
-''';
-    _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'num');
-    expect(declaration.initializer.propagatedType, isNull);
-  }
-
-  void test_pseudoGeneric_max_intDouble() {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1, 2.0);
-}
-''';
-    _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'num');
-    expect(declaration.initializer.propagatedType, isNull);
-  }
-
-  void test_pseudoGeneric_max_intInt() {
-    String code = r'''
-import 'dart:math';
-main() {
-  var foo = max(1, 2);
-}
-''';
-    _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
-  }
-
-  void test_pseudoGeneric_then() {
+  void test_genericMethod_then() {
     String code = r'''
 import 'dart:async';
 String toString(int x) => x.toString();
@@ -13724,7 +13976,7 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
-  void test_pseudoGeneric_then_prefixed() {
+  void test_genericMethod_then_prefixed() {
     String code = r'''
 import 'dart:async' as async;
 String toString(int x) => x.toString();
@@ -13743,6 +13995,22 @@
     expect(declaration.initializer.propagatedType, isNull);
   }
 
+  void test_genericMethod_then_propagatedType() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25482.
+    String code = r'''
+import 'dart:async';
+void main() {
+  Future<String> p;
+  var foo = p.then((r) => new Future<String>.value(3));
+}
+''';
+    // This should produce no hints or warnings.
+    _resolveTestUnit(code);
+    VariableDeclaration foo = _findIdentifier('foo').parent;
+    expect(foo.initializer.staticType.toString(), "Future<String>");
+    expect(foo.initializer.propagatedType, isNull);
+  }
+
   void test_setterWithDynamicTypeIsError() {
     Source source = addSource(r'''
 class A {
@@ -15747,7 +16015,7 @@
 }''';
     SimpleIdentifier methodName = _findMarkedIdentifier(code, "(); // marker");
     MethodInvocation methodInvoke = methodName.parent;
-    expect(methodName.staticType, null, reason: 'library prefix has no type');
+    expect(methodName.staticType, typeProvider.dynamicType);
     expect(methodInvoke.staticType, typeProvider.dynamicType);
   }
 
@@ -15953,11 +16221,81 @@
     expect(provider.mapType, same(mapType));
     expect(provider.objectType, same(objectType));
     expect(provider.stackTraceType, same(stackTraceType));
+    expect(provider.streamType, same(streamType));
     expect(provider.stringType, same(stringType));
     expect(provider.symbolType, same(symbolType));
     expect(provider.typeType, same(typeType));
   }
 
+  void test_creation_no_async() {
+    //
+    // Create a mock library element with the types expected to be in dart:core.
+    // We cannot use either ElementFactory or TestTypeProvider (which uses
+    // ElementFactory) because we side-effect the elements in ways that would
+    // break other tests.
+    //
+    InterfaceType objectType = _classElement("Object", null).type;
+    InterfaceType boolType = _classElement("bool", objectType).type;
+    InterfaceType numType = _classElement("num", objectType).type;
+    InterfaceType doubleType = _classElement("double", numType).type;
+    InterfaceType functionType = _classElement("Function", objectType).type;
+    InterfaceType intType = _classElement("int", numType).type;
+    InterfaceType iterableType =
+        _classElement("Iterable", objectType, ["T"]).type;
+    InterfaceType listType = _classElement("List", objectType, ["E"]).type;
+    InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
+    InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
+    InterfaceType stringType = _classElement("String", objectType).type;
+    InterfaceType symbolType = _classElement("Symbol", objectType).type;
+    InterfaceType typeType = _classElement("Type", objectType).type;
+    CompilationUnitElementImpl coreUnit =
+        new CompilationUnitElementImpl("core.dart");
+    coreUnit.types = <ClassElement>[
+      boolType.element,
+      doubleType.element,
+      functionType.element,
+      intType.element,
+      iterableType.element,
+      listType.element,
+      mapType.element,
+      objectType.element,
+      stackTraceType.element,
+      stringType.element,
+      symbolType.element,
+      typeType.element
+    ];
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
+        context, AstFactory.libraryIdentifier2(["dart.core"]));
+    coreLibrary.definingCompilationUnit = coreUnit;
+
+    LibraryElementImpl mockAsyncLib =
+        (context as AnalysisContextImpl).createMockAsyncLib(coreLibrary);
+    expect(mockAsyncLib.publicNamespace, isNotNull);
+
+    //
+    // Create a type provider and ensure that it can return the expected types.
+    //
+    TypeProviderImpl provider = new TypeProviderImpl(coreLibrary, mockAsyncLib);
+    expect(provider.boolType, same(boolType));
+    expect(provider.bottomType, isNotNull);
+    expect(provider.doubleType, same(doubleType));
+    expect(provider.dynamicType, isNotNull);
+    expect(provider.functionType, same(functionType));
+    InterfaceType mockFutureType = mockAsyncLib.getType('Future').type;
+    expect(provider.futureType, same(mockFutureType));
+    expect(provider.intType, same(intType));
+    expect(provider.listType, same(listType));
+    expect(provider.mapType, same(mapType));
+    expect(provider.objectType, same(objectType));
+    expect(provider.stackTraceType, same(stackTraceType));
+    expect(provider.stringType, same(stringType));
+    expect(provider.symbolType, same(symbolType));
+    InterfaceType mockStreamType = mockAsyncLib.getType('Stream').type;
+    expect(provider.streamType, same(mockStreamType));
+    expect(provider.typeType, same(typeType));
+  }
+
   ClassElement _classElement(String typeName, InterfaceType superclassType,
       [List<String> parameterNames]) {
     ClassElementImpl element =
@@ -16612,12 +16950,17 @@
 
 class _AnalysisContextFactory_initContextWithCore
     extends DirectoryBasedDartSdk {
-  _AnalysisContextFactory_initContextWithCore(JavaFile arg0) : super(arg0);
+  final bool enableAsync;
+  _AnalysisContextFactory_initContextWithCore(JavaFile arg0,
+      {this.enableAsync: true})
+      : super(arg0);
 
   @override
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
     LibraryMap map = new LibraryMap();
-    _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
+    if (enableAsync) {
+      _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
+    }
     _addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
     _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
     _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index e737b56..8a0b3d2 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -8,8 +8,8 @@
 
 import '../utils.dart';
 import 'all_the_rest_test.dart' as all_the_rest;
-import 'ast_test.dart' as ast_test;
 import 'compile_time_error_code_test.dart' as compile_time_error_code_test;
+import 'constant_test.dart' as constant_test;
 import 'declaration_resolver_test.dart' as declaration_resolver_test;
 import 'engine_test.dart' as engine_test;
 import 'incremental_resolver_test.dart' as incremental_resolver_test;
@@ -31,8 +31,8 @@
   initializeTestEnvironment();
   group('generated tests', () {
     all_the_rest.main();
-    ast_test.main();
     compile_time_error_code_test.main();
+    constant_test.main();
     declaration_resolver_test.main();
     engine_test.main();
     incremental_resolver_test.main();
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 87b1282..adccead 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -6,10 +6,11 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart'
+    show AstNode, NodeLocator, SimpleIdentifier;
 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/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -423,9 +424,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/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index bd5876b..d07f422 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -6,7 +6,8 @@
 
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -1506,8 +1507,8 @@
   }
 
   void test_visitSwitchCase_noLabels() {
-    _assertClone(AstFactory.switchCase(
-        AstFactory.identifier3("a"), [AstFactory.block()]));
+    _assertClone(AstFactory
+        .switchCase(AstFactory.identifier3("a"), [AstFactory.block()]));
   }
 
   void test_visitSwitchCase_singleLabel() {
@@ -1531,8 +1532,8 @@
   }
 
   void test_visitSwitchDefault_singleLabel() {
-    _assertClone(AstFactory.switchDefault(
-        [AstFactory.label2("l1")], [AstFactory.block()]));
+    _assertClone(AstFactory
+        .switchDefault([AstFactory.label2("l1")], [AstFactory.block()]));
   }
 
   void test_visitSwitchStatement() {
@@ -3534,8 +3535,8 @@
         AstFactory.extendsClause(AstFactory.typeName4("B")),
         AstFactory.withClause([AstFactory.typeName4("C")]),
         AstFactory.implementsClause([AstFactory.typeName4("D")]), [
-      AstFactory.fieldDeclaration2(
-          false, null, [AstFactory.variableDeclaration("f")])
+      AstFactory
+          .fieldDeclaration2(false, null, [AstFactory.variableDeclaration("f")])
     ]);
     node.documentationComment =
         Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
@@ -3981,8 +3982,8 @@
   }
 
   void test_labeledStatement() {
-    LabeledStatement node = AstFactory.labeledStatement(
-        [AstFactory.label2("l")], AstFactory.block());
+    LabeledStatement node = AstFactory
+        .labeledStatement([AstFactory.label2("l")], AstFactory.block());
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_labeledStatement(0));
     _assertReplace(node, new Getter_NodeReplacerTest_test_labeledStatement());
@@ -4181,8 +4182,8 @@
   }
 
   void test_switchDefault() {
-    SwitchDefault node = AstFactory.switchDefault(
-        [AstFactory.label2("l")], [AstFactory.block()]);
+    SwitchDefault node = AstFactory
+        .switchDefault([AstFactory.label2("l")], [AstFactory.block()]);
     _testSwitchMember(node);
   }
 
@@ -4235,8 +4236,8 @@
   }
 
   void test_typeName() {
-    TypeName node = AstFactory.typeName4(
-        "T", [AstFactory.typeName4("E"), AstFactory.typeName4("F")]);
+    TypeName node = AstFactory
+        .typeName4("T", [AstFactory.typeName4("E"), AstFactory.typeName4("F")]);
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeName_2());
     _assertReplace(node, new Getter_NodeReplacerTest_test_typeName());
   }
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index 24c36cb..970743d 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -73,14 +73,15 @@
 
 Future _invokeSymbolIfExists(InstanceMirror instanceMirror, Symbol symbol) {
   var invocationResult = null;
+  InstanceMirror closure;
   try {
-    invocationResult = instanceMirror.invoke(symbol, []).reflectee;
+    closure = instanceMirror.getField(symbol);
   } on NoSuchMethodError {}
-  if (invocationResult is Future) {
-    return invocationResult;
-  } else {
-    return new Future.value(invocationResult);
+
+  if (closure is ClosureMirror) {
+    invocationResult = closure.apply([]).reflectee;
   }
+  return new Future.value(invocationResult);
 }
 
 /**
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index c152773..cf96040 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -6,6 +6,8 @@
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/embedder.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
@@ -34,13 +36,20 @@
         'fox': [resourceProvider.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
+
+      expectResolved(dartUri, filePath) {
+        Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
+        expect(source, isNotNull, reason: dartUri);
+        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+      }
+
       // We have four mappings.
       expect(resolver.length, equals(4));
       // Check that they map to the correct paths.
-      expect(resolver['dart:fox'], equals("/tmp/slippy.dart"));
-      expect(resolver['dart:bear'], equals("/tmp/grizzly.dart"));
-      expect(resolver['dart:relative'], equals("/relative.dart"));
-      expect(resolver['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+      expectResolved('dart:fox', '/tmp/slippy.dart');
+      expectResolved('dart:bear', '/tmp/grizzly.dart');
+      expectResolved('dart:relative', '/relative.dart');
+      expectResolved('dart:deep', '/tmp/deep/directory/file.dart');
     });
     test('test_BadYAML', () {
       var locator = new EmbedderYamlLocator(null);
@@ -52,15 +61,91 @@
         'fox': [resourceProvider.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
-      var source = resolver.resolveAbsolute(Uri.parse('dart:fox'));
-      expect(source, isNotNull);
-      // Restore source's uri.
-      var restoreUri = resolver.restoreAbsolute(source);
-      expect(restoreUri, isNotNull);
-      // Verify that it is 'dart:fox'.
-      expect(restoreUri.toString(), equals('dart:fox'));
-      expect(restoreUri.scheme, equals('dart'));
-      expect(restoreUri.path, equals('fox'));
+
+      expectRestore(String dartUri, [String expected]) {
+        var source = resolver.resolveAbsolute(Uri.parse(dartUri));
+        expect(source, isNotNull);
+        // Restore source's uri.
+        var restoreUri = resolver.restoreAbsolute(source);
+        expect(restoreUri, isNotNull, reason: dartUri);
+        // Verify that it is 'dart:fox'.
+        expect(restoreUri.toString(), equals(expected ?? dartUri));
+        List<String> split = (expected ?? dartUri).split(':');
+        expect(restoreUri.scheme, equals(split[0]));
+        expect(restoreUri.path, equals(split[1]));
+      }
+
+      try {
+        expectRestore('dart:deep');
+        expectRestore('dart:deep/file.dart', 'dart:deep');
+        expectRestore('dart:deep/part.dart');
+        expectRestore('dart:deep/deep/file.dart');
+        if (JavaFile.separator == '\\') {
+          // See https://github.com/dart-lang/sdk/issues/25498
+          fail('expected to fail on Windows');
+        }
+      } catch (_) {
+        // Test is broken on Windows, but should run elsewhere
+        if (JavaFile.separator != '\\') {
+          rethrow;
+        }
+      }
+    });
+
+    test('test_EmbedderSdk_fromFileUri', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var sdk = resolver.dartSdk;
+
+      expectSource(String filePath, String dartUri) {
+        var uri = Uri.parse(filePath);
+        var source = sdk.fromFileUri(uri);
+        expect(source, isNotNull, reason: filePath);
+        expect(source.uri.toString(), dartUri);
+        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+      }
+
+      //TODO(danrubel) fix embedder on Windows
+      isWindows() => JavaFile.separator == '\\';
+      try {
+        expectSource('/tmp/slippy.dart', 'dart:fox');
+        expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
+        expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
+        if (isWindows()) fail('expected to fail on windows');
+      } catch (e) {
+        if (!isWindows()) rethrow;
+      }
+    });
+    test('test_EmbedderSdk_getSdkLibrary', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var sdk = resolver.dartSdk;
+      var lib = sdk.getSdkLibrary('dart:fox');
+      expect(lib, isNotNull);
+      expect(lib.path, '/tmp/slippy.dart');
+      expect(lib.shortName, 'fox');
+    });
+    test('test_EmbedderSdk_mapDartUri', () {
+      var locator = new EmbedderYamlLocator({
+        'fox': [resourceProvider.getResource('/tmp')]
+      });
+      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var sdk = resolver.dartSdk;
+
+      expectSource(String dartUri, String filePath) {
+        var source = sdk.mapDartUri(dartUri);
+        expect(source, isNotNull, reason: filePath);
+        expect(source.uri.toString(), dartUri);
+        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+      }
+
+      expectSource('dart:fox', '/tmp/slippy.dart');
+      expectSource('dart:deep', '/tmp/deep/directory/file.dart');
+      expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart');
     });
   });
 }
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 41feb593..d37179a 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -5,15 +5,17 @@
 library analyzer.test.src.context.context_test;
 
 import 'dart:async';
+import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/dart/element/visitor.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/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -2002,6 +2004,72 @@
     _assertNoExceptions();
   }
 
+  void test_resolveCompilationUnit_existingElementModel() {
+    Source source = addSource(
+        '/test.dart',
+        r'''
+library test;
+
+String topLevelVariable;
+int get topLevelGetter => 0;
+void set topLevelSetter(int value) {}
+String topLevelFunction(int i) => '';
+
+typedef String FunctionTypeAlias(int i);
+
+enum EnumeratedType {Invalid, Valid}
+
+class ClassOne {
+  int instanceField;
+  static int staticField;
+
+  ClassOne();
+  ClassOne.named();
+
+  int get instanceGetter => 0;
+  static String get staticGetter => '';
+
+  void set instanceSetter(int value) {}
+  static void set staticSetter(int value) {}
+
+  int instanceMethod(int first, [int second = 0]) {
+    int localVariable;
+    int localFunction(String s) {}
+  }
+  static String staticMethod(int first, {int second: 0}) => '';
+}
+
+class ClassTwo {
+  // Implicit no-argument constructor
+}
+''');
+    context.resolveCompilationUnit2(source, source);
+    LibraryElement firstElement = context.computeLibraryElement(source);
+    _ElementGatherer gatherer = new _ElementGatherer();
+    firstElement.accept(gatherer);
+
+    CacheEntry entry =
+        context.analysisCache.get(new LibrarySpecificUnit(source, source));
+    entry.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT4, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT5, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT6, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT7, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT8, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
+    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
+
+    context.resolveCompilationUnit2(source, source);
+    LibraryElement secondElement = context.computeLibraryElement(source);
+    _ElementComparer comparer = new _ElementComparer(gatherer.elements);
+    secondElement.accept(comparer);
+    comparer.expectNoDifferences();
+  }
+
   void test_resolveCompilationUnit_import_relative() {
     Source sourceA =
         addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
@@ -2731,3 +2799,82 @@
   @override
   bool contains(Source source) => source == libB;
 }
+
+/**
+ * A visitor that can be used to compare all of the elements in an element model
+ * with a previously created map of elements. The class [ElementGatherer] can be
+ * used to create the map of elements.
+ */
+class _ElementComparer extends GeneralizingElementVisitor {
+  /**
+   * The previously created map of elements.
+   */
+  final Map<Element, Element> previousElements;
+
+  /**
+   * The number of elements that were found to have been overwritten.
+   */
+  int overwrittenCount = 0;
+
+  /**
+   * A buffer to which a description of the overwritten elements will be written.
+   */
+  final StringBuffer buffer = new StringBuffer();
+
+  /**
+   * Initialize a newly created visitor.
+   */
+  _ElementComparer(this.previousElements);
+
+  /**
+   * Expect that no differences were found, causing the test to fail if that
+   * wasn't the case.
+   */
+  void expectNoDifferences() {
+    if (overwrittenCount > 0) {
+      fail('Found $overwrittenCount overwritten elements.$buffer');
+    }
+  }
+
+  @override
+  void visitElement(Element element) {
+    Element previousElement = previousElements[element];
+    if (!identical(previousElement, element)) {
+      if (overwrittenCount == 0) {
+        buffer.writeln();
+      }
+      overwrittenCount++;
+      buffer.writeln('Overwritten element:');
+      Element currentElement = element;
+      while (currentElement != null) {
+        buffer.write('  ');
+        buffer.writeln(currentElement.toString());
+        currentElement = currentElement.enclosingElement;
+      }
+    }
+    super.visitElement(element);
+  }
+}
+
+/**
+ * A visitor that can be used to collect all of the elements in an element
+ * model.
+ */
+class _ElementGatherer extends GeneralizingElementVisitor {
+  /**
+   * The map in which the elements are collected. The value of each key is the
+   * key itself.
+   */
+  Map<Element, Element> elements = new HashMap<Element, Element>();
+
+  /**
+   * Initialize the visitor.
+   */
+  _ElementGatherer();
+
+  @override
+  void visitElement(Element element) {
+    elements[element] = element;
+    super.visitElement(element);
+  }
+}
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 5cf93dd..b67c4a5 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -228,12 +228,6 @@
       _analysisContext = new _SdkAnalysisContext(this);
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
-      ChangeSet changeSet = new ChangeSet();
-      for (String uri in uris) {
-        Source source = factory.forUri(uri);
-        changeSet.addedSource(source);
-      }
-      _analysisContext.applyChanges(changeSet);
     }
     return _analysisContext;
   }
diff --git a/pkg/analyzer/test/src/dart/ast/test_all.dart b/pkg/analyzer/test/src/dart/ast/test_all.dart
new file mode 100644
index 0000000..f0648c4
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/ast/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.src.dart.ast.test_all;
+
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'utilities_test.dart' as utilities;
+
+/// Utility for manually running all tests.
+main() {
+  initializeTestEnvironment();
+  group('ast tests', () {
+    utilities.main();
+  });
+}
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
similarity index 63%
rename from pkg/analyzer/test/generated/ast_test.dart
rename to pkg/analyzer/test/src/dart/ast/utilities_test.dart
index bff9b8b..8531637 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -2,9 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.generated.ast_test;
+library analyzer.test.src.dart.ast.utilities_test;
 
-import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart' show Predicate;
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -13,211 +14,17 @@
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:unittest/unittest.dart';
 
-import '../reflective_tests.dart';
-import '../utils.dart';
-import 'parser_test.dart' show ParserTestCase;
-import 'test_support.dart';
+import '../../../generated/parser_test.dart' show ParserTestCase;
+import '../../../generated/test_support.dart';
+import '../../../reflective_tests.dart';
+import '../../../utils.dart';
 
 main() {
   initializeTestEnvironment();
-  runReflectiveTests(BreadthFirstVisitorTest);
-  runReflectiveTests(ClassDeclarationTest);
-  runReflectiveTests(ClassTypeAliasTest);
   runReflectiveTests(ConstantEvaluatorTest);
-  runReflectiveTests(ConstructorDeclarationTest);
-  runReflectiveTests(FieldFormalParameterTest);
-  runReflectiveTests(IndexExpressionTest);
-  runReflectiveTests(NodeListTest);
   runReflectiveTests(NodeLocatorTest);
   runReflectiveTests(NodeLocator2Test);
-  runReflectiveTests(SimpleIdentifierTest);
-  runReflectiveTests(SimpleStringLiteralTest);
-  runReflectiveTests(StringInterpolationTest);
   runReflectiveTests(ToSourceVisitorTest);
-  runReflectiveTests(VariableDeclarationTest);
-}
-
-class AssignmentKind extends Enum<AssignmentKind> {
-  static const AssignmentKind BINARY = const AssignmentKind('BINARY', 0);
-
-  static const AssignmentKind COMPOUND_LEFT =
-      const AssignmentKind('COMPOUND_LEFT', 1);
-
-  static const AssignmentKind COMPOUND_RIGHT =
-      const AssignmentKind('COMPOUND_RIGHT', 2);
-
-  static const AssignmentKind POSTFIX_INC =
-      const AssignmentKind('POSTFIX_INC', 3);
-
-  static const AssignmentKind PREFIX_DEC =
-      const AssignmentKind('PREFIX_DEC', 4);
-
-  static const AssignmentKind PREFIX_INC =
-      const AssignmentKind('PREFIX_INC', 5);
-
-  static const AssignmentKind PREFIX_NOT =
-      const AssignmentKind('PREFIX_NOT', 6);
-
-  static const AssignmentKind SIMPLE_LEFT =
-      const AssignmentKind('SIMPLE_LEFT', 7);
-
-  static const AssignmentKind SIMPLE_RIGHT =
-      const AssignmentKind('SIMPLE_RIGHT', 8);
-
-  static const AssignmentKind NONE = const AssignmentKind('NONE', 9);
-
-  static const List<AssignmentKind> values = const [
-    BINARY,
-    COMPOUND_LEFT,
-    COMPOUND_RIGHT,
-    POSTFIX_INC,
-    PREFIX_DEC,
-    PREFIX_INC,
-    PREFIX_NOT,
-    SIMPLE_LEFT,
-    SIMPLE_RIGHT,
-    NONE
-  ];
-
-  const AssignmentKind(String name, int ordinal) : super(name, ordinal);
-}
-
-class BreadthFirstVisitor_BreadthFirstVisitorTest_testIt
-    extends BreadthFirstVisitor<Object> {
-  List<AstNode> nodes;
-
-  BreadthFirstVisitor_BreadthFirstVisitorTest_testIt(this.nodes) : super();
-
-  @override
-  Object visitNode(AstNode node) {
-    nodes.add(node);
-    return super.visitNode(node);
-  }
-}
-
-@reflectiveTest
-class BreadthFirstVisitorTest extends ParserTestCase {
-  void test_it() {
-    String source = r'''
-class A {
-  bool get g => true;
-}
-class B {
-  int f() {
-    num q() {
-      return 3;
-    }
-  return q() + 4;
-  }
-}
-A f(var p) {
-  if ((p as A).g) {
-    return p;
-  } else {
-    return null;
-  }
-}''';
-    CompilationUnit unit = ParserTestCase.parseCompilationUnit(source);
-    List<AstNode> nodes = new List<AstNode>();
-    BreadthFirstVisitor<Object> visitor =
-        new BreadthFirstVisitor_BreadthFirstVisitorTest_testIt(nodes);
-    visitor.visitAllNodes(unit);
-    expect(nodes, hasLength(59));
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is CompilationUnit, CompilationUnit, nodes[0]);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ClassDeclaration, ClassDeclaration, nodes[2]);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is FunctionDeclaration, FunctionDeclaration, nodes[3]);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is FunctionDeclarationStatement,
-        FunctionDeclarationStatement,
-        nodes[27]);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is IntegerLiteral, IntegerLiteral, nodes[58]);
-    //3
-  }
-}
-
-@reflectiveTest
-class ClassDeclarationTest extends ParserTestCase {
-  void test_getConstructor() {
-    List<ConstructorInitializer> initializers =
-        new List<ConstructorInitializer>();
-    ConstructorDeclaration defaultConstructor = AstFactory
-        .constructorDeclaration(AstFactory.identifier3("Test"), null,
-            AstFactory.formalParameterList(), initializers);
-    ConstructorDeclaration aConstructor = AstFactory.constructorDeclaration(
-        AstFactory.identifier3("Test"),
-        "a",
-        AstFactory.formalParameterList(),
-        initializers);
-    ConstructorDeclaration bConstructor = AstFactory.constructorDeclaration(
-        AstFactory.identifier3("Test"),
-        "b",
-        AstFactory.formalParameterList(),
-        initializers);
-    ClassDeclaration clazz = AstFactory.classDeclaration(null, "Test", null,
-        null, null, null, [defaultConstructor, aConstructor, bConstructor]);
-    expect(clazz.getConstructor(null), same(defaultConstructor));
-    expect(clazz.getConstructor("a"), same(aConstructor));
-    expect(clazz.getConstructor("b"), same(bConstructor));
-    expect(clazz.getConstructor("noSuchConstructor"), same(null));
-  }
-
-  void test_getField() {
-    VariableDeclaration aVar = AstFactory.variableDeclaration("a");
-    VariableDeclaration bVar = AstFactory.variableDeclaration("b");
-    VariableDeclaration cVar = AstFactory.variableDeclaration("c");
-    ClassDeclaration clazz =
-        AstFactory.classDeclaration(null, "Test", null, null, null, null, [
-      AstFactory.fieldDeclaration2(false, null, [aVar]),
-      AstFactory.fieldDeclaration2(false, null, [bVar, cVar])
-    ]);
-    expect(clazz.getField("a"), same(aVar));
-    expect(clazz.getField("b"), same(bVar));
-    expect(clazz.getField("c"), same(cVar));
-    expect(clazz.getField("noSuchField"), same(null));
-  }
-
-  void test_getMethod() {
-    MethodDeclaration aMethod = AstFactory.methodDeclaration(null, null, null,
-        null, AstFactory.identifier3("a"), AstFactory.formalParameterList());
-    MethodDeclaration bMethod = AstFactory.methodDeclaration(null, null, null,
-        null, AstFactory.identifier3("b"), AstFactory.formalParameterList());
-    ClassDeclaration clazz = AstFactory.classDeclaration(
-        null, "Test", null, null, null, null, [aMethod, bMethod]);
-    expect(clazz.getMethod("a"), same(aMethod));
-    expect(clazz.getMethod("b"), same(bMethod));
-    expect(clazz.getMethod("noSuchMethod"), same(null));
-  }
-
-  void test_isAbstract() {
-    expect(
-        AstFactory
-            .classDeclaration(null, "A", null, null, null, null)
-            .isAbstract,
-        isFalse);
-    expect(
-        AstFactory
-            .classDeclaration(Keyword.ABSTRACT, "B", null, null, null, null)
-            .isAbstract,
-        isTrue);
-  }
-}
-
-@reflectiveTest
-class ClassTypeAliasTest extends ParserTestCase {
-  void test_isAbstract() {
-    expect(
-        AstFactory.classTypeAlias("A", null, null, null, null, null).isAbstract,
-        isFalse);
-    expect(
-        AstFactory
-            .classTypeAlias("B", null, Keyword.ABSTRACT, null, null, null)
-            .isAbstract,
-        isTrue);
-  }
 }
 
 @reflectiveTest
@@ -525,427 +332,6 @@
 }
 
 @reflectiveTest
-class ConstructorDeclarationTest extends EngineTestCase {
-  void test_firstTokenAfterCommentAndMetadata_all_inverted() {
-    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-    externalKeyword.offset = 14;
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        Keyword.CONST,
-        Keyword.FACTORY,
-        AstFactory.identifier3('int'),
-        null,
-        null,
-        null,
-        null);
-    declaration.externalKeyword = externalKeyword;
-    declaration.constKeyword.offset = 8;
-    Token factoryKeyword = declaration.factoryKeyword;
-    factoryKeyword.offset = 0;
-    expect(declaration.firstTokenAfterCommentAndMetadata, factoryKeyword);
-  }
-
-  void test_firstTokenAfterCommentAndMetadata_all_normal() {
-    Token token = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-    token.offset = 0;
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        Keyword.CONST,
-        Keyword.FACTORY,
-        AstFactory.identifier3('int'),
-        null,
-        null,
-        null,
-        null);
-    declaration.externalKeyword = token;
-    declaration.constKeyword.offset = 9;
-    declaration.factoryKeyword.offset = 15;
-    expect(declaration.firstTokenAfterCommentAndMetadata, token);
-  }
-
-  void test_firstTokenAfterCommentAndMetadata_constOnly() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        Keyword.CONST,
-        null,
-        AstFactory.identifier3('int'),
-        null,
-        null,
-        null,
-        null);
-    expect(declaration.firstTokenAfterCommentAndMetadata,
-        declaration.constKeyword);
-  }
-
-  void test_firstTokenAfterCommentAndMetadata_externalOnly() {
-    Token externalKeyword = TokenFactory.tokenFromKeyword(Keyword.EXTERNAL);
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        null, null, AstFactory.identifier3('int'), null, null, null, null);
-    declaration.externalKeyword = externalKeyword;
-    expect(declaration.firstTokenAfterCommentAndMetadata, externalKeyword);
-  }
-
-  void test_firstTokenAfterCommentAndMetadata_factoryOnly() {
-    ConstructorDeclaration declaration = AstFactory.constructorDeclaration2(
-        null,
-        Keyword.FACTORY,
-        AstFactory.identifier3('int'),
-        null,
-        null,
-        null,
-        null);
-    expect(declaration.firstTokenAfterCommentAndMetadata,
-        declaration.factoryKeyword);
-  }
-}
-
-@reflectiveTest
-class FieldFormalParameterTest extends EngineTestCase {
-  void test_endToken_noParameters() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter2('field');
-    expect(parameter.endToken, parameter.identifier.endToken);
-  }
-
-  void test_endToken_parameters() {
-    FieldFormalParameter parameter = AstFactory.fieldFormalParameter(
-        null, null, 'field', AstFactory.formalParameterList([]));
-    expect(parameter.endToken, parameter.parameters.endToken);
-  }
-}
-
-@reflectiveTest
-class IndexExpressionTest extends EngineTestCase {
-  void test_inGetterContext_assignment_compound_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // a[b] += c
-    AstFactory.assignmentExpression(
-        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
-    expect(expression.inGetterContext(), isTrue);
-  }
-
-  void test_inGetterContext_assignment_simple_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // a[b] = c
-    AstFactory.assignmentExpression(
-        expression, TokenType.EQ, AstFactory.identifier3("c"));
-    expect(expression.inGetterContext(), isFalse);
-  }
-
-  void test_inGetterContext_nonAssignment() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // a[b] + c
-    AstFactory.binaryExpression(
-        expression, TokenType.PLUS, AstFactory.identifier3("c"));
-    expect(expression.inGetterContext(), isTrue);
-  }
-
-  void test_inSetterContext_assignment_compound_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // a[b] += c
-    AstFactory.assignmentExpression(
-        expression, TokenType.PLUS_EQ, AstFactory.identifier3("c"));
-    expect(expression.inSetterContext(), isTrue);
-  }
-
-  void test_inSetterContext_assignment_compound_right() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // c += a[b]
-    AstFactory.assignmentExpression(
-        AstFactory.identifier3("c"), TokenType.PLUS_EQ, expression);
-    expect(expression.inSetterContext(), isFalse);
-  }
-
-  void test_inSetterContext_assignment_simple_left() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // a[b] = c
-    AstFactory.assignmentExpression(
-        expression, TokenType.EQ, AstFactory.identifier3("c"));
-    expect(expression.inSetterContext(), isTrue);
-  }
-
-  void test_inSetterContext_assignment_simple_right() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // c = a[b]
-    AstFactory.assignmentExpression(
-        AstFactory.identifier3("c"), TokenType.EQ, expression);
-    expect(expression.inSetterContext(), isFalse);
-  }
-
-  void test_inSetterContext_nonAssignment() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    AstFactory.binaryExpression(
-        expression, TokenType.PLUS, AstFactory.identifier3("c"));
-    // a[b] + cc
-    expect(expression.inSetterContext(), isFalse);
-  }
-
-  void test_inSetterContext_postfix() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
-    // a[b]++
-    expect(expression.inSetterContext(), isTrue);
-  }
-
-  void test_inSetterContext_prefix_bang() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // !a[b]
-    AstFactory.prefixExpression(TokenType.BANG, expression);
-    expect(expression.inSetterContext(), isFalse);
-  }
-
-  void test_inSetterContext_prefix_minusMinus() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // --a[b]
-    AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
-    expect(expression.inSetterContext(), isTrue);
-  }
-
-  void test_inSetterContext_prefix_plusPlus() {
-    IndexExpression expression = AstFactory.indexExpression(
-        AstFactory.identifier3("a"), AstFactory.identifier3("b"));
-    // ++a[b]
-    AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
-    expect(expression.inSetterContext(), isTrue);
-  }
-}
-
-@reflectiveTest
-class NodeListTest extends EngineTestCase {
-  void test_add() {
-    AstNode parent = AstFactory.argumentList();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    NodeList<AstNode> list = new NodeList<AstNode>(parent);
-    list.insert(0, secondNode);
-    list.insert(0, firstNode);
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    AstNode thirdNode = AstFactory.booleanLiteral(false);
-    list.insert(1, thirdNode);
-    expect(list, hasLength(3));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(thirdNode));
-    expect(list[2], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    expect(thirdNode.parent, same(parent));
-  }
-
-  void test_add_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list.insert(-1, AstFactory.booleanLiteral(true));
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_add_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list.insert(1, AstFactory.booleanLiteral(true));
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_addAll() {
-    AstNode parent = AstFactory.argumentList();
-    List<AstNode> firstNodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    firstNodes.add(firstNode);
-    firstNodes.add(secondNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(parent);
-    list.addAll(firstNodes);
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    List<AstNode> secondNodes = new List<AstNode>();
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    AstNode fourthNode = AstFactory.booleanLiteral(false);
-    secondNodes.add(thirdNode);
-    secondNodes.add(fourthNode);
-    list.addAll(secondNodes);
-    expect(list, hasLength(4));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(secondNode));
-    expect(list[2], same(thirdNode));
-    expect(list[3], same(fourthNode));
-    expect(firstNode.parent, same(parent));
-    expect(secondNode.parent, same(parent));
-    expect(thirdNode.parent, same(parent));
-    expect(fourthNode.parent, same(parent));
-  }
-
-  void test_creation() {
-    AstNode owner = AstFactory.argumentList();
-    NodeList<AstNode> list = new NodeList<AstNode>(owner);
-    expect(list, isNotNull);
-    expect(list, hasLength(0));
-    expect(list.owner, same(owner));
-  }
-
-  void test_get_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list[-1];
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_get_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list[1];
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_getBeginToken_empty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    expect(list.beginToken, isNull);
-  }
-
-  void test_getBeginToken_nonEmpty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    AstNode node =
-        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
-    list.add(node);
-    expect(list.beginToken, same(node.beginToken));
-  }
-
-  void test_getEndToken_empty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    expect(list.endToken, isNull);
-  }
-
-  void test_getEndToken_nonEmpty() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    AstNode node =
-        AstFactory.parenthesizedExpression(AstFactory.booleanLiteral(true));
-    list.add(node);
-    expect(list.endToken, same(node.endToken));
-  }
-
-  void test_indexOf() {
-    List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    AstNode fourthNode = AstFactory.booleanLiteral(false);
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    expect(list.indexOf(firstNode), 0);
-    expect(list.indexOf(secondNode), 1);
-    expect(list.indexOf(thirdNode), 2);
-    expect(list.indexOf(fourthNode), -1);
-    expect(list.indexOf(null), -1);
-  }
-
-  void test_remove() {
-    List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    expect(list.removeAt(1), same(secondNode));
-    expect(list, hasLength(2));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(thirdNode));
-  }
-
-  void test_remove_negative() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list.removeAt(-1);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_remove_tooBig() {
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      list.removeAt(1);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_set() {
-    List<AstNode> nodes = new List<AstNode>();
-    AstNode firstNode = AstFactory.booleanLiteral(true);
-    AstNode secondNode = AstFactory.booleanLiteral(false);
-    AstNode thirdNode = AstFactory.booleanLiteral(true);
-    nodes.add(firstNode);
-    nodes.add(secondNode);
-    nodes.add(thirdNode);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    list.addAll(nodes);
-    expect(list, hasLength(3));
-    AstNode fourthNode = AstFactory.integer(0);
-    expect(javaListSet(list, 1, fourthNode), same(secondNode));
-    expect(list, hasLength(3));
-    expect(list[0], same(firstNode));
-    expect(list[1], same(fourthNode));
-    expect(list[2], same(thirdNode));
-  }
-
-  void test_set_negative() {
-    AstNode node = AstFactory.booleanLiteral(true);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      javaListSet(list, -1, node);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-
-  void test_set_tooBig() {
-    AstNode node = AstFactory.booleanLiteral(true);
-    NodeList<AstNode> list = new NodeList<AstNode>(AstFactory.argumentList());
-    try {
-      javaListSet(list, 1, node);
-      fail("Expected IndexOutOfBoundsException");
-    } on RangeError {
-      // Expected
-    }
-  }
-}
-
-@reflectiveTest
 class NodeLocator2Test extends ParserTestCase {
   void test_onlyStartOffset() {
     String code = ' int vv; ';
@@ -1042,659 +428,6 @@
 }
 
 @reflectiveTest
-class SimpleIdentifierTest extends ParserTestCase {
-  void test_inDeclarationContext_catch_exception() {
-    SimpleIdentifier identifier =
-        AstFactory.catchClause("e").exceptionParameter;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_catch_stack() {
-    SimpleIdentifier identifier =
-        AstFactory.catchClause2("e", "s").stackTraceParameter;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_classDeclaration() {
-    SimpleIdentifier identifier =
-        AstFactory.classDeclaration(null, "C", null, null, null, null).name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_classTypeAlias() {
-    SimpleIdentifier identifier =
-        AstFactory.classTypeAlias("C", null, null, null, null, null).name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_constructorDeclaration() {
-    SimpleIdentifier identifier = AstFactory
-        .constructorDeclaration(AstFactory.identifier3("C"), "c", null, null)
-        .name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_declaredIdentifier() {
-    DeclaredIdentifier declaredIdentifier = AstFactory.declaredIdentifier3("v");
-    SimpleIdentifier identifier = declaredIdentifier.identifier;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_enumConstantDeclaration() {
-    EnumDeclaration enumDeclaration =
-        AstFactory.enumDeclaration2('MyEnum', ['CONST']);
-    SimpleIdentifier identifier = enumDeclaration.constants[0].name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_enumDeclaration() {
-    EnumDeclaration enumDeclaration =
-        AstFactory.enumDeclaration2('MyEnum', ['A', 'B', 'C']);
-    SimpleIdentifier identifier = enumDeclaration.name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_fieldFormalParameter() {
-    SimpleIdentifier identifier =
-        AstFactory.fieldFormalParameter2("p").identifier;
-    expect(identifier.inDeclarationContext(), isFalse);
-  }
-
-  void test_inDeclarationContext_functionDeclaration() {
-    SimpleIdentifier identifier =
-        AstFactory.functionDeclaration(null, null, "f", null).name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_functionTypeAlias() {
-    SimpleIdentifier identifier =
-        AstFactory.typeAlias(null, "F", null, null).name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_label_false() {
-    SimpleIdentifier identifier =
-        AstFactory.namedExpression2("l", AstFactory.integer(0)).name.label;
-    expect(identifier.inDeclarationContext(), isFalse);
-  }
-
-  void test_inDeclarationContext_label_true() {
-    Label label = AstFactory.label2("l");
-    SimpleIdentifier identifier = label.label;
-    AstFactory.labeledStatement([label], AstFactory.emptyStatement());
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_methodDeclaration() {
-    SimpleIdentifier identifier = AstFactory.identifier3("m");
-    AstFactory.methodDeclaration2(
-        null, null, null, null, identifier, null, null);
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_prefix() {
-    SimpleIdentifier identifier =
-        AstFactory.importDirective3("uri", "pref").prefix;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_simpleFormalParameter() {
-    SimpleIdentifier identifier =
-        AstFactory.simpleFormalParameter3("p").identifier;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_typeParameter_bound() {
-    TypeName bound = AstFactory.typeName4("A");
-    SimpleIdentifier identifier = bound.name as SimpleIdentifier;
-    AstFactory.typeParameter2("E", bound);
-    expect(identifier.inDeclarationContext(), isFalse);
-  }
-
-  void test_inDeclarationContext_typeParameter_name() {
-    SimpleIdentifier identifier = AstFactory.typeParameter("E").name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inDeclarationContext_variableDeclaration() {
-    SimpleIdentifier identifier = AstFactory.variableDeclaration("v").name;
-    expect(identifier.inDeclarationContext(), isTrue);
-  }
-
-  void test_inGetterContext() {
-    for (WrapperKind wrapper in WrapperKind.values) {
-      for (AssignmentKind assignment in AssignmentKind.values) {
-        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
-        if (assignment == AssignmentKind.SIMPLE_LEFT &&
-            wrapper != WrapperKind.PREFIXED_LEFT &&
-            wrapper != WrapperKind.PROPERTY_LEFT) {
-          if (identifier.inGetterContext()) {
-            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
-          }
-        } else {
-          if (!identifier.inGetterContext()) {
-            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
-          }
-        }
-      }
-    }
-  }
-
-  void test_inGetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
-    Expression iterator = AstFactory.listLiteral();
-    Statement body = AstFactory.block();
-    AstFactory.forEachStatement2(identifier, iterator, body);
-    expect(identifier.inGetterContext(), isFalse);
-  }
-
-  void test_inReferenceContext() {
-    SimpleIdentifier identifier = AstFactory.identifier3("id");
-    AstFactory.namedExpression(
-        AstFactory.label(identifier), AstFactory.identifier3("_"));
-    expect(identifier.inGetterContext(), isFalse);
-    expect(identifier.inSetterContext(), isFalse);
-  }
-
-  void test_inSetterContext() {
-    for (WrapperKind wrapper in WrapperKind.values) {
-      for (AssignmentKind assignment in AssignmentKind.values) {
-        SimpleIdentifier identifier = _createIdentifier(wrapper, assignment);
-        if (wrapper == WrapperKind.PREFIXED_LEFT ||
-            wrapper == WrapperKind.PROPERTY_LEFT ||
-            assignment == AssignmentKind.BINARY ||
-            assignment == AssignmentKind.COMPOUND_RIGHT ||
-            assignment == AssignmentKind.PREFIX_NOT ||
-            assignment == AssignmentKind.SIMPLE_RIGHT ||
-            assignment == AssignmentKind.NONE) {
-          if (identifier.inSetterContext()) {
-            fail("Expected ${_topMostNode(identifier).toSource()} to be false");
-          }
-        } else {
-          if (!identifier.inSetterContext()) {
-            fail("Expected ${_topMostNode(identifier).toSource()} to be true");
-          }
-        }
-      }
-    }
-  }
-
-  void test_inSetterContext_forEachLoop() {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
-    Expression iterator = AstFactory.listLiteral();
-    Statement body = AstFactory.block();
-    AstFactory.forEachStatement2(identifier, iterator, body);
-    expect(identifier.inSetterContext(), isTrue);
-  }
-
-  void test_isQualified_inMethodInvocation_noTarget() {
-    MethodInvocation invocation =
-        AstFactory.methodInvocation2("test", [AstFactory.identifier3("arg0")]);
-    SimpleIdentifier identifier = invocation.methodName;
-    expect(identifier.isQualified, isFalse);
-  }
-
-  void test_isQualified_inMethodInvocation_withTarget() {
-    MethodInvocation invocation = AstFactory.methodInvocation(
-        AstFactory.identifier3("target"),
-        "test",
-        [AstFactory.identifier3("arg0")]);
-    SimpleIdentifier identifier = invocation.methodName;
-    expect(identifier.isQualified, isTrue);
-  }
-
-  void test_isQualified_inPrefixedIdentifier_name() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.identifier4("prefix", identifier);
-    expect(identifier.isQualified, isTrue);
-  }
-
-  void test_isQualified_inPrefixedIdentifier_prefix() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.identifier(identifier, AstFactory.identifier3("name"));
-    expect(identifier.isQualified, isFalse);
-  }
-
-  void test_isQualified_inPropertyAccess_name() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.propertyAccess(AstFactory.identifier3("target"), identifier);
-    expect(identifier.isQualified, isTrue);
-  }
-
-  void test_isQualified_inPropertyAccess_target() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.propertyAccess(identifier, AstFactory.identifier3("name"));
-    expect(identifier.isQualified, isFalse);
-  }
-
-  void test_isQualified_inReturnStatement() {
-    SimpleIdentifier identifier = AstFactory.identifier3("test");
-    AstFactory.returnStatement2(identifier);
-    expect(identifier.isQualified, isFalse);
-  }
-
-  SimpleIdentifier _createIdentifier(
-      WrapperKind wrapper, AssignmentKind assignment) {
-    SimpleIdentifier identifier = AstFactory.identifier3("a");
-    Expression expression = identifier;
-    while (true) {
-      if (wrapper == WrapperKind.PREFIXED_LEFT) {
-        expression =
-            AstFactory.identifier(identifier, AstFactory.identifier3("_"));
-      } else if (wrapper == WrapperKind.PREFIXED_RIGHT) {
-        expression =
-            AstFactory.identifier(AstFactory.identifier3("_"), identifier);
-      } else if (wrapper == WrapperKind.PROPERTY_LEFT) {
-        expression = AstFactory.propertyAccess2(expression, "_");
-      } else if (wrapper == WrapperKind.PROPERTY_RIGHT) {
-        expression =
-            AstFactory.propertyAccess(AstFactory.identifier3("_"), identifier);
-      } else if (wrapper == WrapperKind.NONE) {}
-      break;
-    }
-    while (true) {
-      if (assignment == AssignmentKind.BINARY) {
-        AstFactory.binaryExpression(
-            expression, TokenType.PLUS, AstFactory.identifier3("_"));
-      } else if (assignment == AssignmentKind.COMPOUND_LEFT) {
-        AstFactory.assignmentExpression(
-            expression, TokenType.PLUS_EQ, AstFactory.identifier3("_"));
-      } else if (assignment == AssignmentKind.COMPOUND_RIGHT) {
-        AstFactory.assignmentExpression(
-            AstFactory.identifier3("_"), TokenType.PLUS_EQ, expression);
-      } else if (assignment == AssignmentKind.POSTFIX_INC) {
-        AstFactory.postfixExpression(expression, TokenType.PLUS_PLUS);
-      } else if (assignment == AssignmentKind.PREFIX_DEC) {
-        AstFactory.prefixExpression(TokenType.MINUS_MINUS, expression);
-      } else if (assignment == AssignmentKind.PREFIX_INC) {
-        AstFactory.prefixExpression(TokenType.PLUS_PLUS, expression);
-      } else if (assignment == AssignmentKind.PREFIX_NOT) {
-        AstFactory.prefixExpression(TokenType.BANG, expression);
-      } else if (assignment == AssignmentKind.SIMPLE_LEFT) {
-        AstFactory.assignmentExpression(
-            expression, TokenType.EQ, AstFactory.identifier3("_"));
-      } else if (assignment == AssignmentKind.SIMPLE_RIGHT) {
-        AstFactory.assignmentExpression(
-            AstFactory.identifier3("_"), TokenType.EQ, expression);
-      } else if (assignment == AssignmentKind.NONE) {}
-      break;
-    }
-    return identifier;
-  }
-
-  /**
-   * Return the top-most node in the AST structure containing the given identifier.
-   *
-   * @param identifier the identifier in the AST structure being traversed
-   * @return the root of the AST structure containing the identifier
-   */
-  AstNode _topMostNode(SimpleIdentifier identifier) {
-    AstNode child = identifier;
-    AstNode parent = identifier.parent;
-    while (parent != null) {
-      child = parent;
-      parent = parent.parent;
-    }
-    return child;
-  }
-}
-
-@reflectiveTest
-class SimpleStringLiteralTest extends ParserTestCase {
-  void test_contentsEnd() {
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
-            .contentsEnd,
-        2);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString('"X"'), "X")
-            .contentsEnd,
-        2);
-
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString('"""X"""'), "X")
-            .contentsEnd,
-        4);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
-            .contentsEnd,
-        4);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("'''  \nX'''"), "X").contentsEnd,
-        7);
-
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
-            .contentsEnd,
-        3);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString('r"X"'), "X")
-            .contentsEnd,
-        3);
-
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString('r"""X"""'), "X")
-            .contentsEnd,
-        5);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
-            .contentsEnd,
-        5);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("r'''  \nX'''"), "X").contentsEnd,
-        8);
-  }
-
-  void test_contentsOffset() {
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
-            .contentsOffset,
-        1);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
-            .contentsOffset,
-        1);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X").contentsOffset,
-        3);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
-            .contentsOffset,
-        3);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
-            .contentsOffset,
-        2);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
-            .contentsOffset,
-        2);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X").contentsOffset,
-        4);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
-            .contentsOffset,
-        4);
-    // leading whitespace
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("''' \ \nX''"), "X").contentsOffset,
-        6);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString('r""" \ \nX"""'), "X").contentsOffset,
-        7);
-  }
-
-  void test_isMultiline() {
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X")
-            .isMultiline,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
-            .isMultiline,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
-            .isMultiline,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
-            .isMultiline,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
-            .isMultiline,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
-            .isMultiline,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X").isMultiline,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X").isMultiline,
-        isTrue);
-  }
-
-  void test_isRaw() {
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'X'"), "X").isRaw,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("\"X\""), "X")
-            .isRaw,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("\"\"\"X\"\"\""), "X").isRaw,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("'''X'''"), "X")
-            .isRaw,
-        isFalse);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'X'"), "X")
-            .isRaw,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r\"X\""), "X")
-            .isRaw,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(
-            TokenFactory.tokenFromString("r\"\"\"X\"\"\""), "X").isRaw,
-        isTrue);
-    expect(
-        new SimpleStringLiteral(TokenFactory.tokenFromString("r'''X'''"), "X")
-            .isRaw,
-        isTrue);
-  }
-
-  void test_isSingleQuoted() {
-    // '
-    {
-      var token = TokenFactory.tokenFromString("'X'");
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isTrue);
-    }
-    // '''
-    {
-      var token = TokenFactory.tokenFromString("'''X'''");
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isTrue);
-    }
-    // "
-    {
-      var token = TokenFactory.tokenFromString('"X"');
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // """
-    {
-      var token = TokenFactory.tokenFromString('"""X"""');
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isFalse);
-    }
-  }
-
-  void test_isSingleQuoted_raw() {
-    // r'
-    {
-      var token = TokenFactory.tokenFromString("r'X'");
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isTrue);
-    }
-    // r'''
-    {
-      var token = TokenFactory.tokenFromString("r'''X'''");
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isTrue);
-    }
-    // r"
-    {
-      var token = TokenFactory.tokenFromString('r"X"');
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // r"""
-    {
-      var token = TokenFactory.tokenFromString('r"""X"""');
-      var node = new SimpleStringLiteral(token, null);
-      expect(node.isSingleQuoted, isFalse);
-    }
-  }
-
-  void test_simple() {
-    Token token = TokenFactory.tokenFromString("'value'");
-    SimpleStringLiteral stringLiteral = new SimpleStringLiteral(token, "value");
-    expect(stringLiteral.literal, same(token));
-    expect(stringLiteral.beginToken, same(token));
-    expect(stringLiteral.endToken, same(token));
-    expect(stringLiteral.value, "value");
-  }
-}
-
-@reflectiveTest
-class StringInterpolationTest extends ParserTestCase {
-  void test_contentsOffsetEnd() {
-    AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
-    // 'a${bb}ccc'
-    {
-      var ae = AstFactory.interpolationString("'a", "a");
-      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 1);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-    // '''a${bb}ccc'''
-    {
-      var ae = AstFactory.interpolationString("'''a", "a");
-      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 3);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-    // """a${bb}ccc"""
-    {
-      var ae = AstFactory.interpolationString('"""a', "a");
-      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 3);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-    // r'a${bb}ccc'
-    {
-      var ae = AstFactory.interpolationString("r'a", "a");
-      var cToken = new StringToken(TokenType.STRING, "ccc'", 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 2);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-    // r'''a${bb}ccc'''
-    {
-      var ae = AstFactory.interpolationString("r'''a", "a");
-      var cToken = new StringToken(TokenType.STRING, "ccc'''", 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 4);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-    // r"""a${bb}ccc"""
-    {
-      var ae = AstFactory.interpolationString('r"""a', "a");
-      var cToken = new StringToken(TokenType.STRING, 'ccc"""', 10);
-      var cElement = new InterpolationString(cToken, 'ccc');
-      StringInterpolation node = AstFactory.string([ae, ae, cElement]);
-      expect(node.contentsOffset, 4);
-      expect(node.contentsEnd, 10 + 4 - 1);
-    }
-  }
-
-  void test_isMultiline() {
-    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
-    // '
-    {
-      var a = AstFactory.interpolationString("'a", "a");
-      var c = AstFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isMultiline, isFalse);
-    }
-    // '''
-    {
-      var a = AstFactory.interpolationString("'''a", "a");
-      var c = AstFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isMultiline, isTrue);
-    }
-    // "
-    {
-      var a = AstFactory.interpolationString('"a', "a");
-      var c = AstFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isMultiline, isFalse);
-    }
-    // """
-    {
-      var a = AstFactory.interpolationString('"""a', "a");
-      var c = AstFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isMultiline, isTrue);
-    }
-  }
-
-  void test_isRaw() {
-    StringInterpolation node = AstFactory.string();
-    expect(node.isRaw, isFalse);
-  }
-
-  void test_isSingleQuoted() {
-    var b = AstFactory.interpolationExpression(AstFactory.identifier3('bb'));
-    // "
-    {
-      var a = AstFactory.interpolationString('"a', "a");
-      var c = AstFactory.interpolationString('ccc"', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // """
-    {
-      var a = AstFactory.interpolationString('"""a', "a");
-      var c = AstFactory.interpolationString('ccc"""', "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isFalse);
-    }
-    // '
-    {
-      var a = AstFactory.interpolationString("'a", "a");
-      var c = AstFactory.interpolationString("ccc'", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isTrue);
-    }
-    // '''
-    {
-      var a = AstFactory.interpolationString("'''a", "a");
-      var c = AstFactory.interpolationString("ccc'''", "ccc");
-      StringInterpolation node = AstFactory.string([a, b, c]);
-      expect(node.isSingleQuoted, isTrue);
-    }
-  }
-}
-
-@reflectiveTest
 class ToSourceVisitorTest extends EngineTestCase {
   void test_visitAdjacentStrings() {
     _assertSource(
@@ -3648,8 +2381,8 @@
   void test_visitSwitchCase_noLabels() {
     _assertSource(
         "case a: {}",
-        AstFactory.switchCase(
-            AstFactory.identifier3("a"), [AstFactory.block()]));
+        AstFactory
+            .switchCase(AstFactory.identifier3("a"), [AstFactory.block()]));
   }
 
   void test_visitSwitchCase_singleLabel() {
@@ -3680,8 +2413,8 @@
   void test_visitSwitchDefault_singleLabel() {
     _assertSource(
         "l1: default: {}",
-        AstFactory.switchDefault(
-            [AstFactory.label2("l1")], [AstFactory.block()]));
+        AstFactory
+            .switchDefault([AstFactory.label2("l1")], [AstFactory.block()]));
   }
 
   void test_visitSwitchStatement() {
@@ -3932,50 +2665,3 @@
     expect(writer.toString(), expectedSource);
   }
 }
-
-@reflectiveTest
-class VariableDeclarationTest extends ParserTestCase {
-  void test_getDocumentationComment_onGrandParent() {
-    VariableDeclaration varDecl = AstFactory.variableDeclaration("a");
-    TopLevelVariableDeclaration decl =
-        AstFactory.topLevelVariableDeclaration2(Keyword.VAR, [varDecl]);
-    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
-    expect(varDecl.documentationComment, isNull);
-    decl.documentationComment = comment;
-    expect(varDecl.documentationComment, isNotNull);
-    expect(decl.documentationComment, isNotNull);
-  }
-
-  void test_getDocumentationComment_onNode() {
-    VariableDeclaration decl = AstFactory.variableDeclaration("a");
-    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
-    decl.documentationComment = comment;
-    expect(decl.documentationComment, isNotNull);
-  }
-}
-
-class WrapperKind extends Enum<WrapperKind> {
-  static const WrapperKind PREFIXED_LEFT =
-      const WrapperKind('PREFIXED_LEFT', 0);
-
-  static const WrapperKind PREFIXED_RIGHT =
-      const WrapperKind('PREFIXED_RIGHT', 1);
-
-  static const WrapperKind PROPERTY_LEFT =
-      const WrapperKind('PROPERTY_LEFT', 2);
-
-  static const WrapperKind PROPERTY_RIGHT =
-      const WrapperKind('PROPERTY_RIGHT', 3);
-
-  static const WrapperKind NONE = const WrapperKind('NONE', 4);
-
-  static const List<WrapperKind> values = const [
-    PREFIXED_LEFT,
-    PREFIXED_RIGHT,
-    PROPERTY_LEFT,
-    PROPERTY_RIGHT,
-    NONE
-  ];
-
-  const WrapperKind(String name, int ordinal) : super(name, ordinal);
-}
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index bf01506..3f0aa84 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2,13 +2,13 @@
 // 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.element_test;
+library analyzer.test.src.dart.element.element_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/java_core.dart';
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index c401919..1997466 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.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 analyzer.test.generated.test_all;
+library analyzer.test.src.dart.element.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
index f0c4598..ec4f182 100644
--- a/pkg/analyzer/test/src/dart/test_all.dart
+++ b/pkg/analyzer/test/src/dart/test_all.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 analyzer.test.generated.test_all;
+library analyzer.test.src.dart.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index b08e293..bfef108 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -184,6 +184,10 @@
     LIB_HTML,
   ];
 
+  static const List<SdkLibrary> LIBRARIES_NO_ASYNC = const [
+    LIB_CORE,
+  ];
+
   final resource.MemoryResourceProvider provider =
       new resource.MemoryResourceProvider();
 
@@ -192,8 +196,9 @@
    */
   InternalAnalysisContext _analysisContext;
 
-  MockSdk() {
-    LIBRARIES.forEach((_MockSdkLibrary library) {
+  MockSdk({bool dartAsync: true}) {
+    List<SdkLibrary> libraries = dartAsync ? LIBRARIES : LIBRARIES_NO_ASYNC;
+    libraries.forEach((_MockSdkLibrary library) {
       provider.newFile(library.path, library.content);
     });
   }
@@ -204,12 +209,6 @@
       _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
-      ChangeSet changeSet = new ChangeSet();
-      for (String uri in uris) {
-        Source source = factory.forUri(uri);
-        changeSet.addedSource(source);
-      }
-      _analysisContext.applyChanges(changeSet);
     }
     return _analysisContext;
   }
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
index e7b7804..7ceed57 100644
--- a/pkg/analyzer/test/src/summary/flat_buffers_test.dart
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -97,6 +97,7 @@
       builder.addInt32(2, 20);
       builder.addOffset(3, stringOffset);
       builder.addInt32(4, 40);
+      builder.addUint32(5, 0x9ABCDEF0);
       Offset offset = builder.endTable();
       byteList = builder.finish(offset);
     }
@@ -107,6 +108,23 @@
     expect(const Int32Reader().vTableGet(object, 2), 20);
     expect(const StringReader().vTableGet(object, 3), '12345');
     expect(const Int32Reader().vTableGet(object, 4), 40);
+    expect(const Uint32Reader().vTableGet(object, 5), 0x9ABCDEF0);
+  }
+
+  void test_writeList_ofFloat64() {
+    List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13];
+    // write
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset offset = builder.writeListFloat64(values);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<double> items = const Float64ListReader().read(root);
+    expect(items, hasLength(5));
+    expect(items, orderedEquals(values));
   }
 
   void test_writeList_ofInt32() {
@@ -195,6 +213,20 @@
     expect(items, contains('12345'));
     expect(items, contains('ABC'));
   }
+
+  void test_writeList_ofUint32() {
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]);
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Uint32Reader()).read(root);
+    expect(items, hasLength(3));
+    expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
+  }
 }
 
 class StringListWrapperImpl {
diff --git a/pkg/analyzer/test/src/summary/name_filter_test.dart b/pkg/analyzer/test/src/summary/name_filter_test.dart
index a3c9ae5..5f5ca4f 100644
--- a/pkg/analyzer/test/src/summary/name_filter_test.dart
+++ b/pkg/analyzer/test/src/summary/name_filter_test.dart
@@ -14,28 +14,11 @@
   runReflectiveTests(NameFilterTest);
 }
 
-class MockUnlinkedCombinator implements UnlinkedCombinator {
-  @override
-  final List<String> hides;
-
-  @override
-  final List<String> shows;
-
-  MockUnlinkedCombinator(
-      {this.hides: const <String>[], this.shows: const <String>[]});
-
-  @override
-  Map<String, Object> toMap() {
-    fail('toMap() called unexpectedly');
-    return null;
-  }
-}
-
 @reflectiveTest
 class NameFilterTest {
   test_accepts_accessors_hide() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(hides: ['bar']));
+        new UnlinkedCombinatorBuilder(hides: ['bar']));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('foo='), isTrue);
     expect(filter.accepts('bar'), isFalse);
@@ -44,7 +27,7 @@
 
   test_accepts_accessors_show() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(shows: ['foo']));
+        new UnlinkedCombinatorBuilder(shows: ['foo']));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('foo='), isTrue);
     expect(filter.accepts('bar'), isFalse);
@@ -88,7 +71,7 @@
 
   test_forUnlinkedCombinator_hide() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(hides: ['foo', 'bar']));
+        new UnlinkedCombinatorBuilder(hides: ['foo', 'bar']));
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isTrue);
@@ -99,7 +82,7 @@
 
   test_forUnlinkedCombinator_show() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(shows: ['foo', 'bar']));
+        new UnlinkedCombinatorBuilder(shows: ['foo', 'bar']));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('bar'), isTrue);
     expect(filter.accepts('baz'), isFalse);
@@ -110,8 +93,8 @@
 
   test_forUnlinkedCombinators() {
     NameFilter filter = new NameFilter.forUnlinkedCombinators([
-      new MockUnlinkedCombinator(hides: ['foo']),
-      new MockUnlinkedCombinator(hides: ['bar'])
+      new UnlinkedCombinatorBuilder(hides: ['foo']),
+      new UnlinkedCombinatorBuilder(hides: ['bar'])
     ]);
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
@@ -130,9 +113,9 @@
 
   test_merge_hides_hides() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(hides: ['foo'])).merge(
+        new UnlinkedCombinatorBuilder(hides: ['foo'])).merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(hides: ['bar'])));
+            new UnlinkedCombinatorBuilder(hides: ['bar'])));
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isTrue);
@@ -143,7 +126,7 @@
 
   test_merge_hides_identity() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(hides: ['foo', 'bar']))
+            new UnlinkedCombinatorBuilder(hides: ['foo', 'bar']))
         .merge(NameFilter.identity);
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
@@ -155,9 +138,9 @@
 
   test_merge_hides_shows() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(hides: ['bar', 'baz'])).merge(
+        new UnlinkedCombinatorBuilder(hides: ['bar', 'baz'])).merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+            new UnlinkedCombinatorBuilder(shows: ['foo', 'bar'])));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isFalse);
@@ -169,7 +152,7 @@
   test_merge_identity_hides() {
     NameFilter filter = NameFilter.identity.merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(hides: ['foo', 'bar'])));
+            new UnlinkedCombinatorBuilder(hides: ['foo', 'bar'])));
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isTrue);
@@ -189,7 +172,7 @@
   test_merge_identity_shows() {
     NameFilter filter = NameFilter.identity.merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(shows: ['foo', 'bar'])));
+            new UnlinkedCombinatorBuilder(shows: ['foo', 'bar'])));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('bar'), isTrue);
     expect(filter.accepts('baz'), isFalse);
@@ -200,9 +183,9 @@
 
   test_merge_shows_hides() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new UnlinkedCombinatorBuilder(shows: ['foo', 'bar'])).merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(hides: ['bar', 'baz'])));
+            new UnlinkedCombinatorBuilder(hides: ['bar', 'baz'])));
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isFalse);
@@ -213,7 +196,7 @@
 
   test_merge_shows_identity() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(shows: ['foo', 'bar']))
+            new UnlinkedCombinatorBuilder(shows: ['foo', 'bar']))
         .merge(NameFilter.identity);
     expect(filter.accepts('foo'), isTrue);
     expect(filter.accepts('bar'), isTrue);
@@ -225,9 +208,9 @@
 
   test_merge_shows_shows() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(shows: ['foo', 'bar'])).merge(
+        new UnlinkedCombinatorBuilder(shows: ['foo', 'bar'])).merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(shows: ['bar', 'baz'])));
+            new UnlinkedCombinatorBuilder(shows: ['bar', 'baz'])));
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isTrue);
     expect(filter.accepts('baz'), isFalse);
@@ -238,9 +221,9 @@
 
   test_merge_shows_shows_emptyResult() {
     NameFilter filter = new NameFilter.forUnlinkedCombinator(
-        new MockUnlinkedCombinator(shows: ['foo'])).merge(
+        new UnlinkedCombinatorBuilder(shows: ['foo'])).merge(
         new NameFilter.forUnlinkedCombinator(
-            new MockUnlinkedCombinator(shows: ['bar'])));
+            new UnlinkedCombinatorBuilder(shows: ['bar'])));
     expect(filter.accepts('foo'), isFalse);
     expect(filter.accepts('bar'), isFalse);
     expect(filter.accepts('baz'), isFalse);
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
new file mode 100644
index 0000000..39e43bd
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/prelinker_test.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.summary.prelinker_test;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/prelink.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import 'summarize_elements_test.dart';
+import 'summary_common.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(PrelinkerTest);
+}
+
+/**
+ * Override of [SummaryTest] which verifies the correctness of the prelinker by
+ * creating summaries from the element model, discarding their prelinked
+ * information, and then recreating it using the prelinker.
+ */
+@reflectiveTest
+class PrelinkerTest extends SummarizeElementsTest {
+  final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
+      <String, UnlinkedPublicNamespace>{};
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => false;
+
+  @override
+  bool get skipFullyLinkedData => true;
+
+  @override
+  bool get strongMode => false;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    uriToPublicNamespace[absUri(filePath)] =
+        computePublicNamespaceFromText(contents, source);
+    return source;
+  }
+
+  String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
+    Source resolvedSource =
+        analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
+    if (resolvedSource == null) {
+      fail('Failed to resolve relative uri "$relativeUri"');
+    }
+    return resolvedSource.uri.toString();
+  }
+
+  @override
+  void serializeLibraryElement(LibraryElement library) {
+    super.serializeLibraryElement(library);
+    Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
+    expect(unlinkedUnits.length, unitUris.length);
+    for (int i = 1; i < unlinkedUnits.length; i++) {
+      uriToUnit[unitUris[i]] = unlinkedUnits[i];
+    }
+    UnlinkedUnit getPart(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedUnit unit = uriToUnit[absoluteUri];
+      if (unit == null) {
+        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
+            ' (resolves to "$absoluteUri").');
+      }
+      return unit;
+    }
+    UnlinkedPublicNamespace getImport(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
+      UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
+      if (namespace == null) {
+        namespace = uriToPublicNamespace[absoluteUri];
+      }
+      if (namespace == null && !allowMissingFiles) {
+        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
+            ' (resolves to "$absoluteUri").'
+            '  Namespaces available: ${uriToPublicNamespace.keys}');
+      }
+      return namespace;
+    }
+    linked = new LinkedLibrary.fromBuffer(
+        prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart b/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart
new file mode 100644
index 0000000..b6a9258
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/resynthesize_strong_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.summary.resynthesize_strong_test;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import 'resynthesize_test.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ResynthStrongTest);
+}
+
+@reflectiveTest
+class ResynthStrongTest extends ResynthTest {
+  @override
+  AnalysisOptionsImpl get options => super.options..strongMode = true;
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index c27b507..c4692fc 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -4,9 +4,14 @@
 
 library test.src.serialization.elements_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/element_handle.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart' show Namespace;
+import 'package:analyzer/src/generated/resolver.dart'
+    show Namespace, TypeProvider;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
@@ -25,6 +30,12 @@
 class ResynthTest extends ResolverTestCase {
   Set<Source> otherLibrarySources = new Set<Source>();
 
+  /**
+   * Determine the analysis options that should be used for this test.
+   */
+  AnalysisOptionsImpl get options =>
+      new AnalysisOptionsImpl()..enableGenericMethods = true;
+
   void addLibrary(String uri) {
     otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri));
   }
@@ -33,13 +44,12 @@
     otherLibrarySources.add(addNamedSource(filePath, contents));
   }
 
-  void checkLibrary(String text,
-      {bool allowErrors: false, int resynthesisCount: 1}) {
+  void checkLibrary(String text, {bool allowErrors: false}) {
     Source source = addSource(text);
     LibraryElementImpl original = resolve2(source);
-    LibraryElementImpl resynthesized = resynthesizeLibrary(
-        source, original, allowErrors,
-        resynthesisCount: resynthesisCount);
+    LibraryElementImpl resynthesized = resynthesizeLibraryElement(
+        encodeLibrary(original, allowErrors: allowErrors),
+        source.uri.toString());
     checkLibraryElements(original, resynthesized);
   }
 
@@ -67,6 +77,10 @@
           'export ${original.exports[i].uri}');
     }
     expect(resynthesized.nameLength, original.nameLength);
+    compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
+        '(public namespace)');
+    compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
+        '(export namespace)');
     if (original.entryPoint == null) {
       expect(resynthesized.entryPoint, isNull);
     } else {
@@ -74,10 +88,14 @@
       compareFunctionElements(
           resynthesized.entryPoint, original.entryPoint, '(entry point)');
     }
-    compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
-        '(public namespace)');
-    compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
-        '(export namespace)');
+    // The libraries `dart:core` and `dart:async` cannot create their
+    // `loadLibrary` functions until after both are created.
+    if (original.name != 'dart.core' && original.name != 'dart.async') {
+      compareExecutableElements(
+          resynthesized.loadLibraryFunction as ExecutableElementImpl,
+          original.loadLibraryFunction as ExecutableElementImpl,
+          '(loadLibraryFunction)');
+    }
     // TODO(paulberry): test metadata.
   }
 
@@ -88,8 +106,8 @@
         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');
+      compareFieldElements(
+          resynthesized.fields[i], original.fields[i], '$desc.field $name');
     }
     compareTypes(
         resynthesized.supertype, original.supertype, '$desc supertype');
@@ -120,18 +138,10 @@
     }
     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 setter ${original.accessors[i].name}');
-      } else {
-        comparePropertyAccessorElements(
-            resynthesized.getGetter(name),
-            original.accessors[i],
-            '$desc getter ${original.accessors[i].name}');
-      }
+      comparePropertyAccessorElements(
+          resynthesized.accessors[i],
+          original.accessors[i],
+          '$desc accessor ${original.accessors[i].name}');
     }
     expect(resynthesized.methods.length, original.methods.length);
     for (int i = 0; i < resynthesized.methods.length; i++) {
@@ -197,8 +207,7 @@
     // TODO(paulberry): test redirectedConstructor and constantInitializers
   }
 
-  void compareElements(
-      ElementImpl resynthesized, ElementImpl original, String desc) {
+  void compareElements(Element resynthesized, Element original, String desc) {
     expect(resynthesized, isNotNull);
     expect(resynthesized.kind, original.kind);
     expect(resynthesized.location, original.location, reason: desc);
@@ -207,20 +216,20 @@
     expect(resynthesized.documentationComment, original.documentationComment,
         reason: desc);
     expect(resynthesized.docRange, original.docRange, reason: desc);
+    // Modifiers are a pain to test via handles.  So just test them via the
+    // actual element.
+    ElementImpl actualResynthesized = getActualElement(resynthesized, desc);
+    ElementImpl actualOriginal = getActualElement(original, desc);
     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);
+      bool got = actualResynthesized.hasModifier(modifier);
+      bool want = actualOriginal.hasModifier(modifier);
       expect(got, want,
           reason: 'Mismatch in $desc.$modifier: got $got, want $want');
     }
   }
 
-  void compareExecutableElements(ExecutableElementImpl resynthesized,
-      ExecutableElementImpl original, String desc) {
+  void compareExecutableElements(ExecutableElement resynthesized,
+      ExecutableElement original, String desc) {
     compareElements(resynthesized, original, desc);
     expect(resynthesized.parameters.length, original.parameters.length);
     for (int i = 0; i < resynthesized.parameters.length; i++) {
@@ -252,8 +261,8 @@
     // TODO(paulberry): test evaluationResult
   }
 
-  void compareFunctionElements(FunctionElementImpl resynthesized,
-      FunctionElementImpl original, String desc) {
+  void compareFunctionElements(
+      FunctionElement resynthesized, FunctionElement original, String desc) {
     compareExecutableElements(resynthesized, original, desc);
   }
 
@@ -286,6 +295,7 @@
     compareUriReferencedElements(resynthesized, original, desc);
     expect(resynthesized.importedLibrary.location,
         original.importedLibrary.location);
+    expect(resynthesized.prefixOffset, original.prefixOffset);
     if (original.prefix == null) {
       expect(resynthesized.prefix, isNull);
     } else {
@@ -347,6 +357,20 @@
           '$desc parameter ${original.parameters[i].name}');
     }
     expect(resynthesized.parameterKind, original.parameterKind);
+    expect(resynthesized.isInitializingFormal, original.isInitializingFormal,
+        reason: desc);
+    expect(resynthesized is FieldFormalParameterElementImpl,
+        original is FieldFormalParameterElementImpl);
+    if (resynthesized is FieldFormalParameterElementImpl &&
+        original is FieldFormalParameterElementImpl) {
+      if (original.field == null) {
+        expect(resynthesized.field, isNull, reason: '$desc field');
+      } else {
+        expect(resynthesized.field, isNotNull, reason: '$desc field');
+        compareFieldElements(
+            resynthesized.field, original.field, '$desc field');
+      }
+    }
   }
 
   void comparePrefixElements(PrefixElementImpl resynthesized,
@@ -371,6 +395,7 @@
       PropertyInducingElementImpl original,
       String desc) {
     compareVariableElements(resynthesized, original, desc);
+    compareTypes(resynthesized.propagatedType, original.propagatedType, desc);
     if (original.getter == null) {
       expect(resynthesized.getter, isNull);
     } else {
@@ -487,75 +512,106 @@
     // TODO(paulberry): test initializer
   }
 
-  fail_library_hasExtUri() {
-    checkLibrary('import "dart-ext:doesNotExist.dart";');
-  }
-
-  LibraryElementImpl resynthesizeLibrary(
-      Source source, LibraryElementImpl original, bool allowErrors,
-      {int resynthesisCount: 1}) {
+  /**
+   * Serialize the given [library] into a summary.  Then create a
+   * [_TestSummaryResynthesizer] which can deserialize it, along with any
+   * references it makes to `dart:core`.
+   *
+   * Errors will lead to a test failure unless [allowErrors] is `true`.
+   */
+  _TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library,
+      {bool allowErrors: false}) {
     if (!allowErrors) {
-      assertNoErrors(source);
+      assertNoErrors(library.source);
     }
-    String uri = source.uri.toString();
     addLibrary('dart:core');
-    return resynthesizeLibraryElement(uri, original,
-        resynthesisCount: resynthesisCount);
+    return encodeLibraryElement(library);
   }
 
-  LibraryElementImpl resynthesizeLibraryElement(
-      String uri, LibraryElementImpl original,
-      {int resynthesisCount: 1}) {
+  /**
+   * Convert the library element [library] into a summary, and then create a
+   * [_TestSummaryResynthesizer] which can deserialize it.
+   *
+   * Caller is responsible for checking the library for errors, and adding any
+   * dependent libraries using [addLibrary].
+   */
+  _TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library) {
     Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
-    PrelinkedLibrary getPrelinkedSummaryFor(LibraryElement lib) {
-      LibrarySerializationResult serialized =
-          serializeLibrary(lib, typeProvider);
+    LinkedLibrary getLinkedSummaryFor(LibraryElement lib) {
+      LibrarySerializationResult serialized = serializeLibrary(
+          lib, typeProvider, analysisContext.analysisOptions.strongMode);
       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());
+      return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
     }
-    Map<String, PrelinkedLibrary> prelinkedSummaries =
-        <String, PrelinkedLibrary>{uri: getPrelinkedSummaryFor(original)};
+    Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
+      library.source.uri.toString(): getLinkedSummaryFor(library)
+    };
     for (Source source in otherLibrarySources) {
       LibraryElement original = resolve2(source);
       String uri = source.uri.toString();
-      prelinkedSummaries[uri] = getPrelinkedSummaryFor(original);
+      linkedSummaries[uri] = getLinkedSummaryFor(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(
+    return new _TestSummaryResynthesizer(
+        null,
         analysisContext,
         analysisContext.typeProvider,
-        getPrelinkedSummary,
-        getUnlinkedSummary,
-        analysisContext.sourceFactory);
+        analysisContext.sourceFactory,
+        unlinkedSummaries,
+        linkedSummaries,
+        options.strongMode);
+  }
+
+  fail_library_hasExtUri() {
+    checkLibrary('import "dart-ext:doesNotExist.dart";');
+  }
+
+  ElementImpl getActualElement(Element element, String desc) {
+    if (element is ElementHandle) {
+      return element.actualElement;
+    } else if (element is ElementImpl) {
+      return element;
+    } else {
+      fail('Unexpected type for resynthesized ($desc):'
+          ' ${element.runtimeType}');
+      return null;
+    }
+  }
+
+  /**
+   * Resynthesize the library element associated with [uri] using
+   * [resynthesizer], and verify that it only had to consult one summary in
+   * order to do so.
+   */
+  LibraryElementImpl resynthesizeLibraryElement(
+      _TestSummaryResynthesizer resynthesizer, String uri) {
     LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
     // Check that no other summaries needed to be resynthesized to resynthesize
     // the library element.
-    // TODO(paulberry): once export namespaces are resynthesized from
-    // prelinked data, resynthesisCount should be hardcoded to 1.
-    expect(resynthesizer.resynthesisCount, resynthesisCount);
+    expect(resynthesizer.resynthesisCount, 1);
     return resynthesized;
   }
 
+  @override
+  void setUp() {
+    super.setUp();
+    resetWithOptions(options);
+  }
+
+  test_class_abstract() {
+    checkLibrary('abstract class C {}');
+  }
+
   test_class_alias() {
     checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
   }
 
+  test_class_alias_abstract() {
+    checkLibrary('abstract class C = D with E; class D {} class E {}');
+  }
+
   test_class_alias_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -662,8 +718,18 @@
     checkLibrary('class C { dynamic x; C(this.x); }');
   }
 
+  test_class_constructor_field_formal_multiple_matching_fields() {
+    // This is a compile-time error but it should still analyze consistently.
+    checkLibrary('class C { C(this.x); int x; String x; }', allowErrors: true);
+  }
+
+  test_class_constructor_field_formal_no_matching_field() {
+    // This is a compile-time error but it should still analyze consistently.
+    checkLibrary('class C { C(this.x); }', allowErrors: true);
+  }
+
   test_class_constructor_field_formal_typed_dynamic() {
-    checkLibrary('class C { num x; C(dynamic this.x); }');
+    checkLibrary('class C { num x; C(dynamic this.x); }', allowErrors: true);
   }
 
   test_class_constructor_field_formal_typed_typed() {
@@ -742,6 +808,10 @@
     checkLibrary('class C { int i; int j; }');
   }
 
+  test_class_getter_abstract() {
+    checkLibrary('abstract class C { int get x; }');
+  }
+
   test_class_getter_external() {
     checkLibrary('class C { external int get x; }');
   }
@@ -770,6 +840,10 @@
     checkLibrary('class C implements D, E {} class D {} class E {}');
   }
 
+  test_class_method_abstract() {
+    checkLibrary('abstract class C { f(); }');
+  }
+
   test_class_method_external() {
     checkLibrary('class C { external f(); }');
   }
@@ -790,6 +864,10 @@
     checkLibrary('class C extends Object with D, E {} class D {} class E {}');
   }
 
+  test_class_setter_abstract() {
+    checkLibrary('abstract class C { void set x(int value); }');
+  }
+
   test_class_setter_external() {
     checkLibrary('class C { external void set x(int value); }');
   }
@@ -849,7 +927,7 @@
     LibraryElementImpl original =
         resolve2(analysisContext2.sourceFactory.forUri(uri));
     LibraryElementImpl resynthesized =
-        resynthesizeLibraryElement(uri, original);
+        resynthesizeLibraryElement(encodeLibraryElement(original), uri);
     checkLibraryElements(original, resynthesized);
   }
 
@@ -880,28 +958,71 @@
     checkLibrary('enum E1 { v1 } enum E2 { v2 }');
   }
 
+  test_export_class() {
+    addLibrarySource('/a.dart', 'class C {}');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_class_type_alias() {
+    addLibrarySource(
+        '/a.dart', 'class C {} exends _D with _E; class _D {} class _E {}');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_function() {
+    addLibrarySource('/a.dart', 'f() {}');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_getter() {
+    addLibrarySource('/a.dart', 'get f() => null;');
+    checkLibrary('export "a.dart";');
+  }
+
   test_export_hide() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" hide Stream, Future;',
-        resynthesisCount: 2);
+    checkLibrary('export "dart:async" hide Stream, Future;');
   }
 
   test_export_multiple_combinators() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" hide Stream show Future;',
-        resynthesisCount: 2);
+    checkLibrary('export "dart:async" hide Stream show Future;');
+  }
+
+  test_export_setter() {
+    addLibrarySource('/a.dart', 'void set f(value) {}');
+    checkLibrary('export "a.dart";');
   }
 
   test_export_show() {
     addLibrary('dart:async');
-    checkLibrary('export "dart:async" show Future, Stream;',
-        resynthesisCount: 2);
+    checkLibrary('export "dart:async" show Future, Stream;');
+  }
+
+  test_export_typedef() {
+    addLibrarySource('/a.dart', 'typedef F();');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_variable() {
+    addLibrarySource('/a.dart', 'var x;');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_variable_const() {
+    addLibrarySource('/a.dart', 'const x = 0;');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_export_variable_final() {
+    addLibrarySource('/a.dart', 'final x = 0;');
+    checkLibrary('export "a.dart";');
   }
 
   test_exports() {
     addLibrarySource('/a.dart', 'library a;');
     addLibrarySource('/b.dart', 'library b;');
-    checkLibrary('export "a.dart"; export "b.dart";', resynthesisCount: 3);
+    checkLibrary('export "a.dart"; export "b.dart";');
   }
 
   test_field_documented() {
@@ -914,6 +1035,68 @@
 }''');
   }
 
+  test_field_formal_param_inferred_type_implicit() {
+    checkLibrary('class C extends D { var v; C(this.v); }'
+        ' abstract class D { int get v; }');
+  }
+
+  test_field_inferred_type_nonstatic_explicit_initialized() {
+    checkLibrary('class C { num v = 0; }');
+  }
+
+  test_field_inferred_type_nonstatic_implicit_initialized() {
+    checkLibrary('class C { var v = 0; }');
+  }
+
+  test_field_inferred_type_nonstatic_implicit_uninitialized() {
+    checkLibrary(
+        'class C extends D { var v; } abstract class D { int get v; }');
+  }
+
+  test_field_inferred_type_static_implicit_initialized() {
+    checkLibrary('class C { static var v = 0; }');
+  }
+
+  test_field_propagatedType_const_noDep() {
+    checkLibrary('''
+class C {
+  static const x = 0;
+}''');
+  }
+
+  test_field_propagatedType_final_dep_inLib() {
+    addNamedSource('/a.dart', 'final a = 1;');
+    checkLibrary('''
+import "a.dart";
+class C {
+  final b = a / 2;
+}''');
+  }
+
+  test_field_propagatedType_final_dep_inPart() {
+    addNamedSource('/a.dart', 'part of lib; final a = 1;');
+    checkLibrary('''
+library lib;
+part "a.dart";
+class C {
+  final b = a / 2;
+}''');
+  }
+
+  test_field_propagatedType_final_noDep_instance() {
+    checkLibrary('''
+class C {
+  final x = 0;
+}''');
+  }
+
+  test_field_propagatedType_final_noDep_static() {
+    checkLibrary('''
+class C {
+  static final x = 0;
+}''');
+  }
+
   test_function_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -929,12 +1112,12 @@
 
   test_function_entry_point_in_export() {
     addLibrarySource('/a.dart', 'library a; main() {}');
-    checkLibrary('export "a.dart";', resynthesisCount: 2);
+    checkLibrary('export "a.dart";');
   }
 
   test_function_entry_point_in_export_hidden() {
     addLibrarySource('/a.dart', 'library a; main() {}');
-    checkLibrary('export "a.dart" hide main;', resynthesisCount: 2);
+    checkLibrary('export "a.dart" hide main;');
   }
 
   test_function_entry_point_in_part() {
@@ -1006,6 +1189,69 @@
     checkLibrary('f() {} g() {}');
   }
 
+  test_getElement_constructor_named() {
+    ConstructorElement original = resolve2(addSource('class C { C.named(); }'))
+        .getType('C')
+        .getNamedConstructor('named');
+    expect(original, isNotNull);
+    ConstructorElement resynthesized = validateGetElement(original);
+    compareConstructorElements(resynthesized, original, 'C.constructor named');
+  }
+
+  test_getElement_constructor_unnamed() {
+    ConstructorElement original =
+        resolve2(addSource('class C { C(); }')).getType('C').unnamedConstructor;
+    expect(original, isNotNull);
+    ConstructorElement resynthesized = validateGetElement(original);
+    compareConstructorElements(resynthesized, original, 'C.constructor');
+  }
+
+  test_getElement_field() {
+    FieldElement original =
+        resolve2(addSource('class C { var f; }')).getType('C').getField('f');
+    expect(original, isNotNull);
+    FieldElement resynthesized = validateGetElement(original);
+    compareFieldElements(resynthesized, original, 'C.field f');
+  }
+
+  test_getElement_getter() {
+    PropertyAccessorElement original =
+        resolve2(addSource('class C { get f => null; }'))
+            .getType('C')
+            .getGetter('f');
+    expect(original, isNotNull);
+    PropertyAccessorElement resynthesized = validateGetElement(original);
+    comparePropertyAccessorElements(resynthesized, original, 'C.getter f');
+  }
+
+  test_getElement_method() {
+    MethodElement original =
+        resolve2(addSource('class C { f() {} }')).getType('C').getMethod('f');
+    expect(original, isNotNull);
+    MethodElement resynthesized = validateGetElement(original);
+    compareMethodElements(resynthesized, original, 'C.method f');
+  }
+
+  test_getElement_operator() {
+    MethodElement original =
+        resolve2(addSource('class C { operator+(x) => null; }'))
+            .getType('C')
+            .getMethod('+');
+    expect(original, isNotNull);
+    MethodElement resynthesized = validateGetElement(original);
+    compareMethodElements(resynthesized, original, 'C.operator+');
+  }
+
+  test_getElement_setter() {
+    PropertyAccessorElement original =
+        resolve2(addSource('class C { void set f(value) {} }'))
+            .getType('C')
+            .getSetter('f');
+    expect(original, isNotNull);
+    PropertyAccessorElement resynthesized = validateGetElement(original);
+    comparePropertyAccessorElements(resynthesized, original, 'C.setter f');
+  }
+
   test_getter_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -1019,6 +1265,11 @@
     checkLibrary('external int get x;');
   }
 
+  test_getter_inferred_type_nonstatic_implicit_return() {
+    checkLibrary(
+        'class C extends D { get f => null; } abstract class D { int get f; }');
+  }
+
   test_getters() {
     checkLibrary('int get x => null; get y => null;');
   }
@@ -1031,6 +1282,11 @@
     checkLibrary('void set x(int value) {} int get x => 0;');
   }
 
+  test_import_deferred() {
+    addLibrarySource('/a.dart', 'f() {}');
+    checkLibrary('import "a.dart" deferred as p; main() { p.f(); }');
+  }
+
   test_import_hide() {
     addLibrary('dart:async');
     checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
@@ -1057,6 +1313,26 @@
     checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
   }
 
+  test_inferred_type_is_typedef() {
+    checkLibrary('typedef int F(String s);'
+        ' class C extends D { var v; }'
+        ' abstract class D { F get v; }');
+  }
+
+  test_inferred_type_refers_to_bound_type_param() {
+    checkLibrary('class C<T> extends D<int, T> { var v; }'
+        ' abstract class D<U, V> { Map<V, U> get v; }');
+  }
+
+  test_inferred_type_via_function_typed_param() {
+    if (options.strongMode) {
+      // TODO(paulberry): get this test to pass.
+      return;
+    }
+    checkLibrary('class C extends D { f(g) {} }'
+        ' abstract class D { void f(int g(String)); }');
+  }
+
   test_library() {
     checkLibrary('');
   }
@@ -1078,6 +1354,51 @@
     checkLibrary('library foo.bar;');
   }
 
+  test_main_class() {
+    checkLibrary('class main {}');
+  }
+
+  test_main_class_alias() {
+    checkLibrary('class main = C with D; class C {} class D {}');
+  }
+
+  test_main_class_alias_via_export() {
+    addLibrarySource('/a.dart', 'class main = C with D; class C {} class D {}');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_main_class_via_export() {
+    addLibrarySource('/a.dart', 'class main {}');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_main_getter() {
+    checkLibrary('get main => null;');
+  }
+
+  test_main_getter_via_export() {
+    addLibrarySource('/a.dart', 'get main => null;');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_main_typedef() {
+    checkLibrary('typedef main();');
+  }
+
+  test_main_typedef_via_export() {
+    addLibrarySource('/a.dart', 'typedef main();');
+    checkLibrary('export "a.dart";');
+  }
+
+  test_main_variable() {
+    checkLibrary('var main;');
+  }
+
+  test_main_variable_via_export() {
+    addLibrarySource('/a.dart', 'var main;');
+    checkLibrary('export "a.dart";');
+  }
+
   test_method_documented() {
     checkLibrary('''
 class C {
@@ -1088,6 +1409,16 @@
 }''');
   }
 
+  test_method_inferred_type_nonstatic_implicit_param() {
+    checkLibrary('class C extends D { void f(value) {} }'
+        ' abstract class D { void f(int value); }');
+  }
+
+  test_method_inferred_type_nonstatic_implicit_return() {
+    checkLibrary(
+        'class C extends D { f() => null; } abstract class D { int f(); }');
+  }
+
   test_method_parameter_parameters() {
     checkLibrary('class C { f(g(x, y)) {} }');
   }
@@ -1124,7 +1455,7 @@
   }
 
   test_operator_equal() {
-    checkLibrary('class C { bool operator==(C other) => false; }');
+    checkLibrary('class C { bool operator==(Object other) => false; }');
   }
 
   test_operator_external() {
@@ -1166,11 +1497,36 @@
     checkLibrary('external void set x(int value);');
   }
 
+  test_setter_inferred_type_nonstatic_implicit_param() {
+    checkLibrary('class C extends D { void set f(value) {} }'
+        ' abstract class D { void set f(int value); }');
+  }
+
+  test_setter_inferred_type_static_implicit_return() {
+    checkLibrary('class C { static set f(int value) {} }');
+  }
+
+  test_setter_inferred_type_top_level_implicit_return() {
+    checkLibrary('set f(int value) {}');
+  }
+
   test_setters() {
     checkLibrary('void set x(int value) {} set y(value) {}');
   }
 
-  test_type_arguments_explicit() {
+  test_type_arguments_explicit_dynamic_dynamic() {
+    checkLibrary('Map<dynamic, dynamic> m;');
+  }
+
+  test_type_arguments_explicit_dynamic_int() {
+    checkLibrary('Map<dynamic, int> m;');
+  }
+
+  test_type_arguments_explicit_String_dynamic() {
+    checkLibrary('Map<String, dynamic> m;');
+  }
+
+  test_type_arguments_explicit_String_int() {
     checkLibrary('Map<String, int> m;');
   }
 
@@ -1386,11 +1742,120 @@
 var x;''');
   }
 
+  test_variable_final() {
+    checkLibrary('final int x = 0;');
+  }
+
+  test_variable_getterInLib_setterInPart() {
+    addNamedSource('/a.dart', 'part of my.lib; void set x(int _) {}');
+    checkLibrary('library my.lib; part "a.dart"; int get x => 42;');
+  }
+
+  test_variable_getterInPart_setterInLib() {
+    addNamedSource('/a.dart', 'part of my.lib; int get x => 42;');
+    checkLibrary('library my.lib; part "a.dart"; void set x(int _) {}');
+  }
+
+  test_variable_getterInPart_setterInPart() {
+    addNamedSource('/a.dart', 'part of my.lib; int get x => 42;');
+    addNamedSource('/b.dart', 'part of my.lib; void set x(int _) {}');
+    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+  }
+
   test_variable_implicit_type() {
     checkLibrary('var x;');
   }
 
+  test_variable_inferred_type_implicit_initialized() {
+    checkLibrary('var v = 0;');
+  }
+
+  test_variable_propagatedType_const_noDep() {
+    checkLibrary('const i = 0;');
+  }
+
+  test_variable_propagatedType_final_dep_inLib() {
+    addNamedSource('/a.dart', 'final a = 1;');
+    checkLibrary('import "a.dart"; final b = a / 2;');
+  }
+
+  test_variable_propagatedType_final_dep_inPart() {
+    addNamedSource('/a.dart', 'part of lib; final a = 1;');
+    checkLibrary('library lib; part "a.dart"; final b = a / 2;');
+  }
+
+  test_variable_propagatedType_final_noDep() {
+    checkLibrary('final i = 0;');
+  }
+
+  test_variable_propagatedType_implicit_dep() {
+    // The propagated type is defined in a library that is not imported.
+    addNamedSource('/a.dart', 'class C {}');
+    addNamedSource('/b.dart', 'import "a.dart"; C f() => null;');
+    checkLibrary('import "b.dart"; final x = f();');
+  }
+
+  test_variable_setterInPart_getterInPart() {
+    addNamedSource('/a.dart', 'part of my.lib; void set x(int _) {}');
+    addNamedSource('/b.dart', 'part of my.lib; int get x => 42;');
+    checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
+  }
+
   test_variables() {
     checkLibrary('int i; int j;');
   }
+
+  /**
+   * Encode the library containing [original] into a summary and then use
+   * [_TestSummaryResynthesizer.getElement] to retrieve just the original
+   * element from the resynthesized summary.
+   */
+  Element validateGetElement(Element original) {
+    _TestSummaryResynthesizer resynthesizer = encodeLibrary(original.library);
+    ElementLocationImpl location = original.location;
+    Element result = resynthesizer.getElement(location);
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 1);
+    expect(result.location, location);
+    return result;
+  }
+}
+
+class _TestSummaryResynthesizer extends SummaryResynthesizer {
+  final Map<String, UnlinkedUnit> unlinkedSummaries;
+  final Map<String, LinkedLibrary> linkedSummaries;
+
+  _TestSummaryResynthesizer(
+      SummaryResynthesizer parent,
+      AnalysisContext context,
+      TypeProvider typeProvider,
+      SourceFactory sourceFactory,
+      this.unlinkedSummaries,
+      this.linkedSummaries,
+      bool strongMode)
+      : super(parent, context, typeProvider, sourceFactory, strongMode);
+
+  @override
+  LinkedLibrary getLinkedSummary(String uri) {
+    LinkedLibrary serializedLibrary = linkedSummaries[uri];
+    if (serializedLibrary == null) {
+      fail('Unexpectedly tried to get linked summary for $uri');
+    }
+    return serializedLibrary;
+  }
+
+  @override
+  UnlinkedUnit getUnlinkedSummary(String uri) {
+    UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
+    if (serializedUnit == null) {
+      fail('Unexpectedly tried to get unlinked summary for $uri');
+    }
+    return serializedUnit;
+  }
+
+  @override
+  bool hasLibrarySummary(String uri) {
+    return true;
+  }
 }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
new file mode 100644
index 0000000..aa7dff0
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.summary.summarize_ast_test;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/summary/summarize_ast.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import 'summary_common.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(UnlinkedSummarizeAstTest);
+}
+
+/**
+ * Override of [SummaryTest] which creates unlinked summaries directly from the
+ * AST.
+ */
+@reflectiveTest
+class UnlinkedSummarizeAstTest extends Object with SummaryTest {
+  @override
+  LinkedLibrary linked;
+
+  @override
+  List<UnlinkedUnit> unlinkedUnits;
+
+  /**
+   * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
+   * passed to [addNamedSource].
+   */
+  Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
+
+  @override
+  bool get checkAstDerivedData => true;
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => false;
+
+  @override
+  bool get skipFullyLinkedData => true;
+
+  @override
+  bool get strongMode => false;
+
+  @override
+  addNamedSource(String filePath, String contents) {
+    CompilationUnit unit = _parseText(contents);
+    UnlinkedUnit unlinkedUnit =
+        new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer());
+    uriToUnit[absUri(filePath)] = unlinkedUnit;
+  }
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    Uri testDartUri = Uri.parse(absUri('/test.dart'));
+    String resolveToAbsoluteUri(String relativeUri) =>
+        testDartUri.resolve(relativeUri).toString();
+    CompilationUnit unit = _parseText(text);
+    UnlinkedUnit definingUnit =
+        new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer());
+    UnlinkedUnit getPart(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(relativeUri);
+      UnlinkedUnit unit = uriToUnit[absoluteUri];
+      if (unit == null && !allowMissingFiles) {
+        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
+            ' (resolves to "$absoluteUri").');
+      }
+      return unit;
+    }
+    UnlinkedPublicNamespace getImport(String relativeUri) {
+      String absoluteUri = resolveToAbsoluteUri(relativeUri);
+      UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
+      if (namespace == null) {
+        namespace = uriToUnit[absoluteUri]?.publicNamespace;
+      }
+      if (namespace == null && !allowMissingFiles) {
+        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
+            ' (resolves to "$absoluteUri").'
+            '  Namespaces available: ${uriToUnit.keys}');
+      }
+      return namespace;
+    }
+    linked = new LinkedLibrary.fromBuffer(
+        prelink(definingUnit, getPart, getImport).toBuffer());
+    unlinkedUnits = <UnlinkedUnit>[definingUnit];
+    for (String relativeUri in definingUnit.publicNamespace.parts) {
+      UnlinkedUnit unit = uriToUnit[resolveToAbsoluteUri(relativeUri)];
+      if (unit == null) {
+        if (!allowMissingFiles) {
+          fail('Test referred to unknown unit $relativeUri');
+        }
+      } else {
+        unlinkedUnits.add(unit);
+      }
+    }
+  }
+
+  CompilationUnit _parseText(String text) {
+    CharSequenceReader reader = new CharSequenceReader(text);
+    Scanner scanner =
+        new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
+    Token token = scanner.tokenize();
+    Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
+    parser.parseGenericMethods = true;
+    return parser.parseCompilationUnit(token);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summarize_elements_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_elements_strong_test.dart
new file mode 100644
index 0000000..8a8bfe6
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summarize_elements_strong_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.summary.summarize_elements_strong_test;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import 'summarize_elements_test.dart';
+import 'summary_common.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarizeElementsStrongTest);
+}
+
+/**
+ * Override of [SummaryTest] which creates summaries from the element model
+ * using strong mode.
+ */
+@reflectiveTest
+class SummarizeElementsStrongTest extends SummarizeElementsTest {
+  @override
+  AnalysisOptionsImpl get options => super.options..strongMode = true;
+
+  @override
+  bool get strongMode => true;
+}
diff --git a/pkg/analyzer/test/src/summary/summarize_elements_test.dart b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
new file mode 100644
index 0000000..7b679b9
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summarize_elements_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.summary.summarize_elements_test;
+
+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/source_io.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/public_namespace_computer.dart'
+    as public_namespace;
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    as summarize_elements;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+import '../../reflective_tests.dart';
+import 'summary_common.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(SummarizeElementsTest);
+}
+
+/**
+ * Override of [SummaryTest] which creates summaries from the element model.
+ */
+@reflectiveTest
+class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
+  /**
+   * The list of absolute unit URIs corresponding to the compilation units in
+   * [unlinkedUnits].
+   */
+  List<String> unitUris;
+
+  /**
+   * Map containing all source files in this test, and their corresponding file
+   * contents.
+   */
+  final Map<Source, String> _fileContents = <Source, String>{};
+
+  @override
+  LinkedLibrary linked;
+
+  @override
+  List<UnlinkedUnit> unlinkedUnits;
+
+  @override
+  bool get checkAstDerivedData => false;
+
+  @override
+  bool get expectAbsoluteUrisInDependencies => true;
+
+  /**
+   * Determine the analysis options that should be used for this test.
+   */
+  AnalysisOptionsImpl get options =>
+      new AnalysisOptionsImpl()..enableGenericMethods = true;
+
+  @override
+  bool get skipFullyLinkedData => false;
+
+  @override
+  bool get strongMode => false;
+
+  @override
+  Source addNamedSource(String filePath, String contents) {
+    Source source = super.addNamedSource(filePath, contents);
+    _fileContents[source] = contents;
+    return source;
+  }
+
+  /**
+   * Serialize the library containing the given class [element], then
+   * deserialize it and return the summary of the class.
+   */
+  UnlinkedClass serializeClassElement(ClassElement element) {
+    serializeLibraryElement(element.library);
+    return findClass(element.name, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given [library] element, then deserialize it and store the
+   * resulting summary in [linked] and [unlinkedUnits].
+   */
+  void serializeLibraryElement(LibraryElement library) {
+    summarize_elements.LibrarySerializationResult serializedLib =
+        summarize_elements.serializeLibrary(
+            library, typeProvider, analysisContext.analysisOptions.strongMode);
+    {
+      List<int> buffer = serializedLib.linked.toBuffer();
+      linked = new LinkedLibrary.fromBuffer(buffer);
+    }
+    unlinkedUnits = serializedLib.unlinkedUnits.map((UnlinkedUnitBuilder b) {
+      List<int> buffer = b.toBuffer();
+      return new UnlinkedUnit.fromBuffer(buffer);
+    }).toList();
+    unitUris = serializedLib.unitUris;
+  }
+
+  @override
+  void serializeLibraryText(String text, {bool allowErrors: false}) {
+    Source source = addSource(text);
+    _fileContents[source] = text;
+    LibraryElement library = resolve2(source);
+    if (!allowErrors) {
+      assertNoErrors(source);
+    }
+    serializeLibraryElement(library);
+    expect(unlinkedUnits[0].imports.length, linked.importDependencies.length);
+    expect(linked.units.length, unlinkedUnits.length);
+    for (int i = 0; i < linked.units.length; i++) {
+      expect(unlinkedUnits[i].references.length,
+          lessThanOrEqualTo(linked.units[i].references.length));
+    }
+    verifyPublicNamespace();
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    resetWithOptions(options);
+  }
+
+  test_class_no_superclass() {
+    UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
+    expect(cls.supertype, isNull);
+    expect(cls.hasNoSupertype, isTrue);
+  }
+
+  /**
+   * Verify that [public_namespace.computePublicNamespace] produces data that's
+   * equivalent to that produced by [summarize_elements.serializeLibrary].
+   */
+  void verifyPublicNamespace() {
+    for (int i = 0; i < unlinkedUnits.length; i++) {
+      Source source = analysisContext.sourceFactory.forUri(unitUris[i]);
+      String text = _fileContents[source];
+      if (text == null) {
+        if (!allowMissingFiles) {
+          fail('Could not find file while verifying public namespace: '
+              '${unitUris[i]}');
+        }
+      } else {
+        UnlinkedPublicNamespace namespace =
+            computePublicNamespaceFromText(text, source);
+        expect(canonicalize(namespace),
+            canonicalize(unlinkedUnits[i].publicNamespace),
+            reason: 'publicNamespace(${unitUris[i]})');
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
new file mode 100644
index 0000000..2122771
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -0,0 +1,5002 @@
+// 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.test.src.summary.summary_common;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.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_engine_io.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/summary/base.dart';
+import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/public_namespace_computer.dart'
+    as public_namespace;
+import 'package:analyzer/src/summary/summarize_elements.dart'
+    as summarize_elements;
+import 'package:unittest/unittest.dart';
+
+import '../../generated/resolver_test.dart';
+
+/**
+ * The public namespaces of the sdk are computed once so that we don't bog
+ * down the test.  Structured as a map from absolute URI to the corresponding
+ * public namespace.
+ *
+ * Note: should an exception occur during computation of this variable, it
+ * will silently be set to null to allow other tests to run.
+ */
+final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () {
+  try {
+    AnalysisContext analysisContext = AnalysisContextFactory.contextWithCore();
+    Map<String, UnlinkedPublicNamespace> uriToNamespace =
+        <String, UnlinkedPublicNamespace>{};
+    List<LibraryElement> libraries = [
+      analysisContext.typeProvider.objectType.element.library,
+      analysisContext.typeProvider.futureType.element.library
+    ];
+    for (LibraryElement library in libraries) {
+      summarize_elements.LibrarySerializationResult serializedLibrary =
+          summarize_elements.serializeLibrary(
+              library, analysisContext.typeProvider, false);
+      for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) {
+        uriToNamespace[serializedLibrary.unitUris[i]] =
+            new UnlinkedUnit.fromBuffer(
+                    serializedLibrary.unlinkedUnits[i].toBuffer())
+                .publicNamespace;
+      }
+    }
+    return uriToNamespace;
+  } catch (_) {
+    return null;
+  }
+}();
+
+/**
+ * Convert a summary object (or a portion of one) into a canonical form that
+ * can be easily compared using [expect].  If [orderByName] is true, and the
+ * object is a [List], it is sorted by the `name` field of its elements.
+ */
+Object canonicalize(Object obj, {bool orderByName: false}) {
+  if (obj is SummaryClass) {
+    Map<String, Object> result = <String, Object>{};
+    obj.toMap().forEach((String key, Object value) {
+      bool orderByName = false;
+      if (obj is UnlinkedPublicNamespace && key == 'names') {
+        orderByName = true;
+      }
+      result[key] = canonicalize(value, orderByName: orderByName);
+    });
+    return result;
+  } else if (obj is List) {
+    List<Object> result = <Object>[];
+    for (Object item in obj) {
+      result.add(canonicalize(item));
+    }
+    if (orderByName) {
+      result.sort((Object a, Object b) {
+        if (a is Map && b is Map) {
+          return Comparable.compare(a['name'], b['name']);
+        } else {
+          return 0;
+        }
+      });
+    }
+    return result;
+  } else if (obj is String || obj is num || obj is bool) {
+    return obj;
+  } else {
+    return obj.toString();
+  }
+}
+
+UnlinkedPublicNamespace computePublicNamespaceFromText(
+    String text, Source source) {
+  CharacterReader reader = new CharSequenceReader(text);
+  Scanner scanner =
+      new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
+  Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
+  parser.parseGenericMethods = true;
+  CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
+  UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
+      public_namespace.computePublicNamespace(unit).toBuffer());
+  return namespace;
+}
+
+/**
+ * Type of a function that validates an [EntityRef].
+ */
+typedef void _EntityRefValidator(EntityRef entityRef);
+
+/**
+ * Base class containing most summary tests.  This allows summary tests to be
+ * re-used to exercise all the different ways in which summaries can be
+ * generated (e.g. direct from the AST, from the element model, from a
+ * "relinking" process, etc.)
+ */
+abstract class SummaryTest {
+  /**
+   * A test will set this to `true` if it contains `import`, `export`, or
+   * `part` declarations that deliberately refer to non-existent files.
+   */
+  bool allowMissingFiles = false;
+
+  /**
+   * `true` if the summary was created directly from the AST (and hence
+   * contains information that is not obtainable from the element model alone).
+   * TODO(paulberry): modify the element model so that it contains all the data
+   * that summaries need, so that this flag is no longer needed.
+   */
+  bool get checkAstDerivedData;
+
+  /**
+   * Get access to the linked defining compilation unit.
+   */
+  LinkedUnit get definingUnit => linked.units[0];
+
+  /**
+   * `true` if the linked portion of the summary is expected to contain
+   * absolute URIs.  This happens because the element model doesn't (yet) store
+   * enough information to recover relative URIs, TODO(paulberry): fix this.
+   */
+  bool get expectAbsoluteUrisInDependencies;
+
+  /**
+   * Get access to the linked summary that results from serializing and
+   * then deserializing the library under test.
+   */
+  LinkedLibrary get linked;
+
+  /**
+   * `true` if the linked portion of the summary only contains prelinked data.
+   * This happens because we don't yet have a full linker; only a prelinker.
+   */
+  bool get skipFullyLinkedData;
+
+  /**
+   * `true` if the linked portion of the summary contains the result of strong
+   * mode analysis.
+   */
+  bool get strongMode;
+
+  /**
+   * Get access to the unlinked compilation unit summaries that result from
+   * serializing and deserializing the library under test.
+   */
+  List<UnlinkedUnit> get unlinkedUnits;
+
+  /**
+   * Convert [path] to a suitably formatted absolute path URI for the current
+   * platform.
+   */
+  String absUri(String path) {
+    return FileUtilities2.createFile(path).toURI().toString();
+  }
+
+  /**
+   * Add the given source file so that it may be referenced by the file under
+   * test.
+   */
+  Source addNamedSource(String filePath, String contents);
+
+  /**
+   * Verify that the [dependency]th element of the dependency table represents
+   * a file reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkDependency(int dependency, String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    expect(dependency, new isInstanceOf<int>());
+    expect(linked.dependencies[dependency].uri, relativeUri);
+  }
+
+  /**
+   * Verify that the given [dependency] lists the given [absoluteUris] or
+   * [relativeUris] as its parts.
+   */
+  void checkDependencyParts(LinkedDependency dependency,
+      List<String> absoluteUris, List<String> relativeUris) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUris = absoluteUris;
+    }
+    expect(dependency.parts, relativeUris);
+  }
+
+  /**
+   * Check that the given [documentationComment] matches the first
+   * Javadoc-style comment found in [text].
+   *
+   * Note that the algorithm for finding the Javadoc-style comment in [text] is
+   * a simple-minded text search; it is easily confused by corner cases such as
+   * strings containing comments, nested comments, etc.
+   */
+  void checkDocumentationComment(
+      UnlinkedDocumentationComment documentationComment, String text) {
+    expect(documentationComment, isNotNull);
+    int commentStart = text.indexOf('/*');
+    expect(commentStart, isNot(-1));
+    int commentEnd = text.indexOf('*/');
+    expect(commentEnd, isNot(-1));
+    commentEnd += 2;
+    String expectedCommentText =
+        text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
+    expect(documentationComment.text, expectedCommentText);
+    expect(documentationComment.offset, commentStart);
+    expect(documentationComment.length, commentEnd - commentStart);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents the type `dynamic`.
+   */
+  void checkDynamicTypeRef(EntityRef typeRef) {
+    checkTypeRef(typeRef, null, null, 'dynamic');
+  }
+
+  /**
+   * Verify that the given [exportName] represents a reference to an entity
+   * declared in a file reachable via [absoluteUri] and [relativeUri], having
+   * name [expectedName].  [expectedKind] is the kind of object referenced.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [exportName] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.
+   */
+  void checkExportName(LinkedExportName exportName, String absoluteUri,
+      String relativeUri, String expectedName, ReferenceKind expectedKind,
+      {int expectedTargetUnit: 0}) {
+    expect(exportName, new isInstanceOf<LinkedExportName>());
+    // Exported names must come from other libraries.
+    expect(exportName.dependency, isNot(0));
+    checkDependency(exportName.dependency, absoluteUri, relativeUri);
+    expect(exportName.name, expectedName);
+    expect(exportName.kind, expectedKind);
+    expect(exportName.unit, expectedTargetUnit);
+  }
+
+  /**
+   * Verify that the dependency table contains an entry for a file reachable
+   * via the given [absoluteUri] and [relativeUri].  If [fullyLinked] is
+   * `true`, then the dependency should be a fully-linked dependency; otherwise
+   * it should be a prelinked dependency.
+   *
+   * The index of the [LinkedDependency] is returned.
+   */
+  int checkHasDependency(String absoluteUri, String relativeUri,
+      {bool fullyLinked: false}) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    List<String> found = <String>[];
+    for (int i = 0; i < linked.dependencies.length; i++) {
+      LinkedDependency dep = linked.dependencies[i];
+      if (dep.uri == relativeUri) {
+        if (fullyLinked) {
+          expect(i, greaterThanOrEqualTo(linked.numPrelinkedDependencies));
+        } else {
+          expect(i, lessThan(linked.numPrelinkedDependencies));
+        }
+        return i;
+      }
+      found.add(dep.uri);
+    }
+    fail('Did not find dependency $relativeUri.  Found: $found');
+    return null;
+  }
+
+  /**
+   * Test an inferred type.  If strong mode is disabled, verify that the given
+   * [slotId] exists and has no associated type.  Otherwise, behave as in
+   * [checkLinkedTypeSlot].
+   */
+  void checkInferredTypeSlot(
+      int slotId, String absoluteUri, String relativeUri, String expectedName,
+      {bool allowTypeParameters: false,
+      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    if (strongMode) {
+      checkLinkedTypeSlot(slotId, absoluteUri, relativeUri, expectedName,
+          allowTypeParameters: allowTypeParameters,
+          expectedKind: expectedKind,
+          expectedTargetUnit: expectedTargetUnit,
+          linkedSourceUnit: linkedSourceUnit,
+          unlinkedSourceUnit: unlinkedSourceUnit,
+          numTypeParameters: numTypeParameters);
+    } else {
+      // A slot id should have been assigned but it should not be associated
+      // with any type.
+      expect(slotId, isNot(0));
+      expect(getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit),
+          isNull);
+    }
+  }
+
+  /**
+   * Verify that the dependency table *does not* contain any entries for a file
+   * reachable via the given [absoluteUri] and [relativeUri].
+   */
+  void checkLacksDependency(String absoluteUri, String relativeUri) {
+    if (expectAbsoluteUrisInDependencies) {
+      // The element model doesn't (yet) store enough information to recover
+      // relative URIs, so we have to use the absolute URI.
+      // TODO(paulberry): fix this.
+      relativeUri = absoluteUri;
+    }
+    for (LinkedDependency dep in linked.dependencies) {
+      if (dep.uri == relativeUri) {
+        fail('Unexpected dependency found: $relativeUri');
+      }
+    }
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type declared
+   * in a file reachable via [absoluteUri] and [relativeUri], having name
+   * [expectedName].  If [allowTypeParameters] is true, allow the type
+   * reference to supply type parameters.  [expectedKind] is the kind of object
+   * referenced.  [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
+   * compilation unit within which the [typeRef] appears; if not specified they
+   * are assumed to refer to the defining compilation unit.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [typeRef] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.  [numTypeParameters] is the
+   * number of type parameters of the thing being referred to.
+   */
+  void checkLinkedTypeRef(EntityRef typeRef, String absoluteUri,
+      String relativeUri, String expectedName,
+      {bool allowTypeParameters: false,
+      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    linkedSourceUnit ??= definingUnit;
+    expect(typeRef, isNotNull,
+        reason: 'No entry in linkedSourceUnit.types matching slotId');
+    expect(typeRef.paramReference, 0);
+    int index = typeRef.reference;
+    if (!allowTypeParameters) {
+      expect(typeRef.typeArguments, isEmpty);
+    }
+    checkTypeRefCommonElements(
+        index,
+        absoluteUri,
+        relativeUri,
+        expectedName,
+        expectedKind,
+        expectedTargetUnit,
+        linkedSourceUnit,
+        unlinkedSourceUnit,
+        numTypeParameters);
+  }
+
+  /**
+   * Verify that the given [slotId] represents a reference to a type declared
+   * in a file reachable via [absoluteUri] and [relativeUri], having name
+   * [expectedName].  If [allowTypeParameters] is true, allow the type
+   * reference to supply type parameters.  [expectedKind] is the kind of object
+   * referenced.  [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
+   * compilation unit within which the [typeRef] appears; if not specified they
+   * are assumed to refer to the defining compilation unit.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [typeRef] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.  [numTypeParameters] is the
+   * number of type parameters of the thing being referred to.
+   */
+  void checkLinkedTypeSlot(
+      int slotId, String absoluteUri, String relativeUri, String expectedName,
+      {bool allowTypeParameters: false,
+      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    // Slot ids should be nonzero, since zero means "no associated slot".
+    expect(slotId, isNot(0));
+    if (skipFullyLinkedData) {
+      return;
+    }
+    linkedSourceUnit ??= definingUnit;
+    checkLinkedTypeRef(
+        getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit),
+        absoluteUri,
+        relativeUri,
+        expectedName,
+        allowTypeParameters: allowTypeParameters,
+        expectedKind: expectedKind,
+        expectedTargetUnit: expectedTargetUnit,
+        linkedSourceUnit: linkedSourceUnit,
+        unlinkedSourceUnit: unlinkedSourceUnit,
+        numTypeParameters: numTypeParameters);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to a type parameter
+   * having the given [deBruijnIndex].
+   */
+  void checkParamTypeRef(EntityRef typeRef, int deBruijnIndex) {
+    expect(typeRef, new isInstanceOf<EntityRef>());
+    expect(typeRef.reference, 0);
+    expect(typeRef.typeArguments, isEmpty);
+    expect(typeRef.paramReference, deBruijnIndex);
+  }
+
+  /**
+   * 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, ReferenceKind.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.  [linkedSourceUnit] and [unlinkedSourceUnit] refer
+   * to the compilation unit within which the [typeRef] appears; if not
+   * specified they are assumed to refer to the defining compilation unit.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [typeRef] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.  [numTypeParameters] is the
+   * number of type parameters of the thing being referred to.
+   */
+  void checkTypeRef(EntityRef typeRef, String absoluteUri, String relativeUri,
+      String expectedName,
+      {String expectedPrefix,
+      List<_PrefixExpectation> prefixExpectations,
+      bool allowTypeParameters: false,
+      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    linkedSourceUnit ??= definingUnit;
+    expect(typeRef, new isInstanceOf<EntityRef>());
+    expect(typeRef.paramReference, 0);
+    int index = typeRef.reference;
+    if (!allowTypeParameters) {
+      expect(typeRef.typeArguments, isEmpty);
+    }
+    UnlinkedReference reference = checkTypeRefCommonElements(
+        index,
+        absoluteUri,
+        relativeUri,
+        expectedName,
+        expectedKind,
+        expectedTargetUnit,
+        linkedSourceUnit,
+        unlinkedSourceUnit,
+        numTypeParameters);
+    expect(reference, isNotNull,
+        reason: 'Unlinked type refs must refer to an explicit reference');
+    if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
+      // summarize_elements.dart isn't yet able to record the prefix of
+      // unresolved references.  TODO(paulberry): fix this.
+      expect(reference.prefixReference, 0);
+    } else if (expectedPrefix != null) {
+      checkPrefix(reference.prefixReference, expectedPrefix);
+    } else if (prefixExpectations != null) {
+      for (_PrefixExpectation expectation in prefixExpectations) {
+        expect(reference.prefixReference, isNot(0));
+        reference = checkTypeRefCommonElements(
+            reference.prefixReference,
+            expectation.inLibraryDefiningUnit
+                ? null
+                : expectation.absoluteUri ?? absoluteUri,
+            expectation.inLibraryDefiningUnit
+                ? null
+                : expectation.relativeUri ?? relativeUri,
+            expectation.name,
+            expectation.kind,
+            expectedTargetUnit,
+            linkedSourceUnit,
+            unlinkedSourceUnit,
+            expectation.numTypeParameters);
+      }
+      expect(reference.prefixReference, 0);
+    } else {
+      expect(reference.prefixReference, 0);
+    }
+  }
+
+  /**
+   * Check the data structures that are common between [checkTypeRef] and
+   * [checkLinkedTypeRef].  If the type reference in question is an explicit
+   * reference, return the [UnlinkedReference] that is used to make the
+   * explicit reference.  If the type reference in question is an implicit
+   * reference, return `null`.
+   */
+  UnlinkedReference checkTypeRefCommonElements(
+      int referenceIndex,
+      String absoluteUri,
+      String relativeUri,
+      String expectedName,
+      ReferenceKind expectedKind,
+      int expectedTargetUnit,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters) {
+    unlinkedSourceUnit ??= unlinkedUnits[0];
+    LinkedReference referenceResolution =
+        linkedSourceUnit.references[referenceIndex];
+    String name;
+    UnlinkedReference reference;
+    if (referenceIndex < unlinkedSourceUnit.references.length) {
+      // This is an explicit reference, so its name and prefix should be in
+      // [UnlinkedUnit.references].
+      expect(referenceResolution.name, isEmpty);
+      reference = unlinkedSourceUnit.references[referenceIndex];
+      name = reference.name;
+      if (reference.prefixReference != 0) {
+        // Prefixes should appear in the references table before any reference
+        // that uses them.
+        expect(reference.prefixReference, lessThan(referenceIndex));
+      }
+    } else {
+      // This is an implicit reference, so its name should be in
+      // [LinkedUnit.references].
+      name = referenceResolution.name;
+    }
+    // Index 0 is reserved.
+    expect(referenceIndex, isNot(0));
+    if (absoluteUri == null) {
+      expect(referenceResolution.dependency, 0);
+    } else {
+      checkDependency(referenceResolution.dependency, absoluteUri, relativeUri);
+    }
+    if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
+      // summarize_elements.dart isn't yet able to record the name of
+      // unresolved references.  TODO(paulberry): fix this.
+      expect(name, '*unresolved*');
+    } else {
+      if (expectedName == null) {
+        expect(name, isEmpty);
+      } else {
+        expect(name, expectedName);
+      }
+    }
+    expect(referenceResolution.kind, expectedKind);
+    expect(referenceResolution.unit, expectedTargetUnit);
+    expect(referenceResolution.numTypeParameters, numTypeParameters);
+    return reference;
+  }
+
+  /**
+   * Verify that the given [typeRef] represents a reference to an unresolved
+   * type.
+   */
+  void checkUnresolvedTypeRef(
+      EntityRef typeRef, String expectedPrefix, String expectedName,
+      {LinkedUnit linkedSourceUnit, UnlinkedUnit unlinkedSourceUnit}) {
+    // When serializing from the element model, unresolved type refs lose their
+    // name.
+    checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null,
+        expectedPrefix: expectedPrefix,
+        expectedKind: ReferenceKind.unresolved,
+        linkedSourceUnit: linkedSourceUnit,
+        unlinkedSourceUnit: unlinkedSourceUnit);
+  }
+
+  /**
+   * Verify that the given [typeRef] represents the type `void`.
+   */
+  void checkVoidTypeRef(EntityRef typeRef) {
+    checkTypeRef(typeRef, null, null, 'void');
+  }
+
+  fail_enum_value_documented() {
+    // TODO(paulberry): currently broken because of dartbug.com/25385
+    String text = '''
+enum E {
+  /**
+   * Docs
+   */
+  v
+}''';
+    UnlinkedEnumValue value = serializeEnumText(text).values[0];
+    expect(value.documentationComment, isNotNull);
+    checkDocumentationComment(value.documentationComment, text);
+  }
+
+  /**
+   * Find the class with the given [className] in the summary, and return its
+   * [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, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedClass result;
+    for (UnlinkedClass cls in unit.classes) {
+      if (cls.name == className) {
+        if (result != null) {
+          fail('Duplicate class $className');
+        }
+        result = cls;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Class $className not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the enum with the given [enumName] in the summary, and return its
+   * [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, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedEnum result;
+    for (UnlinkedEnum e in unit.enums) {
+      if (e.name == enumName) {
+        if (result != null) {
+          fail('Duplicate enum $enumName');
+        }
+        result = e;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Enum $enumName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the executable with the given [executableName] in the summary, and
+   * 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,
+      {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
+    executables ??= unlinkedUnits[0].executables;
+    UnlinkedExecutable result;
+    for (UnlinkedExecutable executable in executables) {
+      if (executable.name == executableName) {
+        if (result != null) {
+          fail('Duplicate executable $executableName');
+        }
+        result = executable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Executable $executableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the typedef with the given [typedefName] in the summary, and return
+   * 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, UnlinkedUnit unit}) {
+    unit ??= unlinkedUnits[0];
+    UnlinkedTypedef result;
+    for (UnlinkedTypedef type in unit.typedefs) {
+      if (type.name == typedefName) {
+        if (result != null) {
+          fail('Duplicate typedef $typedefName');
+        }
+        result = type;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Typedef $typedefName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the top level variable with the given [variableName] in the summary,
+   * 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,
+      {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
+    variables ??= unlinkedUnits[0].variables;
+    UnlinkedVariable result;
+    for (UnlinkedVariable variable in variables) {
+      if (variable.name == variableName) {
+        if (result != null) {
+          fail('Duplicate variable $variableName');
+        }
+        result = variable;
+      }
+    }
+    if (result == null && failIfAbsent) {
+      fail('Variable $variableName not found in serialized output');
+    }
+    return result;
+  }
+
+  /**
+   * Find the entry in [linkedSourceUnit.types] matching [slotId].
+   */
+  EntityRef getTypeRefForSlot(int slotId, {LinkedUnit linkedSourceUnit}) {
+    linkedSourceUnit ??= definingUnit;
+    for (EntityRef typeRef in linkedSourceUnit.types) {
+      if (typeRef.slot == slotId) {
+        return typeRef;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the class
+   * with the given [className].
+   */
+  UnlinkedClass serializeClassText(String text,
+      {String className: 'C', bool allowErrors: false}) {
+    serializeLibraryText(text, allowErrors: allowErrors);
+    return findClass(className, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the enum with
+   * the given [enumName].
+   */
+  UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
+    serializeLibraryText(text);
+    return findEnum(enumName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the
+   * executable with the given [executableName].
+   */
+  UnlinkedExecutable serializeExecutableText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText(text);
+    return findExecutable(executableName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text], then deserialize it and store its
+   * summary in [lib].
+   */
+  void serializeLibraryText(String text, {bool allowErrors: false});
+
+  /**
+   * Serialize the given method [text] and return the summary of the executable
+   * with the given [executableName].
+   */
+  UnlinkedExecutable serializeMethodText(String text,
+      [String executableName = 'f']) {
+    serializeLibraryText('class C { $text }');
+    return findExecutable(executableName,
+        executables: findClass('C', failIfAbsent: true).executables,
+        failIfAbsent: true);
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the typedef
+   * with the given [typedefName].
+   */
+  UnlinkedTypedef serializeTypedefText(String text,
+      [String typedefName = 'F']) {
+    serializeLibraryText(text);
+    return findTypedef(typedefName, failIfAbsent: true);
+  }
+
+  /**
+   * Serialize a type declaration using the given [text] as a type name, and
+   * return a summary of the corresponding [EntityRef].  If the type
+   * declaration needs to refer to types that are not available in core, those
+   * types may be declared in [otherDeclarations].
+   */
+  EntityRef serializeTypeText(String text,
+      {String otherDeclarations: '', bool allowErrors: false}) {
+    return serializeVariableText('$otherDeclarations\n$text v;',
+            allowErrors: allowErrors)
+        .type;
+  }
+
+  /**
+   * Serialize the given library [text] and return the summary of the variable
+   * with the given [variableName].
+   */
+  UnlinkedVariable serializeVariableText(String text,
+      {String variableName: 'v', bool allowErrors: false}) {
+    serializeLibraryText(text, allowErrors: allowErrors);
+    return findVariable(variableName, failIfAbsent: true);
+  }
+
+  test_cascaded_export_hide_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_hide_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_hide() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_export_show_show() {
+    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
+    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib1.dart';
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(
+        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_hide_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' hide C show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_hide() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B hide B, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_cascaded_import_show_show() {
+    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
+    serializeLibraryText(
+        '''
+import 'lib.dart' show A, B show A, C;
+A a;
+B b;
+C c;
+    ''',
+        allowErrors: true);
+    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
+    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
+    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
+  }
+
+  test_class_abstract() {
+    UnlinkedClass cls = serializeClassText('abstract class C {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_abstract() {
+    UnlinkedClass cls = serializeClassText(
+        'abstract class C = D with E; class D {} class E {}');
+    expect(cls.isAbstract, true);
+  }
+
+  test_class_alias_concrete() {
+    UnlinkedClass cls =
+        serializeClassText('class C = _D with _E; class _D {} class _E {}');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_alias_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C = D with E;
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_alias_flag() {
+    UnlinkedClass cls =
+        serializeClassText('class C = D with E; class D {} class E {}');
+    expect(cls.isMixinApplication, true);
+  }
+
+  test_class_alias_generic() {
+    serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
+  }
+
+  test_class_alias_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E, F;
+class D {}
+class E {}
+class F {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'E');
+    checkTypeRef(cls.mixins[1], null, null, 'F');
+  }
+
+  test_class_alias_no_implicit_constructors() {
+    UnlinkedClass cls = serializeClassText('''
+class C = D with E;
+class D {
+  D.foo();
+  D.bar();
+}
+class E {}
+''');
+    expect(cls.executables, isEmpty);
+  }
+
+  test_class_alias_private() {
+    serializeClassText('class _C = _D with _E; class _D {} class _E {}',
+        className: '_C');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_class_alias_reference_generic() {
+    EntityRef typeRef = serializeTypeText('C',
+        otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
+    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+  }
+
+  test_class_alias_reference_generic_imported() {
+    addNamedSource(
+        '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}');
+    EntityRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
+        numTypeParameters: 2);
+  }
+
+  test_class_alias_supertype() {
+    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() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_class_constMembers() {
+    UnlinkedClass cls = serializeClassText('''
+class C {
+  int fieldInstance = 0;
+  final int fieldInstanceFinal = 0;
+  static int fieldStatic = 0;
+  static final int fieldStaticFinal = 0;
+  static const int fieldStaticConst = 0;
+  static const int _fieldStaticConstPrivate = 0;
+  static void methodStaticPublic() {}
+  static void _methodStaticPrivate() {}
+  void methodInstancePublic() {}
+  C operator+(C c) => null;
+}
+''');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0];
+    expect(className.kind, ReferenceKind.classOrEnum);
+    expect(className.name, 'C');
+    expect(className.numTypeParameters, 0);
+    // executables
+    Map<String, UnlinkedPublicName> executablesMap =
+        <String, UnlinkedPublicName>{};
+    className.constMembers.forEach((e) => executablesMap[e.name] = e);
+    expect(executablesMap, hasLength(2));
+    {
+      UnlinkedPublicName executable = executablesMap['fieldStaticConst'];
+      expect(executable.kind, ReferenceKind.constField);
+      expect(executable.constMembers, isEmpty);
+    }
+    {
+      UnlinkedPublicName executable = executablesMap['methodStaticPublic'];
+      expect(executable.kind, ReferenceKind.staticMethod);
+      expect(executable.constMembers, isEmpty);
+    }
+  }
+
+  test_class_constMembers_constructors() {
+    UnlinkedClass cls = serializeClassText('''
+class C {
+  const C();
+  const C.constructorNamedPublicConst();
+  C.constructorNamedPublic();
+  C._constructorNamedPrivate();
+}
+''');
+    expect(cls.isAbstract, false);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0];
+    expect(className.kind, ReferenceKind.classOrEnum);
+    expect(className.name, 'C');
+    expect(className.numTypeParameters, 0);
+    // executables
+    Map<String, UnlinkedPublicName> executablesMap =
+        <String, UnlinkedPublicName>{};
+    className.constMembers.forEach((e) => executablesMap[e.name] = e);
+    expect(executablesMap, hasLength(2));
+    {
+      UnlinkedPublicName executable = executablesMap[''];
+      expect(executable.kind, ReferenceKind.constructor);
+      expect(executable.constMembers, isEmpty);
+    }
+    {
+      UnlinkedPublicName executable =
+          executablesMap['constructorNamedPublicConst'];
+      expect(executable.kind, ReferenceKind.constructor);
+      expect(executable.constMembers, isEmpty);
+    }
+  }
+
+  test_class_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+class C {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_references() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs referring to [D] and [E]
+ */
+class C {}
+
+class D {}
+class E {}''';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_documented_with_with_windows_line_endings() {
+    String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.documentationComment, isNotNull);
+    checkDocumentationComment(cls.documentationComment, text);
+  }
+
+  test_class_interface() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D {}
+class D {}
+''');
+    expect(cls.interfaces, hasLength(1));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+  }
+
+  test_class_interface_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C implements D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.interfaces, hasLength(2));
+    checkTypeRef(cls.interfaces[0], null, null, 'D');
+    checkTypeRef(cls.interfaces[1], null, null, 'E');
+  }
+
+  test_class_mixin() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D {}
+class D {}
+''');
+    expect(cls.mixins, hasLength(1));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+  }
+
+  test_class_mixin_order() {
+    UnlinkedClass cls = serializeClassText('''
+class C extends Object with D, E {}
+class D {}
+class E {}
+''');
+    expect(cls.mixins, hasLength(2));
+    checkTypeRef(cls.mixins[0], null, null, 'D');
+    checkTypeRef(cls.mixins[1], null, null, 'E');
+  }
+
+  test_class_name() {
+    var classText = 'class C {}';
+    UnlinkedClass cls = serializeClassText(classText);
+    expect(cls.name, 'C');
+    expect(cls.nameOffset, classText.indexOf('C'));
+  }
+
+  test_class_no_flags() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isAbstract, false);
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_no_interface() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.interfaces, isEmpty);
+  }
+
+  test_class_no_mixins() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.mixins, isEmpty);
+  }
+
+  test_class_no_type_param() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.typeParameters, isEmpty);
+  }
+
+  test_class_non_alias_flag() {
+    UnlinkedClass cls = serializeClassText('class C {}');
+    expect(cls.isMixinApplication, false);
+  }
+
+  test_class_private() {
+    serializeClassText('class _C {}', className: '_C');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_class_reference_generic() {
+    EntityRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
+    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+  }
+
+  test_class_reference_generic_imported() {
+    addNamedSource('/lib.dart', 'class C<D, E> {}');
+    EntityRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
+        numTypeParameters: 2);
+  }
+
+  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() {
+    UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].bound, isNotNull);
+    checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+  }
+
+  test_class_type_param_f_bound() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
+    EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_class_type_param_f_bound_self_ref() {
+    UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
+    EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_class_type_param_no_bound() {
+    String text = 'class C<T> {}';
+    UnlinkedClass cls = serializeClassText(text);
+    expect(cls.typeParameters, hasLength(1));
+    expect(cls.typeParameters[0].name, 'T');
+    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
+    expect(cls.typeParameters[0].bound, isNull);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_constExpr_binary_add() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_and() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = true && false;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushTrue,
+      UnlinkedConstOperation.pushFalse,
+      UnlinkedConstOperation.and
+    ]);
+  }
+
+  test_constExpr_binary_bitAnd() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 & 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.bitAnd
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_bitOr() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 | 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.bitOr
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_bitShiftLeft() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 << 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.bitShiftLeft
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_bitShiftRight() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 >> 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.bitShiftRight
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_bitXor() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 ^ 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.bitXor
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_divide() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 / 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.divide
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_equal() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 == 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.equal
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_equal_not() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 != 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.equal,
+      UnlinkedConstOperation.not
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_floorDivide() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 ~/ 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.floorDivide
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_greater() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 > 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.greater
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_greaterEqual() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 >= 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.greaterEqual
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_less() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 < 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.less
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_lessEqual() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 <= 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.lessEqual
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_modulo() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 % 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.modulo
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_multiply() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 * 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.multiply
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_binary_or() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = false || true;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushFalse,
+      UnlinkedConstOperation.pushTrue,
+      UnlinkedConstOperation.or
+    ]);
+  }
+
+  test_constExpr_binary_subtract() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.subtract
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_conditional() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = true ? 1 : 2;', allowErrors: true);
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushTrue,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.conditional
+    ], ints: [
+      1,
+      2
+    ]);
+  }
+
+  test_constExpr_identical() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = identical(42, null);');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushNull,
+      UnlinkedConstOperation.identical
+    ], ints: [
+      42
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_named() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  const C.named();
+}
+const v = const C.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'named',
+              expectedKind: ReferenceKind.constructor,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_named_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  const C.named();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = const C.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'named',
+              expectedKind: ReferenceKind.constructor,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_named_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  const C.named();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = const p.C.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'named',
+              expectedKind: ReferenceKind.constructor,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true)
+              ])
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_unnamed() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  const C(a, b, c, d, {e, f, g});
+}
+const v = const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66);
+''');
+    // Stack: 11 22 3.3 '444' 55 '777' 66 ^head
+    // Ints: ^pointer 3 4
+    // Doubles: ^pointer
+    // Strings: ^pointer 'e' 'g' 'f' ''
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushDouble,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      11,
+      22,
+      55,
+      66,
+      3,
+      4,
+    ], doubles: [
+      3.3
+    ], strings: [
+      '444',
+      '777',
+      'e',
+      'g',
+      'f'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_unnamed_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  const C();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = const C();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_unnamed_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  const C();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = const p.C();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
+              expectedKind: ReferenceKind.classOrEnum,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true)
+              ])
+    ]);
+  }
+
+  test_constExpr_length_classConstField() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  static const int length = 0;
+}
+const int v = C.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'length',
+              expectedKind: ReferenceKind.constField,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_length_classConstField_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static const int length = 0;
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const int v = p.C.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'length',
+              expectedKind: ReferenceKind.constField,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                    absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true)
+              ])
+    ]);
+  }
+
+  test_constExpr_length_identifierTarget() {
+    UnlinkedVariable variable = serializeVariableText('''
+const String a = 'aaa';
+const int v = a.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'length',
+              expectedKind: ReferenceKind.length,
+              prefixExpectations: [
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a')
+              ])
+    ]);
+  }
+
+  test_constExpr_length_identifierTarget_classConstField() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  static const String F = '';
+}
+const int v = C.F.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'length',
+              expectedKind: ReferenceKind.length,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.constField, 'F'),
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
+              ])
+    ]);
+  }
+
+  test_constExpr_length_identifierTarget_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+const String a = 'aaa';
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const int v = a.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'length',
+              expectedKind: ReferenceKind.length,
+              prefixExpectations: [
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a',
+                    absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart')
+              ])
+    ]);
+  }
+
+  test_constExpr_length_identifierTarget_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+const String a = 'aaa';
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const int v = p.a.length;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'length',
+              expectedKind: ReferenceKind.length,
+              prefixExpectations: [
+                new _PrefixExpectation(
+                    ReferenceKind.topLevelPropertyAccessor, 'a',
+                    absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true)
+              ])
+    ]);
+  }
+
+  test_constExpr_length_parenthesizedBinaryTarget() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = ("abc" + "edf").length;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.add,
+      UnlinkedConstOperation.length
+    ], strings: [
+      'abc',
+      'edf'
+    ]);
+  }
+
+  test_constExpr_length_parenthesizedStringTarget() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = ("abc").length;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.length
+    ], strings: [
+      'abc'
+    ]);
+  }
+
+  test_constExpr_length_stringLiteralTarget() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = "abc".length;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.length
+    ], strings: [
+      'abc'
+    ]);
+  }
+
+  test_constExpr_makeSymbol() {
+    UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.makeSymbol
+    ], strings: [
+      'a.bb.ccc'
+    ]);
+  }
+
+  test_constExpr_makeTypedList() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = const <int>[11, 22, 33];');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.makeTypedList
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_makeTypedList_dynamic() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = const <dynamic>[11, 22, 33];');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.makeTypedList
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ], referenceValidators: [
+      (EntityRef r) => checkDynamicTypeRef(r)
+    ]);
+  }
+
+  test_constExpr_makeTypedMap() {
+    UnlinkedVariable variable = serializeVariableText(
+        'const v = const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.makeTypedMap
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ], strings: [
+      'aaa',
+      'bbb',
+      'ccc'
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int',
+          expectedKind: ReferenceKind.classOrEnum),
+      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_makeTypedMap_dynamic() {
+    UnlinkedVariable variable = serializeVariableText(
+        'const v = const <dynamic, dynamic>{11: "aaa", 22: "bbb", 33: "ccc"};');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.makeTypedMap
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ], strings: [
+      'aaa',
+      'bbb',
+      'ccc'
+    ], referenceValidators: [
+      (EntityRef r) => checkDynamicTypeRef(r),
+      (EntityRef r) => checkDynamicTypeRef(r)
+    ]);
+  }
+
+  test_constExpr_makeUntypedList() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = const [11, 22, 33];');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.makeUntypedList
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ]);
+  }
+
+  test_constExpr_makeUntypedMap() {
+    UnlinkedVariable variable = serializeVariableText(
+        'const v = const {11: "aaa", 22: "bbb", 33: "ccc"};');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.makeUntypedMap
+    ], ints: [
+      11,
+      22,
+      33,
+      3
+    ], strings: [
+      'aaa',
+      'bbb',
+      'ccc'
+    ]);
+  }
+
+  test_constExpr_parenthesized() {
+    UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.add,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.multiply,
+    ], ints: [
+      1,
+      2,
+      3
+    ]);
+  }
+
+  test_constExpr_prefix_complement() {
+    UnlinkedVariable variable = serializeVariableText('const v = ~2;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.complement
+    ], ints: [
+      2
+    ]);
+  }
+
+  test_constExpr_prefix_negate() {
+    UnlinkedVariable variable = serializeVariableText('const v = -(2);');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.negate
+    ], ints: [
+      2
+    ]);
+  }
+
+  test_constExpr_prefix_not() {
+    UnlinkedVariable variable = serializeVariableText('const v = !true;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushTrue,
+      UnlinkedConstOperation.not
+    ]);
+  }
+
+  test_constExpr_pushDouble() {
+    UnlinkedVariable variable = serializeVariableText('const v = 123.4567;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushDouble], doubles: [123.4567]);
+  }
+
+  test_constExpr_pushFalse() {
+    UnlinkedVariable variable = serializeVariableText('const v = false;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushFalse]);
+  }
+
+  test_constExpr_pushInt() {
+    UnlinkedVariable variable = serializeVariableText('const v = 1;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushInt], ints: [1]);
+  }
+
+  test_constExpr_pushInt_max() {
+    UnlinkedVariable variable = serializeVariableText('const v = 0xFFFFFFFF;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushInt,], ints: [0xFFFFFFFF]);
+  }
+
+  test_constExpr_pushInt_negative() {
+    UnlinkedVariable variable = serializeVariableText('const v = -5;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.negate
+    ], ints: [
+      5
+    ]);
+  }
+
+  test_constExpr_pushInt_shiftOr_long() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = 0xA123456789ABCDEF012345678;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.shiftOr,
+      UnlinkedConstOperation.shiftOr,
+      UnlinkedConstOperation.shiftOr
+    ], ints: [
+      0xA,
+      0x12345678,
+      0x9ABCDEF0,
+      0x12345678
+    ]);
+  }
+
+  test_constExpr_pushInt_shiftOr_min() {
+    UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.shiftOr,
+    ], ints: [
+      1,
+      0,
+    ]);
+  }
+
+  test_constExpr_pushInt_shiftOr_min2() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = 0x10000000000000000;');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.shiftOr,
+      UnlinkedConstOperation.shiftOr,
+    ], ints: [
+      1,
+      0,
+      0,
+    ]);
+  }
+
+  test_constExpr_pushNull() {
+    UnlinkedVariable variable = serializeVariableText('const v = null;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushNull]);
+  }
+
+  test_constExpr_pushReference_class() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {}
+const v = C;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_pushReference_enum() {
+    UnlinkedVariable variable = serializeVariableText('''
+enum C {V1, V2, V3}
+const v = C;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'C',
+          expectedKind: ReferenceKind.classOrEnum)
+    ]);
+  }
+
+  test_constExpr_pushReference_field() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  static const int F = 1;
+}
+const v = C.F;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'F',
+              expectedKind: ReferenceKind.constField,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_field_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static const int F = 1;
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = C.F;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'F',
+              expectedKind: ReferenceKind.constField,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_field_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static const int F = 1;
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = p.C.F;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'F',
+              expectedKind: ReferenceKind.constField,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true),
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_staticMethod() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C {
+  static m() {}
+}
+const v = C.m;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'm',
+              expectedKind: ReferenceKind.staticMethod,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_staticMethod_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static m() {}
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = C.m;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'm',
+              expectedKind: ReferenceKind.staticMethod,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_staticMethod_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C {
+  static m() {}
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = p.C.m;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'm',
+              expectedKind: ReferenceKind.staticMethod,
+              prefixExpectations: [
+                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                    inLibraryDefiningUnit: true)
+              ])
+    ]);
+  }
+
+  test_constExpr_pushReference_topLevelVariable() {
+    UnlinkedVariable variable = serializeVariableText('''
+const int a = 1;
+const v = a;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  test_constExpr_pushReference_topLevelVariable_imported() {
+    addNamedSource('/a.dart', 'const int a = 1;');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = a;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor)
+    ]);
+  }
+
+  test_constExpr_pushReference_topLevelVariable_imported_withPrefix() {
+    addNamedSource('/a.dart', 'const int a = 1;');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = p.a;
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushReference
+    ], referenceValidators: [
+      (EntityRef r) {
+        return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+            expectedKind: ReferenceKind.topLevelPropertyAccessor,
+            expectedPrefix: 'p');
+      }
+    ]);
+  }
+
+  test_constExpr_pushString_adjacent() {
+    UnlinkedVariable variable =
+        serializeVariableText('const v = "aaa" "b" "ccc";');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushString], strings: ['aaabccc']);
+  }
+
+  test_constExpr_pushString_adjacent_interpolation() {
+    UnlinkedVariable variable =
+        serializeVariableText(r'const v = "aaa" "bb ${42} bbb" "cccc";');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.concatenate,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.concatenate,
+    ], ints: [
+      42,
+      3,
+      3,
+    ], strings: [
+      'aaa',
+      'bb ',
+      ' bbb',
+      'cccc'
+    ]);
+  }
+
+  test_constExpr_pushString_interpolation() {
+    UnlinkedVariable variable =
+        serializeVariableText(r'const v = "aaa ${42} bbb";');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushString,
+      UnlinkedConstOperation.concatenate
+    ], ints: [
+      42,
+      3
+    ], strings: [
+      'aaa ',
+      ' bbb'
+    ]);
+  }
+
+  test_constExpr_pushString_simple() {
+    UnlinkedVariable variable = serializeVariableText('const v = "abc";');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushString], strings: ['abc']);
+  }
+
+  test_constExpr_pushTrue() {
+    UnlinkedVariable variable = serializeVariableText('const v = true;');
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushTrue]);
+  }
+
+  test_constructor() {
+    String text = 'class C { C(); }';
+    UnlinkedExecutable executable =
+        findExecutable('', executables: serializeClassText(text).executables);
+    expect(executable.kind, UnlinkedExecutableKind.constructor);
+    expect(executable.returnType, isNull);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('C();'));
+  }
+
+  test_constructor_anonymous() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.name, isEmpty);
+  }
+
+  test_constructor_const() {
+    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_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  C();
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_constructor_external() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { external C(); }').executables);
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_constructor_factory() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { factory C() => null; }').executables);
+    expect(executable.isFactory, isTrue);
+  }
+
+  test_constructor_implicit() {
+    // Implicit constructors are not serialized.
+    UnlinkedExecutable executable = findExecutable(null,
+        executables: serializeClassText('class C { C(); }').executables,
+        failIfAbsent: false);
+    expect(executable, isNull);
+  }
+
+  test_constructor_initializing_formal() {
+    UnlinkedExecutable executable = findExecutable('',
+        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('',
+        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('',
+        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('',
+        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() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): this test fails when building the summary from the
+      // element model because the elment model doesn't record whether a
+      // function-typed parameter's return type is implicit.
+      return;
+    }
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(this.x()); Function x; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isTrue);
+    expect(parameter.type, isNull);
+  }
+
+  test_constructor_initializing_formal_function_typed_no_parameters() {
+    UnlinkedExecutable executable = findExecutable('',
+        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_parameter() {
+    UnlinkedExecutable executable = findExecutable('',
+        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_parameter_order() {
+    UnlinkedExecutable executable = findExecutable('',
+        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');
+    expect(parameter.parameters[1].name, 'b');
+  }
+
+  test_constructor_initializing_formal_implicit_type() {
+    // Note: the implicit type of an initializing formal is the type of the
+    // field.
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); int x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.type, isNull);
+  }
+
+  test_constructor_initializing_formal_name() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.name, 'x');
+  }
+
+  test_constructor_initializing_formal_named() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        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('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isFalse);
+  }
+
+  test_constructor_initializing_formal_positional() {
+    // TODO(paulberry): also test default value
+    UnlinkedExecutable executable = findExecutable('',
+        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('',
+        executables:
+            serializeClassText('class C { C(this.x); final x; }').executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.kind, UnlinkedParamKind.required);
+  }
+
+  test_constructor_initializing_formal_typedef() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText(
+                'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }')
+            .executables);
+    UnlinkedParam parameter = executable.parameters[0];
+    expect(parameter.isFunctionTyped, isFalse);
+    expect(parameter.parameters, isEmpty);
+  }
+
+  test_constructor_named() {
+    String text = 'class C { C.foo(); }';
+    UnlinkedExecutable executable = findExecutable('foo',
+        executables: serializeClassText(text).executables);
+    expect(executable.name, 'foo');
+    expect(executable.nameOffset, text.indexOf('foo'));
+  }
+
+  test_constructor_non_const() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.isConst, isFalse);
+  }
+
+  test_constructor_non_factory() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.isFactory, isFalse);
+  }
+
+  test_constructor_param_inferred_type_explicit() {
+    UnlinkedExecutable ctor =
+        serializeClassText('class C { C(int v); }').executables[0];
+    expect(ctor.kind, UnlinkedExecutableKind.constructor);
+    expect(ctor.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_constructor_param_inferred_type_implicit() {
+    UnlinkedExecutable ctor =
+        serializeClassText('class C { C(v); }').executables[0];
+    expect(ctor.kind, UnlinkedExecutableKind.constructor);
+    expect(ctor.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_constructor_return_type() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C { C(); }').executables);
+    expect(executable.returnType, isNull);
+  }
+
+  test_constructor_return_type_parameterized() {
+    UnlinkedExecutable executable = findExecutable('',
+        executables: serializeClassText('class C<T, U> { C(); }').executables);
+    expect(executable.returnType, isNull);
+  }
+
+  test_dependencies_export_to_export_unused() {
+    addNamedSource('/a.dart', 'export "b.dart";');
+    addNamedSource('/b.dart', '');
+    serializeLibraryText('export "a.dart";');
+    // The main test library depends on b.dart, even though it doesn't
+    // re-export any names defined in b.dart, because a change to b.dart might
+    // cause it to start exporting a name that the main test library *does*
+    // use.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_export_unused() {
+    addNamedSource('/a.dart', '');
+    serializeLibraryText('export "a.dart";');
+    // The main test library depends on a.dart, even though it doesn't
+    // re-export any names defined in a.dart, because a change to a.dart might
+    // cause it to start exporting a name that the main test library *will*
+    // re-export.
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+  }
+
+  test_dependencies_import_to_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_export() {
+    addNamedSource('/a/a.dart',
+        'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+  }
+
+  test_dependencies_import_to_export_in_subdirs_absolute_import() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+  }
+
+  test_dependencies_import_to_export_in_subdirs_relative() {
+    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
+    addNamedSource('/a/b/b.dart', 'library b;');
+    serializeLibraryText('import "a/a.dart"; A a;');
+    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+    // The main test library depends on b.dart, because names defined in
+    // b.dart are exported by a.dart.
+    checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
+  }
+
+  test_dependencies_import_to_export_loop() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "a.dart";');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // Serialization should have been able to walk the transitive export
+    // dependencies to b.dart without going into an infinite loop.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_to_export_transitive_closure() {
+    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
+    addNamedSource('/b.dart', 'library b; export "c.dart";');
+    addNamedSource('/c.dart', 'library c;');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library depends on c.dart, because names defined in
+    // c.dart are exported by b.dart and then re-exported by a.dart.
+    checkHasDependency(absUri('/c.dart'), 'c.dart');
+  }
+
+  test_dependencies_import_to_export_unused() {
+    addNamedSource('/a.dart', 'export "b.dart";');
+    addNamedSource('/b.dart', '');
+    serializeLibraryText('import "a.dart";', allowErrors: true);
+    // The main test library depends on b.dart, even though it doesn't use any
+    // names defined in b.dart, because a change to b.dart might cause it to
+    // start exporting a name that the main test library *does* use.
+    checkHasDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_transitive_closure() {
+    addNamedSource(
+        '/a.dart', 'library a; import "b.dart"; class A extends B {}');
+    addNamedSource('/b.dart', 'library b; class B {}');
+    serializeLibraryText('import "a.dart"; A a;');
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+    // The main test library doesn't depend on b.dart, because no change to
+    // b.dart can possibly affect the serialized element model for it.
+    checkLacksDependency(absUri('/b.dart'), 'b.dart');
+  }
+
+  test_dependencies_import_unused() {
+    addNamedSource('/a.dart', '');
+    serializeLibraryText('import "a.dart";', allowErrors: true);
+    // The main test library depends on a.dart, even though it doesn't use any
+    // names defined in a.dart, because a change to a.dart might cause it to
+    // start exporting a name that the main test library *does* use.
+    checkHasDependency(absUri('/a.dart'), 'a.dart');
+  }
+
+  test_dependencies_parts() {
+    addNamedSource(
+        '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a;');
+    serializeLibraryText('import "a.dart"; A a;');
+    int dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
+    checkDependencyParts(linked.dependencies[dep],
+        [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
+  }
+
+  test_dependencies_parts_relative_to_importing_library() {
+    addNamedSource('/a/b.dart', 'export "c/d.dart";');
+    addNamedSource('/a/c/d.dart',
+        'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
+    addNamedSource('/a/c/e/f.dart', 'part of d;');
+    addNamedSource('/a/c/g/h.dart', 'part of d;');
+    serializeLibraryText('import "a/b.dart"; D d;');
+    int dep = checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
+    checkDependencyParts(
+        linked.dependencies[dep],
+        [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
+        ['a/c/e/f.dart', 'a/c/g/h.dart']);
+  }
+
+  test_elements_in_part() {
+    addNamedSource(
+        '/part1.dart',
+        '''
+part of my.lib;
+
+class C {}
+enum E { v }
+var v;
+f() {}
+typedef F();
+''');
+    serializeLibraryText('library my.lib; part "part1.dart";');
+    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() {
+    String text = 'enum E { v1 }';
+    UnlinkedEnum e = serializeEnumText(text);
+    expect(e.name, 'E');
+    expect(e.nameOffset, text.indexOf('E'));
+    expect(e.values, hasLength(1));
+    expect(e.values[0].name, 'v1');
+    expect(e.values[0].nameOffset, text.indexOf('v1'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.classOrEnum);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_enum_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+enum E { v }''';
+    UnlinkedEnum enm = serializeEnumText(text);
+    expect(enm.documentationComment, isNotNull);
+    checkDocumentationComment(enm.documentationComment, text);
+  }
+
+  test_enum_order() {
+    UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
+    expect(e.values, hasLength(2));
+    expect(e.values[0].name, 'v1');
+    expect(e.values[1].name, 'v2');
+  }
+
+  test_enum_private() {
+    serializeEnumText('enum _E { v1 }', '_E');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_abstract() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f(); }').executables[0];
+    expect(executable.isAbstract, isTrue);
+  }
+
+  test_executable_concrete() {
+    UnlinkedExecutable executable =
+        serializeClassText('abstract class C { f() {} }').executables[0];
+    expect(executable.isAbstract, isFalse);
+  }
+
+  test_executable_function() {
+    String text = '  f() {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.returnType, isNull);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.topLevelFunction);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_executable_function_explicit_return() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('dynamic f() => null;');
+    checkDynamicTypeRef(executable.returnType);
+  }
+
+  test_executable_function_external() {
+    UnlinkedExecutable executable = serializeExecutableText('external f();');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_function_private() {
+    serializeExecutableText('_f() {}', '_f');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_getter() {
+    String text = 'int get f => 1;';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(executable.returnType, isNotNull);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f='), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.topLevelPropertyAccessor);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
+  }
+
+  test_executable_getter_external() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('external int get f;');
+    expect(executable.isExternal, isTrue);
+  }
+
+  test_executable_getter_private() {
+    serializeExecutableText('int get _f => 1;', '_f');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_getter_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_getter_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
+    expect(executable.returnType, isNull);
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_member_function() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables: serializeClassText('class C { f() {} }').executables);
+    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
+    expect(executable.returnType, isNull);
+    expect(executable.isExternal, isFalse);
+  }
+
+  test_executable_member_function_explicit_return() {
+    UnlinkedExecutable executable = findExecutable('f',
+        executables:
+            serializeClassText('class C { dynamic f() => null; }').executables);
+    expect(executable.returnType, isNotNull);
+  }
+
+  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', executables: cls.executables, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.getter);
+    expect(executable.returnType, isNotNull);
+    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=', executables: cls.executables, failIfAbsent: true);
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(executable.returnType, isNotNull);
+    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.returnType, isNull);
+  }
+
+  test_executable_name() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.name, 'f');
+  }
+
+  test_executable_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.isAbstract, isFalse);
+    expect(executable.isConst, isFalse);
+    expect(executable.isFactory, isFalse);
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { f() {} }').executables[0];
+    expect(executable.isStatic, isFalse);
+  }
+
+  test_executable_non_static_top_level() {
+    // Top level executables are considered non-static.
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    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.returnType, isNotNull);
+    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==(Object 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.returnType, isNotNull);
+    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.returnType, isNotNull);
+    expect(executable.isAbstract, false);
+    expect(executable.isConst, false);
+    expect(executable.isFactory, false);
+    expect(executable.isStatic, false);
+    expect(executable.parameters, hasLength(2));
+    checkVoidTypeRef(executable.returnType);
+    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() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): this test fails when building the summary from the
+      // element model because the elment model doesn't record whether a
+      // function-typed parameter's return type is implicit.
+      return;
+    }
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].isFunctionTyped, isTrue);
+    expect(executable.parameters[0].type, isNull);
+  }
+
+  test_executable_param_function_typed_explicit_return_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('f(dynamic g()) {}');
+    expect(executable.parameters[0].type, isNotNull);
+  }
+
+  test_executable_param_function_typed_param() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
+    expect(executable.parameters[0].parameters, hasLength(1));
+  }
+
+  test_executable_param_function_typed_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].parameters, isEmpty);
+  }
+
+  test_executable_param_function_typed_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
+    expect(executable.parameters[0].parameters, hasLength(2));
+    expect(executable.parameters[0].parameters[0].name, 'x');
+    expect(executable.parameters[0].parameters[1].name, 'y');
+  }
+
+  test_executable_param_function_typed_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_param_function_typed_return_type_implicit() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): this test fails when building the summary from the
+      // element model because the elment model doesn't record whether a
+      // function-typed parameter's return type is implicit.
+      return;
+    }
+    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
+    expect(executable.parameters[0].isFunctionTyped, isTrue);
+    expect(executable.parameters[0].type, isNull);
+  }
+
+  test_executable_param_function_typed_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
+    checkVoidTypeRef(executable.parameters[0].type);
+  }
+
+  test_executable_param_kind_named() {
+    UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.named);
+  }
+
+  test_executable_param_kind_positional() {
+    UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.positional);
+  }
+
+  test_executable_param_kind_required() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].kind, UnlinkedParamKind.required);
+  }
+
+  test_executable_param_name() {
+    String text = 'f(x) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
+  }
+
+  test_executable_param_no_flags() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+    expect(executable.parameters[0].isInitializingFormal, isFalse);
+  }
+
+  test_executable_param_non_function_typed() {
+    UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+  }
+
+  test_executable_param_none() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.parameters, isEmpty);
+  }
+
+  test_executable_param_order() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
+    expect(executable.parameters, hasLength(2));
+    expect(executable.parameters[0].name, 'x');
+    expect(executable.parameters[1].name, 'y');
+  }
+
+  test_executable_param_type_explicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}');
+    checkDynamicTypeRef(executable.parameters[0].type);
+  }
+
+  test_executable_param_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+    expect(executable.parameters[0].type, isNull);
+  }
+
+  test_executable_return_type() {
+    UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
+    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_return_type_implicit() {
+    UnlinkedExecutable executable = serializeExecutableText('f() {}');
+    expect(executable.returnType, isNull);
+  }
+
+  test_executable_return_type_void() {
+    UnlinkedExecutable executable = serializeExecutableText('void f() {}');
+    checkVoidTypeRef(executable.returnType);
+  }
+
+  test_executable_setter() {
+    String text = 'void set f(value) {}';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    expect(executable.kind, UnlinkedExecutableKind.setter);
+    expect(executable.returnType, isNotNull);
+    expect(executable.isExternal, isFalse);
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(findVariable('f'), isNull);
+    expect(findExecutable('f'), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.topLevelPropertyAccessor);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f=');
+  }
+
+  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=');
+    expect(executable.returnType, isNull);
+  }
+
+  test_executable_setter_private() {
+    serializeExecutableText('void set _f(value) {}', '_f=');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_executable_setter_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('void set f(int value) {}', 'f=');
+    checkVoidTypeRef(executable.returnType);
+    expect(executable.parameters, hasLength(1));
+    expect(executable.parameters[0].name, 'value');
+    checkTypeRef(
+        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_executable_static() {
+    UnlinkedExecutable executable =
+        serializeClassText('class C { static f() {} }').executables[0];
+    expect(executable.isStatic, isTrue);
+  }
+
+  test_executable_type_param_f_bound_function() {
+    UnlinkedExecutable ex =
+        serializeExecutableText('void f<T, U extends List<T>>() {}');
+    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_executable_type_param_f_bound_method() {
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<T>>() {}');
+    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 2);
+  }
+
+  test_executable_type_param_f_bound_self_ref_function() {
+    UnlinkedExecutable ex =
+        serializeExecutableText('void f<T, U extends List<U>>() {}');
+    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_executable_type_param_f_bound_self_ref_method() {
+    UnlinkedExecutable ex =
+        serializeMethodText('void f<T, U extends List<U>>() {}');
+    EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
+    checkParamTypeRef(typeArgument, 1);
+  }
+
+  test_executable_type_param_in_parameter_function() {
+    UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
+    checkParamTypeRef(ex.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_executable_type_param_in_parameter_method() {
+    UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
+    checkParamTypeRef(ex.parameters[0].type, 1);
+  }
+
+  test_executable_type_param_in_return_type_function() {
+    UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;');
+    checkParamTypeRef(ex.returnType, 1);
+  }
+
+  test_executable_type_param_in_return_type_method() {
+    UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
+    checkParamTypeRef(ex.returnType, 1);
+  }
+
+  test_export_class() {
+    addNamedSource('/a.dart', 'class C {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C',
+        ReferenceKind.classOrEnum);
+  }
+
+  test_export_class_alias() {
+    addNamedSource(
+        '/a.dart', 'class C extends _D with _E {} class _D {} class _E {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C',
+        ReferenceKind.classOrEnum);
+  }
+
+  test_export_enum() {
+    addNamedSource('/a.dart', 'enum E { v }');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'E',
+        ReferenceKind.classOrEnum);
+  }
+
+  test_export_from_part() {
+    addNamedSource('/a.dart', 'library foo; part "b.dart";');
+    addNamedSource('/b.dart', 'part of foo; f() {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelFunction,
+        expectedTargetUnit: 1);
+  }
+
+  test_export_function() {
+    addNamedSource('/a.dart', 'f() {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelFunction);
+  }
+
+  test_export_getter() {
+    addNamedSource('/a.dart', 'get f => null');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelPropertyAccessor);
+  }
+
+  test_export_hide() {
+    addNamedSource('/a.dart', 'f() {} g() {}');
+    serializeLibraryText('export "a.dart" hide g;');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelFunction);
+  }
+
+  test_export_hide_order() {
+    serializeLibraryText('export "dart:async" hide Future, Stream;');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
+        isEmpty);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
+        hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0],
+        'Future');
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
+        'Stream');
+    expect(linked.exportNames, isNotEmpty);
+  }
+
+  test_export_names_excludes_names_from_library() {
+    addNamedSource('/a.dart', 'part of my.lib; int y; int _y;');
+    serializeLibraryText('library my.lib; part "a.dart"; int x; int _x;');
+    expect(linked.exportNames, isEmpty);
+  }
+
+  test_export_no_combinators() {
+    serializeLibraryText('export "dart:async";');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
+  }
+
+  test_export_not_shadowed_by_prefix() {
+    addNamedSource('/a.dart', 'f() {}');
+    serializeLibraryText('export "a.dart"; import "dart:core" as f; f.int _x;');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelFunction);
+  }
+
+  test_export_offset() {
+    String libraryText = '    export "dart:async";';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].exports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
+    expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
+  }
+
+  test_export_private() {
+    // Private names should not be exported.
+    addNamedSource('/a.dart', '_f() {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, isEmpty);
+  }
+
+  test_export_setter() {
+    addNamedSource('/a.dart', 'void set f(value) {}');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f=',
+        ReferenceKind.topLevelPropertyAccessor);
+  }
+
+  test_export_shadowed() {
+    // f() is not shown in exportNames because it is already defined at top
+    // level in the library.
+    addNamedSource('/a.dart', 'f() {}');
+    serializeLibraryText('export "a.dart"; f() {}');
+    expect(linked.exportNames, isEmpty);
+  }
+
+  test_export_shadowed_variable() {
+    // Neither `v` nor `v=` is shown in exportNames because both are defined at
+    // top level in the library by the declaration `var v;`.
+    addNamedSource('/a.dart', 'var v;');
+    serializeLibraryText('export "a.dart"; var v;');
+    expect(linked.exportNames, isEmpty);
+  }
+
+  test_export_shadowed_variable_const() {
+    // `v=` is shown in exportNames because the top level declaration
+    // `const v = 0;` only shadows `v`, not `v=`.
+    addNamedSource('/a.dart', 'var v;');
+    serializeLibraryText('export "a.dart"; const v = 0;');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=',
+        ReferenceKind.topLevelPropertyAccessor);
+  }
+
+  test_export_shadowed_variable_final() {
+    // `v=` is shown in exportNames because the top level declaration
+    // `final v = 0;` only shadows `v`, not `v=`.
+    addNamedSource('/a.dart', 'var v;');
+    serializeLibraryText('export "a.dart"; final v = 0;');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=',
+        ReferenceKind.topLevelPropertyAccessor);
+  }
+
+  test_export_show() {
+    addNamedSource('/a.dart', 'f() {} g() {}');
+    serializeLibraryText('export "a.dart" show f;');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
+        ReferenceKind.topLevelFunction);
+  }
+
+  test_export_show_order() {
+    serializeLibraryText('export "dart:async" show Future, Stream;');
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
+        hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
+        isEmpty);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0],
+        'Future');
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
+        'Stream');
+  }
+
+  test_export_typedef() {
+    addNamedSource('/a.dart', 'typedef F();');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(1));
+    checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'F',
+        ReferenceKind.typedef);
+  }
+
+  test_export_uri() {
+    addNamedSource('/a.dart', 'library my.lib;');
+    String uriString = '"a.dart"';
+    String libraryText = 'export $uriString;';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'a.dart');
+  }
+
+  test_export_variable() {
+    addNamedSource('/a.dart', 'var v;');
+    serializeLibraryText('export "a.dart";');
+    expect(linked.exportNames, hasLength(2));
+    LinkedExportName getter =
+        linked.exportNames.firstWhere((e) => e.name == 'v');
+    expect(getter, isNotNull);
+    checkExportName(getter, absUri('/a.dart'), 'a.dart', 'v',
+        ReferenceKind.topLevelPropertyAccessor);
+    LinkedExportName setter =
+        linked.exportNames.firstWhere((e) => e.name == 'v=');
+    expect(setter, isNotNull);
+    checkExportName(setter, absUri('/a.dart'), 'a.dart', 'v=',
+        ReferenceKind.topLevelPropertyAccessor);
+  }
+
+  test_field() {
+    UnlinkedClass cls = serializeClassText('class C { int i; }');
+    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);
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushInt], ints: [0]);
+  }
+
+  test_field_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  var v;
+}''';
+    UnlinkedVariable variable = serializeClassText(text).fields[0];
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
+  test_field_final() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { final int i = 0; }').fields[0];
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_field_formal_param_inferred_type_explicit() {
+    UnlinkedClass cls = serializeClassText(
+        'class C extends D { var v; C(int this.v); }'
+        ' abstract class D { num get v; }',
+        className: 'C');
+    checkInferredTypeSlot(
+        cls.fields[0].inferredTypeSlot, 'dart:core', 'dart:core', 'num');
+    expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor);
+    expect(cls.executables[0].parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_field_formal_param_inferred_type_implicit() {
+    // Both the field `v` and the constructor argument `this.v` will have their
+    // type inferred by strong mode.  But only the field should have its
+    // inferred type stored in the summary, since the standard rules for field
+    // formal parameters will take care of the rest (they implicitly inherit
+    // the type of the associated field).
+    UnlinkedClass cls = serializeClassText(
+        'class C extends D { var v; C(this.v); }'
+        ' abstract class D { int get v; }',
+        className: 'C');
+    checkInferredTypeSlot(
+        cls.fields[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+    expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor);
+    expect(cls.executables[0].parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_field_inferred_type_nonstatic_explicit_initialized() {
+    UnlinkedVariable v = serializeClassText('class C { num v = 0; }').fields[0];
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_field_inferred_type_nonstatic_explicit_uninitialized() {
+    UnlinkedVariable v = serializeClassText(
+            'class C extends D { num v; } abstract class D { int get v; }',
+            className: 'C',
+            allowErrors: true)
+        .fields[0];
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_field_inferred_type_nonstatic_implicit_initialized() {
+    UnlinkedVariable v = serializeClassText('class C { var v = 0; }').fields[0];
+    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_field_inferred_type_nonstatic_implicit_uninitialized() {
+    UnlinkedVariable v = serializeClassText(
+            'class C extends D { var v; } abstract class D { int get v; }',
+            className: 'C')
+        .fields[0];
+    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_field_inferred_type_static_explicit_initialized() {
+    UnlinkedVariable v =
+        serializeClassText('class C { static int v = 0; }').fields[0];
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_field_inferred_type_static_implicit_initialized() {
+    UnlinkedVariable v =
+        serializeClassText('class C { static var v = 0; }').fields[0];
+    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_field_inferred_type_static_implicit_uninitialized() {
+    UnlinkedVariable v =
+        serializeClassText('class C { static var v; }').fields[0];
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_field_propagated_type_final_immediate() {
+    UnlinkedVariable v =
+        serializeClassText('class C { final v = 0; }').fields[0];
+    checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_field_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
+  }
+
+  test_fully_linked_references_follow_other_references() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    serializeLibraryText('final x = 0; String y;');
+    checkLinkedTypeSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot,
+        'dart:core', 'dart:core', 'int');
+    checkTypeRef(
+        unlinkedUnits[0].variables[1].type, 'dart:core', 'dart:core', 'String');
+    // Even though the definition of y follows the definition of x, the linked
+    // type reference for x should use a higher numbered reference than the
+    // unlinked type reference for y.
+    EntityRef propagatedType =
+        getTypeRefForSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot);
+    expect(unlinkedUnits[0].variables[1].type.reference,
+        lessThan(propagatedType.reference));
+  }
+
+  test_function_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+f() {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_function_inferred_type_implicit_param() {
+    UnlinkedExecutable f = serializeExecutableText('void f(value) {}');
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_function_inferred_type_implicit_return() {
+    UnlinkedExecutable f = serializeExecutableText('f() => null;');
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_generic_method_in_generic_class() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
+    List<UnlinkedParam> params = cls.executables[0].parameters;
+    checkParamTypeRef(params[0].type, 4);
+    checkParamTypeRef(params[1].type, 3);
+    checkParamTypeRef(params[2].type, 2);
+    checkParamTypeRef(params[3].type, 1);
+  }
+
+  test_getter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+get f => null;''';
+    UnlinkedExecutable executable = serializeExecutableText(text);
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_getter_inferred_type_nonstatic_explicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { num get f => null; }'
+            ' abstract class D { int get f; }',
+            className: 'C',
+            allowErrors: true)
+        .executables[0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_getter_inferred_type_nonstatic_implicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { get f => null; } abstract class D { int get f; }',
+            className: 'C')
+        .executables[0];
+    checkInferredTypeSlot(
+        f.inferredReturnTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_getter_inferred_type_static_implicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { static get f => null; }'
+            ' class D { static int get f => null; }',
+            className: 'C')
+        .executables[0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_implicit_dependencies_follow_other_dependencies() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    addNamedSource('/a.dart', 'import "b.dart"; class C {} D f() => null;');
+    addNamedSource('/b.dart', 'class D {}');
+    serializeLibraryText('import "a.dart"; final x = f(); C y;');
+    // The dependency on b.dart is implicit, so it should be placed at the end
+    // of the dependency list, after a.dart, even though the code that refers
+    // to b.dart comes before the code that refers to a.dart.
+    int aDep =
+        checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
+    int bDep =
+        checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+    expect(aDep, lessThan(bDep));
+  }
+
+  test_import_deferred() {
+    serializeLibraryText(
+        'import "dart:async" deferred as a; main() { print(a.Future); }');
+    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(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(linked.importDependencies[0], 'dart:async', 'dart:async');
+  }
+
+  test_import_explicit() {
+    serializeLibraryText('import "dart:core"; int i;');
+    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(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));
+    expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
+    expect(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(unlinkedUnits[0].imports, hasLength(1));
+    checkDependency(linked.importDependencies[0], 'dart:core', 'dart:core');
+    expect(unlinkedUnits[0].imports[0].uri, isEmpty);
+    expect(unlinkedUnits[0].imports[0].uriOffset, 0);
+    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
+    expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
+  }
+
+  test_import_missing() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): At the moment unresolved imports are not included in
+      // the element model, so we can't pass this test.
+      return;
+    }
+    // Unresolved imports are included since this is necessary for proper
+    // dependency tracking.
+    allowMissingFiles = true;
+    serializeLibraryText('import "foo.dart";', allowErrors: true);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    checkDependency(
+        linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
+  }
+
+  test_import_no_combinators() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
+  }
+
+  test_import_no_flags() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    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(unlinkedUnits[0].imports[0].isDeferred, isFalse);
+  }
+
+  test_import_of_file_with_missing_part() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // part declaration for bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
+    addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_of_missing_export() {
+    // Other references in foo.dart should be resolved even though foo.dart's
+    // re-export of bar.dart refers to a non-existent file.
+    allowMissingFiles = true;
+    addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
+    serializeLibraryText('import "foo.dart"; C x;');
+    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
+  }
+
+  test_import_offset() {
+    String libraryText = '    import "dart:async"; Future x;';
+    serializeLibraryText(libraryText);
+    expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
+    expect(unlinkedUnits[0].imports[0].uriOffset,
+        libraryText.indexOf('"dart:async"'));
+    expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
+  }
+
+  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(unlinkedUnits[0].imports, hasLength(2));
+    checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
+    expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
+  }
+
+  test_import_prefix_none() {
+    serializeLibraryText('import "dart:async"; Future x;');
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
+  }
+
+  test_import_prefix_not_in_public_namespace() {
+    serializeLibraryText('import "dart:async" as a; a.Future v;');
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v');
+    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v=');
+  }
+
+  test_import_prefix_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async" as a; a.Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a', numTypeParameters: 1);
+  }
+
+  test_import_prefixes_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class b {} class A');
+    addNamedSource('/b.dart', 'class Cls {}');
+    addNamedSource('/c.dart', 'class Cls {}');
+    addNamedSource('/d.dart', 'class c {} class D');
+    serializeLibraryText('''
+import 'a.dart';
+import 'b.dart' as b;
+import 'c.dart' as c;
+import 'd.dart';
+A aCls;
+b.Cls bCls;
+c.Cls cCls;
+D dCls;
+''');
+    checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A');
+    checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls',
+        expectedPrefix: 'b');
+    checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls',
+        expectedPrefix: 'c');
+    checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D');
+  }
+
+  test_import_reference() {
+    UnlinkedVariable variable =
+        serializeVariableText('import "dart:async"; Future v;');
+    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
+        numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_no_prefix() {
+    serializeLibraryText('''
+import "dart:async" show Future;
+import "dart:async" show Stream;
+
+Future f;
+Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
+        numTypeParameters: 1);
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
+        numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_prefixed() {
+    serializeLibraryText('''
+import "dart:async" as a show Future;
+import "dart:async" as a show Stream;
+
+a.Future f;
+a.Stream s;
+''');
+    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
+        expectedPrefix: 'a', numTypeParameters: 1);
+    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
+        expectedPrefix: 'a', numTypeParameters: 1);
+  }
+
+  test_import_reference_merged_prefixed_separate_libraries() {
+    addNamedSource('/a.dart', 'class A {}');
+    addNamedSource('/b.dart', 'class B {}');
+    serializeLibraryText('''
+import 'a.dart' as p;
+import 'b.dart' as p;
+
+p.A a;
+p.B b;
+''');
+    checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A',
+        expectedPrefix: 'p');
+    checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B',
+        expectedPrefix: 'p');
+  }
+
+  test_import_show_order() {
+    String libraryText =
+        'import "dart:async" show Future, Stream; Future x; Stream y;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    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);
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
+    expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
+  }
+
+  test_import_uri() {
+    String uriString = '"dart:async"';
+    String libraryText = 'import $uriString; Future x;';
+    serializeLibraryText(libraryText);
+    // Second import is the implicit import of dart:core
+    expect(unlinkedUnits[0].imports, hasLength(2));
+    expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
+  }
+
+  test_inferred_type_refers_to_bound_type_param() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedClass cls = serializeClassText(
+        'class C<T> extends D<int, T> { var v; }'
+        ' abstract class D<U, V> { Map<V, U> get v; }',
+        className: 'C');
+    EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
+    // Check that v has inferred type Map<T, int>.
+    checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    checkParamTypeRef(type.typeArguments[0], 1);
+    checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_invalid_prefix_dynamic() {
+    if (checkAstDerivedData) {
+      // TODO(paulberry): get this to work properly.
+      return;
+    }
+    checkUnresolvedTypeRef(
+        serializeTypeText('dynamic.T', allowErrors: true), 'dynamic', 'T');
+  }
+
+  test_invalid_prefix_type_parameter() {
+    if (checkAstDerivedData) {
+      // TODO(paulberry): get this to work properly.
+      return;
+    }
+    checkUnresolvedTypeRef(
+        serializeClassText('class C<T> { T.U x; }', allowErrors: true)
+            .fields[0]
+            .type,
+        'T',
+        'U');
+  }
+
+  test_invalid_prefix_void() {
+    if (checkAstDerivedData) {
+      // TODO(paulberry): get this to work properly.
+      return;
+    }
+    checkUnresolvedTypeRef(
+        serializeTypeText('void.T', allowErrors: true), 'void', 'T');
+  }
+
+  test_library_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+library foo;''';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
+    checkDocumentationComment(
+        unlinkedUnits[0].libraryDocumentationComment, text);
+  }
+
+  test_library_name_with_spaces() {
+    String text = 'library foo . bar ;';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
+  }
+
+  test_library_named() {
+    String text = 'library foo.bar;';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].libraryName, 'foo.bar');
+    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
+    expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
+  }
+
+  test_library_unnamed() {
+    serializeLibraryText('');
+    expect(unlinkedUnits[0].libraryName, isEmpty);
+    expect(unlinkedUnits[0].libraryNameOffset, 0);
+    expect(unlinkedUnits[0].libraryNameLength, 0);
+  }
+
+  test_library_with_missing_part() {
+    // References to other parts should still be resolved.
+    allowMissingFiles = true;
+    addNamedSource('/bar.dart', 'part of my.lib; class C {}');
+    serializeLibraryText(
+        'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
+        allowErrors: true);
+    checkTypeRef(findVariable('c').type, null, null, 'C',
+        expectedTargetUnit: 2);
+  }
+
+  test_linked_reference_reuse() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // When the reference for a linked type is the same as an explicitly
+    // referenced type, the explicit reference should be re-used.
+    addNamedSource('/a.dart', 'class C {}');
+    addNamedSource('/b.dart', 'import "a.dart"; C f() => null;');
+    serializeLibraryText(
+        'import "a.dart"; import "b.dart"; C c1; final c2 = f();');
+    int explicitReference = findVariable('c1').type.reference;
+    expect(getTypeRefForSlot(findVariable('c2').propagatedTypeSlot).reference,
+        explicitReference);
+  }
+
+  test_linked_type_dependency_reuse() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // When the dependency for a linked type is the same as an explicit
+    // dependency, the explicit dependency should be re-used.
+    addNamedSource('/a.dart', 'class C {} class D {}');
+    addNamedSource('/b.dart', 'import "a.dart"; D f() => null;');
+    serializeLibraryText(
+        'import "a.dart"; import "b.dart"; C c; final d = f();');
+    int cReference = findVariable('c').type.reference;
+    int explicitDependency = linked.units[0].references[cReference].dependency;
+    int dReference =
+        getTypeRefForSlot(findVariable('d').propagatedTypeSlot).reference;
+    expect(
+        linked.units[0].references[dReference].dependency, explicitDependency);
+  }
+
+  test_local_names_take_precedence_over_imported_names() {
+    addNamedSource('/a.dart', 'class C {} class D {}');
+    serializeLibraryText('''
+import 'a.dart';
+class C {}
+C c;
+D d;''');
+    checkTypeRef(findVariable('c').type, null, null, 'C');
+    checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D');
+  }
+
+  test_method_documented() {
+    String text = '''
+class C {
+  /**
+   * Docs
+   */
+  f() {}
+}''';
+    UnlinkedExecutable executable = serializeClassText(text).executables[0];
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_method_inferred_type_nonstatic_explicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { void f(num value) {} }'
+            ' abstract class D { void f(int value); }',
+            className: 'C')
+        .executables[0];
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_method_inferred_type_nonstatic_explicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { num f() => null; } abstract class D { int f(); }',
+            className: 'C',
+            allowErrors: true)
+        .executables[0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_method_inferred_type_nonstatic_implicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { void f(value) {} }'
+            ' abstract class D { void f(int value); }',
+            className: 'C')
+        .executables[0];
+    checkInferredTypeSlot(
+        f.parameters[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_method_inferred_type_nonstatic_implicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { f() => null; } abstract class D { int f(); }',
+            className: 'C')
+        .executables[0];
+    checkInferredTypeSlot(
+        f.inferredReturnTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_method_inferred_type_static_implicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { static void f(value) {} }'
+            ' class D { static void f(int value) {} }',
+            className: 'C')
+        .executables[0];
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_method_inferred_type_static_implicit_return() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { static f() => null; }'
+            ' class D { static int f() => null; }',
+            className: 'C')
+        .executables[0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_part_declaration() {
+    addNamedSource('/a.dart', 'part of my.lib;');
+    String text = 'library my.lib; part "a.dart"; // <-part';
+    serializeLibraryText(text);
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
+    expect(unlinkedUnits[0].parts, hasLength(1));
+    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
+    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
+  }
+
+  test_parts_defining_compilation_unit() {
+    serializeLibraryText('');
+    expect(linked.units, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts, isEmpty);
+  }
+
+  test_parts_included() {
+    addNamedSource('/part1.dart', 'part of my.lib;');
+    String partString = '"part1.dart"';
+    String libraryText = 'library my.lib; part $partString;';
+    serializeLibraryText(libraryText);
+    expect(linked.units, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
+  }
+
+  test_public_namespace_of_part() {
+    addNamedSource('/a.dart', 'part of foo; class C {}');
+    serializeLibraryText('library foo; part "a.dart";');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+    expect(unlinkedUnits[1].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
+  }
+
+  test_setter_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+void set f(value) {}''';
+    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    expect(executable.documentationComment, isNotNull);
+    checkDocumentationComment(executable.documentationComment, text);
+  }
+
+  test_setter_inferred_type_nonstatic_explicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { void set f(num value) {} }'
+            ' abstract class D { void set f(int value); }',
+            className: 'C')
+        .executables[0];
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_setter_inferred_type_nonstatic_explicit_return() {
+    UnlinkedExecutable f =
+        serializeClassText('class C { void set f(int value) {} }').executables[
+            0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_setter_inferred_type_nonstatic_implicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { void set f(value) {} }'
+            ' abstract class D { void set f(int value); }',
+            className: 'C')
+        .executables[0];
+    checkInferredTypeSlot(
+        f.parameters[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_setter_inferred_type_nonstatic_implicit_return() {
+    UnlinkedExecutable f =
+        serializeClassText('class C { set f(int value) {} }').executables[0];
+    checkInferredTypeSlot(f.inferredReturnTypeSlot, null, null, 'void');
+  }
+
+  test_setter_inferred_type_static_implicit_param() {
+    UnlinkedExecutable f = serializeClassText(
+            'class C extends D { static void set f(value) {} }'
+            ' class D { static void set f(int value) {} }',
+            className: 'C')
+        .executables[0];
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_setter_inferred_type_static_implicit_return() {
+    UnlinkedExecutable f =
+        serializeClassText('class C { static set f(int value) {} }')
+            .executables[0];
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_setter_inferred_type_top_level_implicit_param() {
+    UnlinkedExecutable f =
+        serializeExecutableText('void set f(value) {}', 'f=');
+    expect(f.parameters[0].inferredTypeSlot, 0);
+  }
+
+  test_setter_inferred_type_top_level_implicit_return() {
+    UnlinkedExecutable f = serializeExecutableText('set f(int value) {}', 'f=');
+    expect(f.inferredReturnTypeSlot, 0);
+  }
+
+  test_slot_reuse() {
+    // Different compilation units have independent notions of slot id, so slot
+    // ids should be reused.
+    addNamedSource('/a.dart', 'part of foo; final v = 0;');
+    serializeLibraryText('library foo; part "a.dart"; final w = 0;');
+    expect(unlinkedUnits[0].variables[0].propagatedTypeSlot, 1);
+    expect(unlinkedUnits[1].variables[0].propagatedTypeSlot, 1);
+  }
+
+  test_type_arguments_explicit() {
+    EntityRef typeRef = serializeTypeText('List<int>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_explicit_dynamic() {
+    EntityRef typeRef = serializeTypeText('List<dynamic>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_dynamic_dynamic() {
+    EntityRef typeRef = serializeTypeText('Map<dynamic, dynamic>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    // Trailing type arguments of type `dynamic` are omitted.
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_dynamic_int() {
+    EntityRef typeRef = serializeTypeText('Map<dynamic, int>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    // Leading type arguments of type `dynamic` are not omitted.
+    expect(typeRef.typeArguments.length, 2);
+    checkDynamicTypeRef(typeRef.typeArguments[0]);
+    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_explicit_dynamic_typedef() {
+    EntityRef typeRef =
+        serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: ReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_explicit_String_dynamic() {
+    EntityRef typeRef = serializeTypeText('Map<String, dynamic>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    // Trailing type arguments of type `dynamic` are omitted.
+    expect(typeRef.typeArguments.length, 1);
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
+  }
+
+  test_type_arguments_explicit_String_int() {
+    EntityRef typeRef = serializeTypeText('Map<String, int>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    expect(typeRef.typeArguments.length, 2);
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
+    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_explicit_typedef() {
+    EntityRef typeRef =
+        serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: ReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, hasLength(1));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_type_arguments_implicit() {
+    EntityRef typeRef = serializeTypeText('List');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
+        allowTypeParameters: true, numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_implicit_typedef() {
+    EntityRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        allowTypeParameters: true,
+        expectedKind: ReferenceKind.typedef,
+        numTypeParameters: 1);
+    expect(typeRef.typeArguments, isEmpty);
+  }
+
+  test_type_arguments_order() {
+    EntityRef typeRef = serializeTypeText('Map<int, Object>');
+    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    expect(typeRef.typeArguments, hasLength(2));
+    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
+    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
+  }
+
+  test_type_dynamic() {
+    checkDynamicTypeRef(serializeTypeText('dynamic'));
+  }
+
+  test_type_param_not_shadowed_by_constructor() {
+    UnlinkedClass cls =
+        serializeClassText('class C<D> { D x; C.D(); } class D {}');
+    checkParamTypeRef(cls.fields[0].type, 1);
+  }
+
+  test_type_param_not_shadowed_by_field_in_extends() {
+    UnlinkedClass cls =
+        serializeClassText('class C<T> extends D<T> { T x; } class D<T> {}');
+    checkParamTypeRef(cls.supertype.typeArguments[0], 1);
+  }
+
+  test_type_param_not_shadowed_by_field_in_implements() {
+    UnlinkedClass cls =
+        serializeClassText('class C<T> implements D<T> { T x; } class D<T> {}');
+    checkParamTypeRef(cls.interfaces[0].typeArguments[0], 1);
+  }
+
+  test_type_param_not_shadowed_by_field_in_with() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<T> extends Object with D<T> { T x; } class D<T> {}');
+    checkParamTypeRef(cls.mixins[0].typeArguments[0], 1);
+  }
+
+  test_type_param_not_shadowed_by_method_parameter() {
+    UnlinkedClass cls = serializeClassText('class C<T> { f(int T, T x) {} }');
+    checkParamTypeRef(cls.executables[0].parameters[1].type, 1);
+  }
+
+  test_type_param_not_shadowed_by_setter() {
+    // The code under test should not produce a compile-time error, but it
+    // does.
+    bool workAroundBug25525 = true;
+    UnlinkedClass cls = serializeClassText(
+        'class C<D> { D x; void set D(value) {} } class D {}',
+        allowErrors: workAroundBug25525);
+    checkParamTypeRef(cls.fields[0].type, 1);
+  }
+
+  test_type_param_not_shadowed_by_typedef_parameter() {
+    UnlinkedTypedef typedef =
+        serializeTypedefText('typedef void F<T>(int T, T x);');
+    checkParamTypeRef(typedef.parameters[1].type, 1);
+  }
+
+  test_type_param_shadowed_by_field() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<D> { D x; int D; } class D {}',
+        allowErrors: true);
+    checkDynamicTypeRef(cls.fields[0].type);
+  }
+
+  test_type_param_shadowed_by_getter() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<D> { D x; int get D => null; } class D {}',
+        allowErrors: true);
+    checkDynamicTypeRef(cls.fields[0].type);
+  }
+
+  test_type_param_shadowed_by_method() {
+    UnlinkedClass cls = serializeClassText(
+        'class C<D> { D x; void D() {} } class D {}',
+        allowErrors: true);
+    checkDynamicTypeRef(cls.fields[0].type);
+  }
+
+  test_type_param_shadowed_by_type_param() {
+    UnlinkedClass cls =
+        serializeClassText('class C<T> { T f<T>(T x) => null; }');
+    checkParamTypeRef(cls.executables[0].returnType, 1);
+    checkParamTypeRef(cls.executables[0].parameters[0].type, 1);
+  }
+
+  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: ReferenceKind.classOrEnum,
+        linkedSourceUnit: linked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
+  test_type_reference_from_part_withPrefix() {
+    addNamedSource('/a.dart', 'class C {}');
+    addNamedSource('/p.dart', 'part of foo; a.C v;');
+    serializeLibraryText(
+        'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
+        allowErrors: true);
+    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
+        absUri('/a.dart'), 'a.dart', 'C',
+        expectedPrefix: 'a',
+        linkedSourceUnit: linked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
+  test_type_reference_to_class_argument() {
+    UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
+    {
+      EntityRef typeRef =
+          findVariable('t', variables: cls.fields, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 2);
+    }
+    {
+      EntityRef typeRef =
+          findVariable('u', variables: cls.fields, failIfAbsent: true).type;
+      checkParamTypeRef(typeRef, 1);
+    }
+  }
+
+  test_type_reference_to_import_of_export() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
+        absUri('/b.dart'), 'b.dart', 'C');
+  }
+
+  test_type_reference_to_import_of_export_via_prefix() {
+    addNamedSource('/a.dart', 'library a; export "b.dart";');
+    addNamedSource('/b.dart', 'library b; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
+        absUri('/b.dart'),
+        'b.dart',
+        'C',
+        expectedPrefix: 'p');
+  }
+
+  test_type_reference_to_imported_part() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; import "a.dart";'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_imported_part_with_prefix() {
+    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
+    addNamedSource('/b.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('p.C',
+            otherDeclarations: 'library my.lib; import "a.dart" as p;'),
+        absUri('/a.dart'),
+        'a.dart',
+        'C',
+        expectedPrefix: 'p',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_internal_class() {
+    checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null,
+        null, 'C');
+  }
+
+  test_type_reference_to_internal_class_alias() {
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'class C = D with E; class D {} class E {}'),
+        null,
+        null,
+        'C');
+  }
+
+  test_type_reference_to_internal_enum() {
+    checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
+        null, null, 'E');
+  }
+
+  test_type_reference_to_local_part() {
+    addNamedSource('/a.dart', 'part of my.lib; class C {}');
+    checkTypeRef(
+        serializeTypeText('C',
+            otherDeclarations: 'library my.lib; part "a.dart";'),
+        null,
+        null,
+        'C',
+        expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_nonexistent_file_via_prefix() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): this test currently fails because there is not enough
+      // information in the element model to figure out that the unresolved
+      // reference `p.C` uses the prefix `p`.
+      return;
+    }
+    allowMissingFiles = true;
+    EntityRef typeRef = serializeTypeText('p.C',
+        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, 'p', 'C');
+  }
+
+  test_type_reference_to_part() {
+    addNamedSource('/a.dart', 'part of foo; class C { C(); }');
+    serializeLibraryText('library foo; part "a.dart"; C c;');
+    checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C',
+        expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1);
+  }
+
+  test_type_reference_to_type_visible_via_multiple_import_prefixes() {
+    if (!checkAstDerivedData) {
+      // TODO(paulberry): this test currently fails because the element model
+      // doesn't record enough information to track which prefix is used to
+      // refer to a type.
+      return;
+    }
+    addNamedSource('/lib1.dart', 'class C');
+    addNamedSource('/lib2.dart', 'export "lib1.dart";');
+    addNamedSource('/lib3.dart', 'export "lib1.dart";');
+    addNamedSource('/lib4.dart', 'export "lib1.dart";');
+    serializeLibraryText('''
+import 'lib2.dart';
+import 'lib3.dart' as a;
+import 'lib4.dart' as b;
+C c2;
+a.C c3;
+b.C c4;''');
+    // Note: it is important that each reference to class C records the prefix
+    // used to find it; otherwise it's possible that relinking might produce an
+    // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
+    checkTypeRef(
+        findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C');
+    checkTypeRef(
+        findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'a');
+    checkTypeRef(
+        findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
+        expectedPrefix: 'b');
+  }
+
+  test_type_reference_to_typedef() {
+    checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
+        null, null, 'F',
+        expectedKind: ReferenceKind.typedef);
+  }
+
+  test_type_unit_counts_unreferenced_units() {
+    addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
+    addNamedSource('/b.dart', 'part of a;');
+    addNamedSource('/c.dart', 'part of a; class C {}');
+    EntityRef typeRef =
+        serializeTypeText('C', otherDeclarations: 'import "a.dart";');
+    // 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',
+        expectedTargetUnit: 2);
+  }
+
+  test_type_unresolved() {
+    EntityRef typeRef = serializeTypeText('Foo', allowErrors: true);
+    checkUnresolvedTypeRef(typeRef, null, 'Foo');
+  }
+
+  test_typedef_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+typedef F();''';
+    UnlinkedTypedef typedef = serializeTypedefText(text);
+    expect(typedef.documentationComment, isNotNull);
+    checkDocumentationComment(typedef.documentationComment, text);
+  }
+
+  test_typedef_name() {
+    String text = 'typedef F();';
+    UnlinkedTypedef type = serializeTypedefText(text);
+    expect(type.name, 'F');
+    expect(type.nameOffset, text.indexOf('F'));
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(
+        unlinkedUnits[0].publicNamespace.names[0].kind, ReferenceKind.typedef);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+  }
+
+  test_typedef_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.parameters, isEmpty);
+  }
+
+  test_typedef_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
+    expect(type.parameters, hasLength(2));
+    expect(type.parameters[0].name, 'x');
+    expect(type.parameters[1].name, 'y');
+  }
+
+  test_typedef_private() {
+    serializeTypedefText('typedef _F();', '_F');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_typedef_reference_generic() {
+    EntityRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+  }
+
+  test_typedef_reference_generic_imported() {
+    addNamedSource('/lib.dart', 'typedef void F<A, B>();');
+    EntityRef typeRef =
+        serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
+    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
+        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+  }
+
+  test_typedef_return_type_explicit() {
+    UnlinkedTypedef type = serializeTypedefText('typedef int F();');
+    checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_typedef_type_param_in_parameter() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
+    checkParamTypeRef(type.parameters[0].type, 1);
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
+  }
+
+  test_typedef_type_param_in_return_type() {
+    UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
+    checkParamTypeRef(type.returnType, 1);
+  }
+
+  test_typedef_type_param_none() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F();');
+    expect(type.typeParameters, isEmpty);
+  }
+
+  test_typedef_type_param_order() {
+    UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
+    expect(type.typeParameters, hasLength(2));
+    expect(type.typeParameters[0].name, 'T');
+    expect(type.typeParameters[1].name, 'U');
+  }
+
+  test_unresolved_reference_in_multiple_parts() {
+    addNamedSource('/a.dart', 'part of foo; int x; Unresolved y;');
+    serializeLibraryText('library foo; part "a.dart"; Unresolved z;',
+        allowErrors: true);
+    // The unresolved types in the defining compilation unit and the part
+    // should both work correctly even though they use different reference
+    // indices.
+    checkUnresolvedTypeRef(
+        unlinkedUnits[0].variables[0].type, null, 'Unresolved');
+    checkUnresolvedTypeRef(
+        unlinkedUnits[1].variables[1].type, null, 'Unresolved',
+        linkedSourceUnit: linked.units[1],
+        unlinkedSourceUnit: unlinkedUnits[1]);
+  }
+
+  test_variable() {
+    String text = 'int i;';
+    UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
+    expect(v.nameOffset, text.indexOf('i;'));
+    expect(findExecutable('i'), isNull);
+    expect(findExecutable('i='), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
+    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
+        ReferenceKind.topLevelPropertyAccessor);
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
+    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
+    expect(unlinkedUnits[0].publicNamespace.names[1].kind,
+        ReferenceKind.topLevelPropertyAccessor);
+    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
+    expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
+  }
+
+  test_variable_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('const int i = 0;', variableName: 'i');
+    expect(variable.isConst, isTrue);
+  }
+
+  test_variable_documented() {
+    String text = '''
+// Extra comment so doc comment offset != 0
+/**
+ * Docs
+ */
+var v;''';
+    UnlinkedVariable variable = serializeVariableText(text);
+    expect(variable.documentationComment, isNotNull);
+    checkDocumentationComment(variable.documentationComment, text);
+  }
+
+  test_variable_explicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('dynamic v;');
+    checkDynamicTypeRef(variable.type);
+  }
+
+  test_variable_final_top_level() {
+    UnlinkedVariable variable =
+        serializeVariableText('final int i = 0;', variableName: 'i');
+    expect(variable.isFinal, isTrue);
+  }
+
+  test_variable_implicit_dynamic() {
+    UnlinkedVariable variable = serializeVariableText('var v;');
+    expect(variable.type, isNull);
+  }
+
+  test_variable_inferred_type_explicit_initialized() {
+    UnlinkedVariable v = serializeVariableText('int v = 0;');
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_variable_inferred_type_implicit_initialized() {
+    UnlinkedVariable v = serializeVariableText('var v = 0;');
+    checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_variable_inferred_type_implicit_uninitialized() {
+    UnlinkedVariable v = serializeVariableText('var v;');
+    expect(v.inferredTypeSlot, 0);
+  }
+
+  test_variable_name() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.name, 'i');
+  }
+
+  test_variable_no_flags() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+    expect(variable.isConst, isFalse);
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_const() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i = 0;', variableName: 'i');
+    expect(variable.isConst, isFalse);
+  }
+
+  test_variable_non_final() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isFinal, isFalse);
+  }
+
+  test_variable_non_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { int i; }').fields[0];
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_non_static_top_level() {
+    // Top level variables are considered non-static.
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    expect(variable.isStatic, isFalse);
+  }
+
+  test_variable_private() {
+    serializeVariableText('int _i;', variableName: '_i');
+    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
+  }
+
+  test_variable_propagated_type_final_immediate() {
+    UnlinkedVariable v = serializeVariableText('final v = 0;');
+    checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
+  }
+
+  test_variable_propagated_type_new_reference() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('final v = 0;');
+    // Since the propagated type of `v` is `int`, and there are no references
+    // to `int` elsewhere in the source file, a new linked reference should
+    // have been created for it, with no associated unlinked reference.
+    expect(v.propagatedTypeSlot, isNot(0));
+    EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
+    expect(type, isNotNull);
+    expect(type.reference,
+        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
+  }
+
+  test_variable_propagated_type_omit_dynamic() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
+    EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
+    checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
+        allowTypeParameters: true, numTypeParameters: 2);
+    expect(type.typeArguments, hasLength(1));
+    checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
+  }
+
+  test_variable_propagatedTypeSlot_const() {
+    // Const variables are propagable so they have a nonzero
+    // propagatedTypeSlot.
+    UnlinkedVariable variable = serializeVariableText('const v = 0;');
+    expect(variable.propagatedTypeSlot, isNot(0));
+  }
+
+  test_variable_propagatedTypeSlot_final() {
+    // Final variables are propagable so they have a nonzero
+    // propagatedTypeSlot.
+    UnlinkedVariable variable = serializeVariableText('final v = 0;');
+    expect(variable.propagatedTypeSlot, isNot(0));
+  }
+
+  test_variable_propagatedTypeSlot_non_propagable() {
+    // Non-final non-const variables aren't propagable so they don't have a
+    // propagatedTypeSlot.
+    UnlinkedVariable variable = serializeVariableText('var v;');
+    expect(variable.propagatedTypeSlot, 0);
+  }
+
+  test_variable_static() {
+    UnlinkedVariable variable =
+        serializeClassText('class C { static int i; }').fields[0];
+    expect(variable.isStatic, isTrue);
+  }
+
+  test_variable_type() {
+    UnlinkedVariable variable =
+        serializeVariableText('int i;', variableName: 'i');
+    checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int');
+  }
+
+  void _assertUnlinkedConst(UnlinkedConst constExpr,
+      {List<UnlinkedConstOperation> operators,
+      List<int> ints: const <int>[],
+      List<double> doubles: const <double>[],
+      List<String> strings: const <String>[],
+      List<_EntityRefValidator> referenceValidators:
+          const <_EntityRefValidator>[]}) {
+    expect(constExpr, isNotNull);
+    expect(constExpr.operations, operators);
+    expect(constExpr.ints, ints);
+    expect(constExpr.doubles, doubles);
+    expect(constExpr.strings, strings);
+    expect(constExpr.references, hasLength(referenceValidators.length));
+    for (int i = 0; i < referenceValidators.length; i++) {
+      referenceValidators[i](constExpr.references[i]);
+    }
+  }
+}
+
+/**
+ * Description of expectations for a prelinked prefix reference.
+ */
+class _PrefixExpectation {
+  final ReferenceKind kind;
+  final String name;
+  final bool inLibraryDefiningUnit;
+  final String absoluteUri;
+  final String relativeUri;
+  final int numTypeParameters;
+
+  _PrefixExpectation(this.kind, this.name,
+      {this.inLibraryDefiningUnit: false,
+      this.absoluteUri,
+      this.relativeUri,
+      this.numTypeParameters: 0});
+}
diff --git a/pkg/analyzer/test/src/summary/summary_sdk_test.dart b/pkg/analyzer/test/src/summary/summary_sdk_test.dart
deleted file mode 100644
index 5ec807e..0000000
--- a/pkg/analyzer/test/src/summary/summary_sdk_test.dart
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.src.summary.summary_sdk_test;
-
-import 'dart:io';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisContext, CacheState;
-import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/summary_sdk.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart' show AnalysisContextTarget;
-import 'package:analyzer/task/model.dart';
-import 'package:path/path.dart' as pathos;
-import 'package:unittest/unittest.dart';
-
-import '../../generated/test_support.dart';
-import '../../reflective_tests.dart';
-
-main() {
-  groupSep = ' | ';
-  runReflectiveTests(SummarySdkAnalysisContextTest);
-}
-
-@reflectiveTest
-class SummarySdkAnalysisContextTest {
-  static String _analyzerPackagePath;
-  static bool _analyzerPackagePathInitialized = false;
-
-  static SdkBundle sdkBundle;
-
-  SummarySdkAnalysisContext context;
-
-  void setUp() {
-    _initializeSdkContext();
-  }
-
-  test_libraryResults() {
-    if (context == null) {
-      return;
-    }
-    // verify that there are at least some interesting libraries in the bundle
-    expect(sdkBundle.prelinkedLibraryUris, contains('dart:core'));
-    expect(sdkBundle.prelinkedLibraryUris, contains('dart:async'));
-    expect(sdkBundle.prelinkedLibraryUris, contains('dart:html'));
-    // verify every library
-    for (String uri in sdkBundle.prelinkedLibraryUris) {
-      // TODO(scheglov) breaks at _LibraryResynthesizer.buildImplicitTopLevelVariable
-      if (uri == 'dart:io' || uri == 'dart:_isolate_helper') {
-        continue;
-      }
-      _assertLibraryResults(uri);
-    }
-  }
-
-  test_sourceKind() {
-    if (context == null) {
-      return;
-    }
-    // libraries
-    _assertHasSourceKind('dart:core', SourceKind.LIBRARY);
-    _assertHasSourceKind('dart:async', SourceKind.LIBRARY);
-    _assertHasSourceKind('dart:math', SourceKind.LIBRARY);
-    // parts
-    _assertHasSourceKind('dart:core/bool.dart', SourceKind.PART);
-    _assertHasSourceKind('dart:async/future.dart', SourceKind.PART);
-    // unknown
-    _assertHasSourceKind('dart:no_such_library.dart', null);
-    _assertHasSourceKind('dart:core/no_such_part.dart', null);
-  }
-
-  test_typeProvider() {
-    if (context == null) {
-      return;
-    }
-    AnalysisContextTarget target = AnalysisContextTarget.request;
-    CacheEntry cacheEntry = context.getCacheEntry(target);
-    bool hasResult = context.aboutToComputeResult(cacheEntry, TYPE_PROVIDER);
-    expect(hasResult, isTrue);
-    expect(cacheEntry.getState(TYPE_PROVIDER), CacheState.VALID);
-    TypeProvider typeProvider = cacheEntry.getValue(TYPE_PROVIDER);
-    expect(typeProvider.objectType, isNotNull);
-    expect(typeProvider.boolType, isNotNull);
-    expect(typeProvider.intType, isNotNull);
-    expect(typeProvider.futureType, isNotNull);
-    expect(typeProvider.futureDynamicType, isNotNull);
-    expect(typeProvider.streamType, isNotNull);
-    expect(typeProvider.streamDynamicType, isNotNull);
-  }
-
-  void _assertHasLibraryElement(CacheEntry cacheEntry,
-      ResultDescriptor<LibraryElement> resultDescriptor) {
-    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
-    expect(hasResult, isTrue);
-    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
-    LibraryElement library = cacheEntry.getValue(resultDescriptor);
-    expect(library, isNotNull);
-  }
-
-  void _assertHasSourceKind(String uri, SourceKind expectedValue) {
-    Source target = context.sourceFactory.forUri(uri);
-    CacheEntry cacheEntry = context.getCacheEntry(target);
-    ResultDescriptor<SourceKind> resultDescriptor = SOURCE_KIND;
-    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
-    if (expectedValue == null) {
-      expect(hasResult, isFalse);
-      expect(cacheEntry.getState(resultDescriptor), CacheState.INVALID);
-    } else {
-      expect(hasResult, isTrue);
-      expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
-      SourceKind value = cacheEntry.getValue(resultDescriptor);
-      expect(value, expectedValue);
-    }
-  }
-
-  void _assertIsLibraryElementReady(
-      CacheEntry cacheEntry, ResultDescriptor<bool> resultDescriptor) {
-    bool hasResult = context.aboutToComputeResult(cacheEntry, resultDescriptor);
-    expect(hasResult, isTrue);
-    expect(cacheEntry.getState(resultDescriptor), CacheState.VALID);
-    bool ready = cacheEntry.getValue(resultDescriptor);
-    expect(ready, isTrue);
-  }
-
-  void _assertLibraryResults(String uri) {
-    Source target = context.sourceFactory.forUri(uri);
-    CacheEntry cacheEntry = context.getCacheEntry(target);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT1);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT2);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT3);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT4);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT5);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT6);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT7);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT8);
-    _assertHasLibraryElement(cacheEntry, LIBRARY_ELEMENT);
-    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT2);
-    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT5);
-    _assertIsLibraryElementReady(cacheEntry, READY_LIBRARY_ELEMENT6);
-  }
-
-  void _initializeSdkBundle() {
-    if (sdkBundle != null) {
-      return;
-    }
-    // prepare analyzer path
-    String analyzerPath = getAnalyzerPackagePath();
-    if (analyzerPath == null) {
-      return;
-    }
-    // prepare summary path
-    String sdkSummaryPath = pathos.join(
-        analyzerPath, 'test', 'src', 'summary', 'sdk_analysis_summary');
-    File file = new File(sdkSummaryPath);
-    if (!file.existsSync()) {
-      return;
-    }
-    // load SdkBundle
-    List<int> bytes = file.readAsBytesSync();
-    sdkBundle = new SdkBundle.fromBuffer(bytes);
-  }
-
-  void _initializeSdkContext() {
-    _initializeSdkBundle();
-    if (sdkBundle == null) {
-      return;
-    }
-    context = new _TestSummarySdkAnalysisContext(sdkBundle);
-    DartSdk sdk = new _TestSummaryDartSdk();
-    context.sourceFactory = new SourceFactory([new DartUriResolver(sdk)]);
-  }
-
-  static String getAnalyzerPackagePath() {
-    if (!_analyzerPackagePathInitialized) {
-      _analyzerPackagePathInitialized = true;
-      _analyzerPackagePath = _computeAnalyzerPackagePath();
-    }
-    return _analyzerPackagePath;
-  }
-
-  /**
-   * Return the path to the `analyzer` package root, or `null` if it cannot
-   * be determined.
-   *
-   * This method expects that one of the `analyzer` tests was run, so
-   * [Platform.script] is inside of the `analyzer/test` folder.
-   */
-  static String _computeAnalyzerPackagePath() {
-    Uri uri = Platform.script;
-    if (uri == null || uri.scheme != 'file') {
-      return null;
-    }
-    String path = pathos.fromUri(uri);
-    List<String> segments = pathos.split(path);
-    while (segments.length > 2) {
-      if (segments[segments.length - 1] == 'test' &&
-          segments[segments.length - 2] == 'analyzer') {
-        segments.removeLast();
-        return pathos.joinAll(segments);
-      }
-      segments.removeLast();
-    }
-    return null;
-  }
-}
-
-class _TestSummaryDartSdk implements DartSdk {
-  @override
-  Source mapDartUri(String uriStr) {
-    Uri uri = Uri.parse(uriStr);
-    List<String> segments = uri.pathSegments;
-    if (segments.length == 1) {
-      String libraryName = segments.first;
-      String path = '/sdk/$libraryName/$libraryName.dart';
-      return new _TestSummarySdkSource(path, uri);
-    } else {
-      String path = '/sdk/' + segments.join('/');
-      return new _TestSummarySdkSource(path, uri);
-    }
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-/**
- * [SummarySdkAnalysisContext] with simplified cache creation.
- */
-class _TestSummarySdkAnalysisContext extends SummarySdkAnalysisContext {
-  _TestSummarySdkAnalysisContext(SdkBundle bundle) : super(bundle);
-
-  @override
-  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    return new AnalysisCache(<CachePartition>[new SdkCachePartition(this)]);
-  }
-}
-
-class _TestSummarySdkSource extends TestSourceWithUri {
-  _TestSummarySdkSource(String path, Uri uri) : super(path, uri);
-
-  @override
-  bool get isInSystemLibrary => true;
-
-  @override
-  Uri resolveRelativeUri(Uri relativeUri) {
-    Uri baseUri = uri;
-    if (uri.scheme == 'dart') {
-      String libraryName = uri.path;
-      baseUri = Uri.parse('dart:$libraryName/$libraryName.dart');
-    }
-    return baseUri.resolveUri(relativeUri);
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
deleted file mode 100644
index 8b25e9d..0000000
--- a/pkg/analyzer/test/src/summary/summary_test.dart
+++ /dev/null
@@ -1,2966 +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 analyzer.test.src.summary.summary_test;
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/summary/base.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/prelink.dart';
-import 'package:analyzer/src/summary/public_namespace_computer.dart'
-    as public_namespace;
-import 'package:analyzer/src/summary/summarize_elements.dart'
-    as summarize_elements;
-import 'package:unittest/unittest.dart';
-
-import '../../generated/resolver_test.dart';
-import '../../reflective_tests.dart';
-
-main() {
-  groupSep = ' | ';
-  runReflectiveTests(SummarizeElementsTest);
-  runReflectiveTests(PrelinkerTest);
-}
-
-/**
- * Convert a summary object (or a portion of one) into a canonical form that
- * can be easily compared using [expect].  If [orderByName] is true, and the
- * object is a [List], it is sorted by the `name` field of its elements.
- */
-Object canonicalize(Object obj, {bool orderByName: false}) {
-  if (obj is SummaryClass) {
-    Map<String, Object> result = <String, Object>{};
-    obj.toMap().forEach((String key, Object value) {
-      bool orderByName = false;
-      if (obj is UnlinkedPublicNamespace && key == 'names') {
-        orderByName = true;
-      }
-      result[key] = canonicalize(value, orderByName: orderByName);
-    });
-    return result;
-  } else if (obj is List) {
-    List<Object> result = <Object>[];
-    for (Object item in obj) {
-      result.add(canonicalize(item));
-    }
-    if (orderByName) {
-      result.sort((Object a, Object b) {
-        if (a is Map && b is Map) {
-          return Comparable.compare(a['name'], b['name']);
-        } else {
-          return 0;
-        }
-      });
-    }
-    return result;
-  } else if (obj is String || obj is num || obj is bool) {
-    return obj;
-  } else {
-    return obj.toString();
-  }
-}
-
-UnlinkedPublicNamespace computePublicNamespaceFromText(
-    String text, Source source) {
-  CharacterReader reader = new CharSequenceReader(text);
-  Scanner scanner =
-      new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
-  Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
-  parser.parseGenericMethods = true;
-  CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
-  UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
-      public_namespace.computePublicNamespace(unit).toBuffer());
-  return namespace;
-}
-
-/**
- * Override of [SummaryTest] which verifies the correctness of the prelinker by
- * creating summaries from the element model, discarding their prelinked
- * information, and then recreating it using the prelinker.
- */
-@reflectiveTest
-class PrelinkerTest extends SummarizeElementsTest {
-  /**
-   * The public namespaces of the sdk are computed once so that we don't bog
-   * down the test.  Structured as a map from absolute URI to the corresponding
-   * public namespace.
-   *
-   * Note: should an exception occur during computation of this variable, it
-   * will silently be set to null to allow other tests to run.
-   */
-  static final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () {
-    try {
-      AnalysisContext analysisContext =
-          AnalysisContextFactory.contextWithCore();
-      Map<String, UnlinkedPublicNamespace> uriToNamespace =
-          <String, UnlinkedPublicNamespace>{};
-      List<LibraryElement> libraries = [
-        analysisContext.typeProvider.objectType.element.library,
-        analysisContext.typeProvider.futureType.element.library
-      ];
-      for (LibraryElement library in libraries) {
-        summarize_elements.LibrarySerializationResult serializedLibrary =
-            summarize_elements.serializeLibrary(
-                library, analysisContext.typeProvider);
-        for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) {
-          uriToNamespace[
-              serializedLibrary.unitUris[i]] = new UnlinkedUnit.fromBuffer(
-              serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace;
-        }
-      }
-      return uriToNamespace;
-    } catch (_) {
-      return null;
-    }
-  }();
-
-  final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
-      <String, UnlinkedPublicNamespace>{};
-
-  @override
-  bool get expectAbsoluteUrisInDependencies => false;
-
-  @override
-  Source addNamedSource(String filePath, String contents) {
-    Source source = super.addNamedSource(filePath, contents);
-    uriToPublicNamespace[absUri(filePath)] =
-        computePublicNamespaceFromText(contents, source);
-    return source;
-  }
-
-  String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
-    Source resolvedSource =
-        analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
-    if (resolvedSource == null) {
-      fail('Failed to resolve relative uri "$relativeUri"');
-    }
-    return resolvedSource.uri.toString();
-  }
-
-  @override
-  void serializeLibraryElement(LibraryElement library) {
-    super.serializeLibraryElement(library);
-    Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
-    expect(unlinkedUnits.length, unitUris.length);
-    for (int i = 1; i < unlinkedUnits.length; i++) {
-      uriToUnit[unitUris[i]] = unlinkedUnits[i];
-    }
-    UnlinkedUnit getPart(String relativeUri) {
-      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
-      UnlinkedUnit unit = uriToUnit[absoluteUri];
-      if (unit == null) {
-        fail('Prelinker unexpectedly requested unit for "$relativeUri"'
-            ' (resolves to "$absoluteUri").');
-      }
-      return unit;
-    }
-    UnlinkedPublicNamespace getImport(String relativeUri) {
-      String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
-      UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
-      if (namespace == null) {
-        namespace = uriToPublicNamespace[absoluteUri];
-      }
-      if (namespace == null && !allowMissingFiles) {
-        fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
-            ' (resolves to "$absoluteUri").'
-            '  Namespaces available: ${uriToPublicNamespace.keys}');
-      }
-      return namespace;
-    }
-    prelinked = new PrelinkedLibrary.fromBuffer(
-        prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
-  }
-}
-
-/**
- * Override of [SummaryTest] which creates summaries from the element model.
- */
-@reflectiveTest
-class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
-  /**
-   * The list of absolute unit URIs corresponding to the compilation units in
-   * [unlinkedUnits].
-   */
-  List<String> unitUris;
-
-  /**
-   * Map containing all source files in this test, and their corresponding file
-   * contents.
-   */
-  final Map<Source, String> _fileContents = <Source, String>{};
-
-  @override
-  bool get checkAstDerivedData => false;
-
-  @override
-  bool get expectAbsoluteUrisInDependencies => true;
-
-  @override
-  Source addNamedSource(String filePath, String contents) {
-    Source source = super.addNamedSource(filePath, contents);
-    _fileContents[source] = contents;
-    return source;
-  }
-
-  /**
-   * Serialize the library containing the given class [element], then
-   * deserialize it and return the summary of the class.
-   */
-  UnlinkedClass serializeClassElement(ClassElement element) {
-    serializeLibraryElement(element.library);
-    return findClass(element.name, failIfAbsent: true);
-  }
-
-  /**
-   * Serialize the given [library] element, then deserialize it and store the
-   * resulting summary in [prelinked] and [unlinkedUnits].
-   */
-  void serializeLibraryElement(LibraryElement library) {
-    summarize_elements.LibrarySerializationResult serializedLib =
-        summarize_elements.serializeLibrary(library, typeProvider);
-    {
-      List<int> buffer = serializedLib.prelinked.toBuffer();
-      prelinked = new PrelinkedLibrary.fromBuffer(buffer);
-    }
-    unlinkedUnits = serializedLib.unlinkedUnits.map((UnlinkedUnitBuilder b) {
-      List<int> buffer = b.toBuffer();
-      return new UnlinkedUnit.fromBuffer(buffer);
-    }).toList();
-    unitUris = serializedLib.unitUris;
-  }
-
-  @override
-  void serializeLibraryText(String text, {bool allowErrors: false}) {
-    Source source = addSource(text);
-    _fileContents[source] = text;
-    LibraryElement library = resolve2(source);
-    if (!allowErrors) {
-      assertNoErrors(source);
-    }
-    serializeLibraryElement(library);
-    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);
-    }
-    verifyPublicNamespace();
-  }
-
-  @override
-  void setUp() {
-    super.setUp();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.enableGenericMethods = true;
-    resetWithOptions(options);
-  }
-
-  test_class_no_superclass() {
-    UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
-    expect(cls.supertype, isNull);
-    expect(cls.hasNoSupertype, isTrue);
-  }
-
-  /**
-   * Verify that [public_namespace.computePublicNamespace] produces data that's
-   * equivalent to that produced by [summarize_elements.serializeLibrary].
-   */
-  void verifyPublicNamespace() {
-    for (int i = 0; i < unlinkedUnits.length; i++) {
-      Source source = analysisContext.sourceFactory.forUri(unitUris[i]);
-      String text = _fileContents[source];
-      if (text == null) {
-        if (!allowMissingFiles) {
-          fail('Could not find file while verifying public namespace: '
-              '${unitUris[i]}');
-        }
-      } else {
-        UnlinkedPublicNamespace namespace =
-            computePublicNamespaceFromText(text, source);
-        expect(canonicalize(namespace),
-            canonicalize(unlinkedUnits[i].publicNamespace),
-            reason: 'publicNamespace(${unitUris[i]})');
-      }
-    }
-  }
-}
-
-/**
- * Base class containing most summary tests.  This allows summary tests to be
- * re-used to exercise all the different ways in which summaries can be
- * generated (e.g. direct from the AST, from the element model, from a
- * "relinking" process, etc.)
- */
-abstract class SummaryTest {
-  /**
-   * Prelinked summary that results from serializing and then deserializing the
-   * library under test.
-   */
-  PrelinkedLibrary prelinked;
-
-  /**
-   * Unlinked compilation unit summaries that result from serializing and
-   * deserializing the library under test.
-   */
-  List<UnlinkedUnit> unlinkedUnits;
-
-  /**
-   * A test will set this to `true` if it contains `import`, `export`, or
-   * `part` declarations that deliberately refer to non-existent files.
-   */
-  bool allowMissingFiles = false;
-
-  /**
-   * `true` if the summary was created directly from the AST (and hence
-   * contains information that is not obtainable from the element model alone).
-   * TODO(paulberry): modify the element model so that it contains all the data
-   * that summaries need, so that this flag is no longer needed.
-   */
-  bool get checkAstDerivedData;
-
-  /**
-   * Get access to the prelinked defining compilation unit.
-   */
-  PrelinkedUnit get definingUnit => prelinked.units[0];
-
-  /**
-   * `true` if the prelinked portion of the summary is expected to contain
-   * absolute URIs.  This happens because the element model doesn't (yet) store
-   * enough information to recover relative URIs, TODO(paulberry): fix this.
-   */
-  bool get expectAbsoluteUrisInDependencies;
-
-  /**
-   * Convert [path] to a suitably formatted absolute path URI for the current
-   * platform.
-   */
-  String absUri(String path) {
-    return FileUtilities2.createFile(path).toURI().toString();
-  }
-
-  /**
-   * Add the given source file so that it may be referenced by the file under
-   * test.
-   */
-  Source addNamedSource(String filePath, String contents);
-
-  /**
-   * Verify that the [dependency]th element of the dependency table represents
-   * a file reachable via the given [absoluteUri] and [relativeUri].
-   */
-  void checkDependency(int dependency, String absoluteUri, String relativeUri) {
-    if (expectAbsoluteUrisInDependencies) {
-      // The element model doesn't (yet) store enough information to recover
-      // relative URIs, so we have to use the absolute URI.
-      // TODO(paulberry): fix this.
-      relativeUri = absoluteUri;
-    }
-    expect(dependency, new isInstanceOf<int>());
-    expect(prelinked.dependencies[dependency].uri, relativeUri);
-  }
-
-  /**
-   * Verify that the given [dependency] lists the given [absoluteUris] or
-   * [relativeUris] as its parts.
-   */
-  void checkDependencyParts(PrelinkedDependency dependency,
-      List<String> absoluteUris, List<String> relativeUris) {
-    if (expectAbsoluteUrisInDependencies) {
-      // The element model doesn't (yet) store enough information to recover
-      // relative URIs, so we have to use the absolute URI.
-      // TODO(paulberry): fix this.
-      relativeUris = absoluteUris;
-    }
-    expect(dependency.parts, relativeUris);
-  }
-
-  /**
-   * Check that the given [documentationComment] matches the first
-   * Javadoc-style comment found in [text].
-   *
-   * Note that the algorithm for finding the Javadoc-style comment in [text] is
-   * a simple-minded text search; it is easily confused by corner cases such as
-   * strings containing comments, nested comments, etc.
-   */
-  void checkDocumentationComment(
-      UnlinkedDocumentationComment documentationComment, String text) {
-    expect(documentationComment, isNotNull);
-    int commentStart = text.indexOf('/*');
-    expect(commentStart, isNot(-1));
-    int commentEnd = text.indexOf('*/');
-    expect(commentEnd, isNot(-1));
-    commentEnd += 2;
-    String expectedCommentText =
-        text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
-    expect(documentationComment.text, expectedCommentText);
-    expect(documentationComment.offset, commentStart);
-    expect(documentationComment.length, commentEnd - commentStart);
-  }
-
-  /**
-   * Verify that the given [typeRef] represents the type `dynamic`.
-   */
-  void checkDynamicTypeRef(UnlinkedTypeRef typeRef) {
-    checkTypeRef(typeRef, null, null, null);
-  }
-
-  /**
-   * Verify that the dependency table contains an entry for a file reachable
-   * via the given [absoluteUri] and [relativeUri].
-   *
-   * The [PrelinkedDependency] is returned.
-   */
-  PrelinkedDependency checkHasDependency(
-      String absoluteUri, String relativeUri) {
-    if (expectAbsoluteUrisInDependencies) {
-      // The element model doesn't (yet) store enough information to recover
-      // relative URIs, so we have to use the absolute URI.
-      // TODO(paulberry): fix this.
-      relativeUri = absoluteUri;
-    }
-    List<String> found = <String>[];
-    for (PrelinkedDependency dep in prelinked.dependencies) {
-      if (dep.uri == relativeUri) {
-        return dep;
-      }
-      found.add(dep.uri);
-    }
-    fail('Did not find dependency $relativeUri.  Found: $found');
-    return null;
-  }
-
-  /**
-   * Verify that the dependency table *does not* contain any entries for a file
-   * reachable via the given [absoluteUri] and [relativeUri].
-   */
-  void checkLacksDependency(String absoluteUri, String relativeUri) {
-    if (expectAbsoluteUrisInDependencies) {
-      // The element model doesn't (yet) store enough information to recover
-      // relative URIs, so we have to use the absolute URI.
-      // TODO(paulberry): fix this.
-      relativeUri = absoluteUri;
-    }
-    for (PrelinkedDependency dep in prelinked.dependencies) {
-      if (dep.uri == relativeUri) {
-        fail('Unexpected dependency found: $relativeUri');
-      }
-    }
-  }
-
-  /**
-   * Verify that the given [typeRef] represents a reference to a type parameter
-   * having the given [deBruijnIndex].
-   */
-  void checkParamTypeRef(UnlinkedTypeRef typeRef, int deBruijnIndex) {
-    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
-    expect(typeRef.reference, 0);
-    expect(typeRef.typeArguments, isEmpty);
-    expect(typeRef.paramReference, deBruijnIndex);
-  }
-
-  /**
-   * 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.  [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.  [numTypeParameters] is the
-   * number of type parameters of the thing being referred to.
-   */
-  void checkTypeRef(UnlinkedTypeRef typeRef, String absoluteUri,
-      String relativeUri, String expectedName,
-      {String expectedPrefix,
-      bool allowTypeParameters: false,
-      PrelinkedReferenceKind expectedKind: PrelinkedReferenceKind.classOrEnum,
-      int expectedTargetUnit: 0,
-      PrelinkedUnit prelinkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0}) {
-    prelinkedSourceUnit ??= definingUnit;
-    unlinkedSourceUnit ??= unlinkedUnits[0];
-    expect(typeRef, new isInstanceOf<UnlinkedTypeRef>());
-    expect(typeRef.paramReference, 0);
-    int index = typeRef.reference;
-    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 {
-      checkDependency(referenceResolution.dependency, absoluteUri, relativeUri);
-    }
-    if (!allowTypeParameters) {
-      expect(typeRef.typeArguments, isEmpty);
-    }
-    if (expectedKind == PrelinkedReferenceKind.unresolved) {
-      // summarize_elements.dart isn't yet able to record the name of
-      // unresolved references.  TODO(paulberry): fix this.
-      expect(reference.name, '*unresolved*');
-    } else if (expectedName == null) {
-      expect(reference.name, isEmpty);
-    } else {
-      expect(reference.name, expectedName);
-    }
-    if (expectedPrefix == null) {
-      expect(reference.prefixReference, 0);
-    } else {
-      checkPrefix(reference.prefixReference, expectedPrefix);
-    }
-    expect(referenceResolution.kind, expectedKind);
-    expect(referenceResolution.unit, expectedTargetUnit);
-    expect(referenceResolution.numTypeParameters, numTypeParameters);
-  }
-
-  /**
-   * Verify that the given [typeRef] represents a reference to an unresolved
-   * type.
-   */
-  void checkUnresolvedTypeRef(
-      UnlinkedTypeRef typeRef, String expectedPrefix, String expectedName) {
-    // When serializing from the element model, unresolved type refs lose their
-    // name.
-    checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null,
-        expectedPrefix: expectedPrefix,
-        expectedKind: PrelinkedReferenceKind.unresolved);
-  }
-
-  fail_enum_value_documented() {
-    // TODO(paulberry): currently broken because of dartbug.com/25385
-    String text = '''
-enum E {
-  /**
-   * Docs
-   */
-  v
-}''';
-    UnlinkedEnumValue value = serializeEnumText(text).values[0];
-    expect(value.documentationComment, isNotNull);
-    checkDocumentationComment(value.documentationComment, text);
-  }
-
-  fail_test_import_missing() {
-    // TODO(paulberry): At the moment unresolved imports are not included in
-    // the element model, so we can't pass this test.
-    // Unresolved imports are included since this is necessary for proper
-    // dependency tracking.
-    allowMissingFiles = true;
-    serializeLibraryText('import "foo.dart";', allowErrors: true);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    checkDependency(
-        prelinked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
-  }
-
-  fail_type_reference_to_nonexistent_file_via_prefix() {
-    // TODO(paulberry): this test currently fails because there is not enough
-    // information in the element model to figure out that the unresolved
-    // reference `p.C` uses the prefix `p`.
-    allowMissingFiles = true;
-    UnlinkedTypeRef typeRef = serializeTypeText('p.C',
-        otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
-    checkUnresolvedTypeRef(typeRef, 'p', 'C');
-  }
-
-  fail_type_reference_to_type_visible_via_multiple_import_prefixes() {
-    // TODO(paulberry): this test currently fails because the element model
-    // doesn't record enough information to track which prefix is used to refer
-    // to a type.
-    addNamedSource('/lib1.dart', 'class C');
-    addNamedSource('/lib2.dart', 'export "lib1.dart";');
-    addNamedSource('/lib3.dart', 'export "lib1.dart";');
-    addNamedSource('/lib4.dart', 'export "lib1.dart";');
-    serializeLibraryText('''
-import 'lib2.dart';
-import 'lib3.dart' as a;
-import 'lib4.dart' as b;
-C c2;
-a.C c3;
-b.C c4;''');
-    // Note: it is important that each reference to class C records the prefix
-    // used to find it; otherwise it's possible that relinking might produce an
-    // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
-    checkTypeRef(
-        findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C');
-    checkTypeRef(
-        findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
-        expectedPrefix: 'a');
-    checkTypeRef(
-        findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
-        expectedPrefix: 'b');
-  }
-
-  /**
-   * Find the class with the given [className] in the summary, and return its
-   * [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, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedClass result;
-    for (UnlinkedClass cls in unit.classes) {
-      if (cls.name == className) {
-        if (result != null) {
-          fail('Duplicate class $className');
-        }
-        result = cls;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Class $className not found in serialized output');
-    }
-    return result;
-  }
-
-  /**
-   * Find the enum with the given [enumName] in the summary, and return its
-   * [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, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedEnum result;
-    for (UnlinkedEnum e in unit.enums) {
-      if (e.name == enumName) {
-        if (result != null) {
-          fail('Duplicate enum $enumName');
-        }
-        result = e;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Enum $enumName not found in serialized output');
-    }
-    return result;
-  }
-
-  /**
-   * Find the executable with the given [executableName] in the summary, and
-   * 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,
-      {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
-    executables ??= unlinkedUnits[0].executables;
-    UnlinkedExecutable result;
-    for (UnlinkedExecutable executable in executables) {
-      if (executable.name == executableName) {
-        if (result != null) {
-          fail('Duplicate executable $executableName');
-        }
-        result = executable;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Executable $executableName not found in serialized output');
-    }
-    return result;
-  }
-
-  /**
-   * Find the typedef with the given [typedefName] in the summary, and return
-   * 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, UnlinkedUnit unit}) {
-    unit ??= unlinkedUnits[0];
-    UnlinkedTypedef result;
-    for (UnlinkedTypedef type in unit.typedefs) {
-      if (type.name == typedefName) {
-        if (result != null) {
-          fail('Duplicate typedef $typedefName');
-        }
-        result = type;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Typedef $typedefName not found in serialized output');
-    }
-    return result;
-  }
-
-  /**
-   * Find the top level variable with the given [variableName] in the summary,
-   * 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,
-      {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
-    variables ??= unlinkedUnits[0].variables;
-    UnlinkedVariable result;
-    for (UnlinkedVariable variable in variables) {
-      if (variable.name == variableName) {
-        if (result != null) {
-          fail('Duplicate variable $variableName');
-        }
-        result = variable;
-      }
-    }
-    if (result == null && failIfAbsent) {
-      fail('Variable $variableName not found in serialized output');
-    }
-    return result;
-  }
-
-  /**
-   * Serialize the given library [text] and return the summary of the class
-   * with the given [className].
-   */
-  UnlinkedClass serializeClassText(String text, [String className = 'C']) {
-    serializeLibraryText(text);
-    return findClass(className, failIfAbsent: true);
-  }
-
-  /**
-   * Serialize the given library [text] and return the summary of the enum with
-   * the given [enumName].
-   */
-  UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
-    serializeLibraryText(text);
-    return findEnum(enumName, failIfAbsent: true);
-  }
-
-  /**
-   * Serialize the given library [text] and return the summary of the
-   * executable with the given [executableName].
-   */
-  UnlinkedExecutable serializeExecutableText(String text,
-      [String executableName = 'f']) {
-    serializeLibraryText(text);
-    return findExecutable(executableName, failIfAbsent: true);
-  }
-
-  /**
-   * Serialize the given library [text], then deserialize it and store its
-   * summary in [lib].
-   */
-  void serializeLibraryText(String text, {bool allowErrors: false});
-
-  /**
-   * Serialize the given method [text] and return the summary of the executable
-   * with the given [executableName].
-   */
-  UnlinkedExecutable serializeMethodText(String text,
-      [String executableName = 'f']) {
-    serializeLibraryText('class C { $text }');
-    return findExecutable(executableName,
-        executables: findClass('C', failIfAbsent: true).executables,
-        failIfAbsent: true);
-  }
-
-  /**
-   * Serialize the given library [text] and return the summary of the typedef
-   * with the given [typedefName].
-   */
-  UnlinkedTypedef serializeTypedefText(String text,
-      [String typedefName = 'F']) {
-    serializeLibraryText(text);
-    return findTypedef(typedefName, failIfAbsent: true);
-  }
-
-  /**
-   * Serialize a type declaration using the given [text] as a type name, and
-   * return a summary of the corresponding [UnlinkedTypeRef].  If the type
-   * declaration needs to refer to types that are not available in core, those
-   * types may be declared in [otherDeclarations].
-   */
-  UnlinkedTypeRef serializeTypeText(String text,
-      {String otherDeclarations: '', bool allowErrors: false}) {
-    return serializeVariableText('$otherDeclarations\n$text v;',
-        allowErrors: allowErrors).type;
-  }
-
-  /**
-   * Serialize the given library [text] and return the summary of the variable
-   * with the given [variableName].
-   */
-  UnlinkedVariable serializeVariableText(String text,
-      {String variableName: 'v', bool allowErrors: false}) {
-    serializeLibraryText(text, allowErrors: allowErrors);
-    return findVariable(variableName, failIfAbsent: true);
-  }
-
-  test_cascaded_export_hide_hide() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(
-        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_hide_show() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(
-        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_show_hide() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(
-        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_export_show_show() {
-    addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
-    addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib1.dart';
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(
-        findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_hide_hide() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib.dart' hide C hide B, C;
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_hide_show() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib.dart' hide C show A, C;
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_show_hide() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib.dart' show A, B hide B, C;
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_cascaded_import_show_show() {
-    addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
-    serializeLibraryText(
-        '''
-import 'lib.dart' show A, B show A, C;
-A a;
-B b;
-C c;
-    ''',
-        allowErrors: true);
-    checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
-    checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
-    checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
-  }
-
-  test_class_abstract() {
-    UnlinkedClass cls = serializeClassText('abstract class C {}');
-    expect(cls.isAbstract, true);
-  }
-
-  test_class_alias_abstract() {
-    UnlinkedClass cls = serializeClassText(
-        'abstract class C = D with E; class D {} class E {}');
-    expect(cls.isAbstract, true);
-  }
-
-  test_class_alias_concrete() {
-    UnlinkedClass cls =
-        serializeClassText('class C = _D with _E; class _D {} class _E {}');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_class_alias_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C = D with E;
-
-class D {}
-class E {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_alias_flag() {
-    UnlinkedClass cls =
-        serializeClassText('class C = D with E; class D {} class E {}');
-    expect(cls.isMixinApplication, true);
-  }
-
-  test_class_alias_generic() {
-    serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
-  }
-
-  test_class_alias_mixin_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C = D with E, F;
-class D {}
-class E {}
-class F {}
-''');
-    expect(cls.mixins, hasLength(2));
-    checkTypeRef(cls.mixins[0], null, null, 'E');
-    checkTypeRef(cls.mixins[1], null, null, 'F');
-  }
-
-  test_class_alias_no_implicit_constructors() {
-    UnlinkedClass cls = serializeClassText('''
-class C = D with E;
-class D {
-  D.foo();
-  D.bar();
-}
-class E {}
-''');
-    expect(cls.executables, isEmpty);
-  }
-
-  test_class_alias_private() {
-    serializeClassText('class _C = _D with _E; class _D {} class _E {}', '_C');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_class_alias_reference_generic() {
-    UnlinkedTypeRef typeRef = serializeTypeText('C',
-        otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
-    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
-  }
-
-  test_class_alias_reference_generic_imported() {
-    addNamedSource(
-        '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}');
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
-        numTypeParameters: 2);
-  }
-
-  test_class_alias_supertype() {
-    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() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isAbstract, false);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_class_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-class C {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_documented_with_references() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs referring to [D] and [E]
- */
-class C {}
-
-class D {}
-class E {}''';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_documented_with_with_windows_line_endings() {
-    String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.documentationComment, isNotNull);
-    checkDocumentationComment(cls.documentationComment, text);
-  }
-
-  test_class_interface() {
-    UnlinkedClass cls = serializeClassText('''
-class C implements D {}
-class D {}
-''');
-    expect(cls.interfaces, hasLength(1));
-    checkTypeRef(cls.interfaces[0], null, null, 'D');
-  }
-
-  test_class_interface_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C implements D, E {}
-class D {}
-class E {}
-''');
-    expect(cls.interfaces, hasLength(2));
-    checkTypeRef(cls.interfaces[0], null, null, 'D');
-    checkTypeRef(cls.interfaces[1], null, null, 'E');
-  }
-
-  test_class_mixin() {
-    UnlinkedClass cls = serializeClassText('''
-class C extends Object with D {}
-class D {}
-''');
-    expect(cls.mixins, hasLength(1));
-    checkTypeRef(cls.mixins[0], null, null, 'D');
-  }
-
-  test_class_mixin_order() {
-    UnlinkedClass cls = serializeClassText('''
-class C extends Object with D, E {}
-class D {}
-class E {}
-''');
-    expect(cls.mixins, hasLength(2));
-    checkTypeRef(cls.mixins[0], null, null, 'D');
-    checkTypeRef(cls.mixins[1], null, null, 'E');
-  }
-
-  test_class_name() {
-    var classText = 'class C {}';
-    UnlinkedClass cls = serializeClassText(classText);
-    expect(cls.name, 'C');
-    expect(cls.nameOffset, classText.indexOf('C'));
-  }
-
-  test_class_no_flags() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isAbstract, false);
-    expect(cls.isMixinApplication, false);
-  }
-
-  test_class_no_interface() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.interfaces, isEmpty);
-  }
-
-  test_class_no_mixins() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.mixins, isEmpty);
-  }
-
-  test_class_no_type_param() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.typeParameters, isEmpty);
-  }
-
-  test_class_non_alias_flag() {
-    UnlinkedClass cls = serializeClassText('class C {}');
-    expect(cls.isMixinApplication, false);
-  }
-
-  test_class_private() {
-    serializeClassText('class _C {}', '_C');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_class_reference_generic() {
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
-    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
-  }
-
-  test_class_reference_generic_imported() {
-    addNamedSource('/lib.dart', 'class C<D, E> {}');
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
-        numTypeParameters: 2);
-  }
-
-  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() {
-    UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
-    expect(cls.typeParameters, hasLength(1));
-    expect(cls.typeParameters[0].name, 'T');
-    expect(cls.typeParameters[0].bound, isNotNull);
-    checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-  }
-
-  test_class_type_param_f_bound() {
-    UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
-    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_class_type_param_f_bound_self_ref() {
-    UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
-    UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_class_type_param_no_bound() {
-    String text = 'class C<T> {}';
-    UnlinkedClass cls = serializeClassText(text);
-    expect(cls.typeParameters, hasLength(1));
-    expect(cls.typeParameters[0].name, 'T');
-    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
-    expect(cls.typeParameters[0].bound, isNull);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_constructor() {
-    String text = 'class C { C(); }';
-    UnlinkedExecutable executable =
-        findExecutable('', executables: serializeClassText(text).executables);
-    expect(executable.kind, UnlinkedExecutableKind.constructor);
-    expect(executable.hasImplicitReturnType, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.nameOffset, text.indexOf('C();'));
-  }
-
-  test_constructor_anonymous() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.name, isEmpty);
-  }
-
-  test_constructor_const() {
-    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_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  C();
-}''';
-    UnlinkedExecutable executable = serializeClassText(text).executables[0];
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_constructor_external() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { external C(); }').executables);
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_constructor_factory() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables:
-            serializeClassText('class C { factory C() => null; }').executables);
-    expect(executable.isFactory, isTrue);
-  }
-
-  test_constructor_implicit() {
-    // Implicit constructors are not serialized.
-    UnlinkedExecutable executable = findExecutable(null,
-        executables: serializeClassText('class C { C(); }').executables,
-        failIfAbsent: false);
-    expect(executable, isNull);
-  }
-
-  test_constructor_initializing_formal() {
-    UnlinkedExecutable executable = findExecutable('',
-        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('',
-        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('',
-        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('',
-        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('',
-        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_parameters() {
-    UnlinkedExecutable executable = findExecutable('',
-        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_parameter() {
-    UnlinkedExecutable executable = findExecutable('',
-        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_parameter_order() {
-    UnlinkedExecutable executable = findExecutable('',
-        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');
-    expect(parameter.parameters[1].name, 'b');
-  }
-
-  test_constructor_initializing_formal_implicit_type() {
-    // Note: the implicit type of an initializing formal is the type of the
-    // field.
-    UnlinkedExecutable executable = findExecutable('',
-        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('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.name, 'x');
-  }
-
-  test_constructor_initializing_formal_named() {
-    // TODO(paulberry): also test default value
-    UnlinkedExecutable executable = findExecutable('',
-        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('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.isFunctionTyped, isFalse);
-  }
-
-  test_constructor_initializing_formal_positional() {
-    // TODO(paulberry): also test default value
-    UnlinkedExecutable executable = findExecutable('',
-        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('',
-        executables:
-            serializeClassText('class C { C(this.x); final x; }').executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.kind, UnlinkedParamKind.required);
-  }
-
-  test_constructor_initializing_formal_typedef() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText(
-                'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }')
-            .executables);
-    UnlinkedParam parameter = executable.parameters[0];
-    expect(parameter.parameters, hasLength(1));
-  }
-
-  test_constructor_named() {
-    String text = 'class C { C.foo(); }';
-    UnlinkedExecutable executable = findExecutable('foo',
-        executables: serializeClassText(text).executables);
-    expect(executable.name, 'foo');
-    expect(executable.nameOffset, text.indexOf('foo'));
-  }
-
-  test_constructor_non_const() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.isConst, isFalse);
-  }
-
-  test_constructor_non_factory() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.isFactory, isFalse);
-  }
-
-  test_constructor_return_type() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C { C(); }').executables);
-    expect(executable.returnType, isNull);
-  }
-
-  test_constructor_return_type_parameterized() {
-    UnlinkedExecutable executable = findExecutable('',
-        executables: serializeClassText('class C<T, U> { C(); }').executables);
-    expect(executable.returnType, isNull);
-  }
-
-  test_dependencies_export_none() {
-    // Exports are not listed as dependencies since no change to the exported
-    // file can change the summary of the exporting file.
-    // TODO(paulberry): this needs to change since the element model for a
-    // library includes its export namespace.
-    addNamedSource('/a.dart', 'library a; export "b.dart";');
-    addNamedSource('/b.dart', 'library b;');
-    serializeLibraryText('export "a.dart";');
-    checkLacksDependency(absUri('/a.dart'), 'a.dart');
-    checkLacksDependency(absUri('/b.dart'), 'b.dart');
-  }
-
-  test_dependencies_import_to_export() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b;');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'), 'a.dart');
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/b.dart'), 'b.dart');
-  }
-
-  test_dependencies_import_to_export_in_subdirs_absolute_export() {
-    addNamedSource('/a/a.dart',
-        'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "a/a.dart"; A a;');
-    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
-  }
-
-  test_dependencies_import_to_export_in_subdirs_absolute_import() {
-    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
-    checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
-  }
-
-  test_dependencies_import_to_export_in_subdirs_relative() {
-    addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
-    addNamedSource('/a/b/b.dart', 'library b;');
-    serializeLibraryText('import "a/a.dart"; A a;');
-    checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
-    // The main test library depends on b.dart, because names defined in
-    // b.dart are exported by a.dart.
-    checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
-  }
-
-  test_dependencies_import_to_export_loop() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b; export "a.dart";');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'), 'a.dart');
-    // Serialization should have been able to walk the transitive export
-    // dependencies to b.dart without going into an infinite loop.
-    checkHasDependency(absUri('/b.dart'), 'b.dart');
-  }
-
-  test_dependencies_import_to_export_transitive_closure() {
-    addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
-    addNamedSource('/b.dart', 'library b; export "c.dart";');
-    addNamedSource('/c.dart', 'library c;');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'), 'a.dart');
-    // The main test library depends on c.dart, because names defined in
-    // c.dart are exported by b.dart and then re-exported by a.dart.
-    checkHasDependency(absUri('/c.dart'), 'c.dart');
-  }
-
-  test_dependencies_import_transitive_closure() {
-    addNamedSource(
-        '/a.dart', 'library a; import "b.dart"; class A extends B {}');
-    addNamedSource('/b.dart', 'library b; class B {}');
-    serializeLibraryText('import "a.dart"; A a;');
-    checkHasDependency(absUri('/a.dart'), 'a.dart');
-    // The main test library doesn't depend on b.dart, because no change to
-    // b.dart can possibly affect the serialized element model for it.
-    checkLacksDependency(absUri('/b.dart'), 'b.dart');
-  }
-
-  test_dependencies_parts() {
-    addNamedSource(
-        '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
-    addNamedSource('/b.dart', 'part of a;');
-    addNamedSource('/c.dart', 'part of a;');
-    serializeLibraryText('import "a.dart"; A a;');
-    PrelinkedDependency dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
-    checkDependencyParts(
-        dep, [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
-  }
-
-  test_dependencies_parts_relative_to_importing_library() {
-    addNamedSource('/a/b.dart', 'export "c/d.dart";');
-    addNamedSource('/a/c/d.dart',
-        'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
-    addNamedSource('/a/c/e/f.dart', 'part of d;');
-    addNamedSource('/a/c/g/h.dart', 'part of d;');
-    serializeLibraryText('import "a/b.dart"; D d;');
-    PrelinkedDependency dep =
-        checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
-    checkDependencyParts(
-        dep,
-        [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
-        ['a/c/e/f.dart', 'a/c/g/h.dart']);
-  }
-
-  test_elements_in_part() {
-    addNamedSource(
-        '/part1.dart',
-        '''
-part of my.lib;
-
-class C {}
-enum E { v }
-var v;
-f() {}
-typedef F();
-''');
-    serializeLibraryText('library my.lib; part "part1.dart";');
-    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() {
-    String text = 'enum E { v1 }';
-    UnlinkedEnum e = serializeEnumText(text);
-    expect(e.name, 'E');
-    expect(e.nameOffset, text.indexOf('E'));
-    expect(e.values, hasLength(1));
-    expect(e.values[0].name, 'v1');
-    expect(e.values[0].nameOffset, text.indexOf('v1'));
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.classOrEnum);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_enum_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-enum E { v }''';
-    UnlinkedEnum enm = serializeEnumText(text);
-    expect(enm.documentationComment, isNotNull);
-    checkDocumentationComment(enm.documentationComment, text);
-  }
-
-  test_enum_order() {
-    UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
-    expect(e.values, hasLength(2));
-    expect(e.values[0].name, 'v1');
-    expect(e.values[1].name, 'v2');
-  }
-
-  test_enum_private() {
-    serializeEnumText('enum _E { v1 }', '_E');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_abstract() {
-    UnlinkedExecutable executable =
-        serializeClassText('abstract class C { f(); }').executables[0];
-    expect(executable.isAbstract, isTrue);
-  }
-
-  test_executable_concrete() {
-    UnlinkedExecutable executable =
-        serializeClassText('abstract class C { f() {} }').executables[0];
-    expect(executable.isAbstract, isFalse);
-  }
-
-  test_executable_function() {
-    String text = '  f() {}';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
-    expect(executable.hasImplicitReturnType, isTrue);
-    checkDynamicTypeRef(executable.returnType);
-    expect(executable.isExternal, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.other);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  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_function_private() {
-    serializeExecutableText('_f() {}', '_f');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_getter() {
-    String text = 'int get f => 1;';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.kind, UnlinkedExecutableKind.getter);
-    expect(executable.hasImplicitReturnType, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(findVariable('f'), isNull);
-    expect(findExecutable('f='), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.other);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
-  }
-
-  test_executable_getter_external() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('external int get f;');
-    expect(executable.isExternal, isTrue);
-  }
-
-  test_executable_getter_private() {
-    serializeExecutableText('int get _f => 1;', '_f');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_getter_type() {
-    UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
-    checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
-    expect(executable.parameters, isEmpty);
-  }
-
-  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',
-        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', executables: cls.executables, failIfAbsent: true);
-    expect(executable.kind, UnlinkedExecutableKind.getter);
-    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=', executables: cls.executables, failIfAbsent: true);
-    expect(executable.kind, UnlinkedExecutableKind.setter);
-    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, isTrue);
-    checkDynamicTypeRef(executable.returnType);
-  }
-
-  test_executable_name() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.name, 'f');
-  }
-
-  test_executable_no_flags() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.isAbstract, isFalse);
-    expect(executable.isConst, isFalse);
-    expect(executable.isFactory, isFalse);
-    expect(executable.isStatic, isFalse);
-  }
-
-  test_executable_non_static() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { f() {} }').executables[0];
-    expect(executable.isStatic, isFalse);
-  }
-
-  test_executable_non_static_top_level() {
-    // Top level executables are considered non-static.
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    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() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
-    expect(executable.parameters[0].parameters, hasLength(1));
-  }
-
-  test_executable_param_function_typed_param_none() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
-    expect(executable.parameters[0].parameters, isEmpty);
-  }
-
-  test_executable_param_function_typed_param_order() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
-    expect(executable.parameters[0].parameters, hasLength(2));
-    expect(executable.parameters[0].parameters[0].name, 'x');
-    expect(executable.parameters[0].parameters[1].name, 'y');
-  }
-
-  test_executable_param_function_typed_return_type() {
-    UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
-    checkTypeRef(
-        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
-  }
-
-  test_executable_param_function_typed_return_type_implicit() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
-    checkDynamicTypeRef(executable.parameters[0].type);
-  }
-
-  test_executable_param_function_typed_return_type_void() {
-    UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
-    expect(executable.parameters[0].type, isNull);
-  }
-
-  test_executable_param_kind_named() {
-    UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
-    expect(executable.parameters[0].kind, UnlinkedParamKind.named);
-  }
-
-  test_executable_param_kind_positional() {
-    UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
-    expect(executable.parameters[0].kind, UnlinkedParamKind.positional);
-  }
-
-  test_executable_param_kind_required() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    expect(executable.parameters[0].kind, UnlinkedParamKind.required);
-  }
-
-  test_executable_param_name() {
-    String text = 'f(x) {}';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.parameters, hasLength(1));
-    expect(executable.parameters[0].name, 'x');
-    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
-  }
-
-  test_executable_param_no_flags() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
-    expect(executable.parameters[0].isFunctionTyped, isFalse);
-    expect(executable.parameters[0].isInitializingFormal, isFalse);
-  }
-
-  test_executable_param_non_function_typed() {
-    UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
-    expect(executable.parameters[0].isFunctionTyped, isFalse);
-  }
-
-  test_executable_param_none() {
-    UnlinkedExecutable executable = serializeExecutableText('f() {}');
-    expect(executable.parameters, isEmpty);
-  }
-
-  test_executable_param_order() {
-    UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
-    expect(executable.parameters, hasLength(2));
-    expect(executable.parameters[0].name, 'x');
-    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() {
-    UnlinkedExecutable executable = serializeExecutableText('void f() {}');
-    expect(executable.returnType, isNull);
-  }
-
-  test_executable_setter() {
-    String text = 'void set f(value) {}';
-    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
-    expect(executable.kind, UnlinkedExecutableKind.setter);
-    expect(executable.hasImplicitReturnType, isFalse);
-    expect(executable.isExternal, isFalse);
-    expect(executable.nameOffset, text.indexOf('f'));
-    expect(findVariable('f'), isNull);
-    expect(findExecutable('f'), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.other);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f=');
-  }
-
-  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=');
-    expect(executable.hasImplicitReturnType, isTrue);
-    checkDynamicTypeRef(executable.returnType);
-  }
-
-  test_executable_setter_private() {
-    serializeExecutableText('void set _f(value) {}', '_f=');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_executable_setter_type() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('void set f(int value) {}', 'f=');
-    expect(executable.returnType, isNull);
-    expect(executable.parameters, hasLength(1));
-    expect(executable.parameters[0].name, 'value');
-    checkTypeRef(
-        executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
-  }
-
-  test_executable_static() {
-    UnlinkedExecutable executable =
-        serializeClassText('class C { static f() {} }').executables[0];
-    expect(executable.isStatic, isTrue);
-  }
-
-  test_executable_type_param_f_bound_function() {
-    UnlinkedExecutable ex =
-        serializeExecutableText('void f<T, U extends List<T>>() {}');
-    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_executable_type_param_f_bound_method() {
-    UnlinkedExecutable ex =
-        serializeMethodText('void f<T, U extends List<T>>() {}');
-    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 2);
-  }
-
-  test_executable_type_param_f_bound_self_ref_function() {
-    UnlinkedExecutable ex =
-        serializeExecutableText('void f<T, U extends List<U>>() {}');
-    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_executable_type_param_f_bound_self_ref_method() {
-    UnlinkedExecutable ex =
-        serializeMethodText('void f<T, U extends List<U>>() {}');
-    UnlinkedTypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
-    checkParamTypeRef(typeArgument, 1);
-  }
-
-  test_executable_type_param_in_parameter_function() {
-    UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
-    checkParamTypeRef(ex.parameters[0].type, 1);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_executable_type_param_in_parameter_method() {
-    UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
-    checkParamTypeRef(ex.parameters[0].type, 1);
-  }
-
-  test_executable_type_param_in_return_type_function() {
-    UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;');
-    checkParamTypeRef(ex.returnType, 1);
-  }
-
-  test_executable_type_param_in_return_type_method() {
-    UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
-    checkParamTypeRef(ex.returnType, 1);
-  }
-
-  test_export_hide_order() {
-    serializeLibraryText('export "dart:async" hide Future, Stream;');
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(
-        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
-        isEmpty);
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
-        hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0],
-        'Future');
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
-        'Stream');
-  }
-
-  test_export_no_combinators() {
-    serializeLibraryText('export "dart:async";');
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
-  }
-
-  test_export_offset() {
-    String libraryText = '    export "dart:async";';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].exports[0].uriOffset,
-        libraryText.indexOf('"dart:async"'));
-    expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
-    expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
-  }
-
-  test_export_show_order() {
-    serializeLibraryText('export "dart:async" show Future, Stream;');
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(
-        unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
-        hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
-        isEmpty);
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0],
-        'Future');
-    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
-        'Stream');
-  }
-
-  test_export_uri() {
-    addNamedSource('/a.dart', 'library my.lib;');
-    String uriString = '"a.dart"';
-    String libraryText = 'export $uriString;';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'a.dart');
-  }
-
-  test_field() {
-    UnlinkedClass cls = serializeClassText('class C { int i; }');
-    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_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  var v;
-}''';
-    UnlinkedVariable variable = serializeClassText(text).fields[0];
-    expect(variable.documentationComment, isNotNull);
-    checkDocumentationComment(variable.documentationComment, text);
-  }
-
-  test_field_final() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { final int i = 0; }').fields[0];
-    expect(variable.isFinal, isTrue);
-  }
-
-  test_field_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static int i; }').fields[0];
-    expect(variable.isStatic, isTrue);
-  }
-
-  test_function_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-f() {}''';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_generic_method_in_generic_class() {
-    UnlinkedClass cls = serializeClassText(
-        'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
-    List<UnlinkedParam> params = cls.executables[0].parameters;
-    checkParamTypeRef(params[0].type, 4);
-    checkParamTypeRef(params[1].type, 3);
-    checkParamTypeRef(params[2].type, 2);
-    checkParamTypeRef(params[3].type, 1);
-  }
-
-  test_getter_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-get f => null;''';
-    UnlinkedExecutable executable = serializeExecutableText(text);
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_import_deferred() {
-    serializeLibraryText(
-        'import "dart:async" deferred as a; main() { print(a.Future); }');
-    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(unlinkedUnits[0].imports, hasLength(2));
-    checkDependency(
-        prelinked.importDependencies[0], 'dart:async', 'dart:async');
-  }
-
-  test_import_explicit() {
-    serializeLibraryText('import "dart:core"; int i;');
-    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(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));
-    expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
-    expect(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(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].uriOffset, 0);
-    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
-    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(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
-  }
-
-  test_import_no_flags() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    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(unlinkedUnits[0].imports[0].isDeferred, isFalse);
-  }
-
-  test_import_of_file_with_missing_part() {
-    // Other references in foo.dart should be resolved even though foo.dart's
-    // part declaration for bar.dart refers to a non-existent file.
-    allowMissingFiles = true;
-    addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
-    serializeLibraryText('import "foo.dart"; C x;');
-    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
-  }
-
-  test_import_of_missing_export() {
-    // Other references in foo.dart should be resolved even though foo.dart's
-    // re-export of bar.dart refers to a non-existent file.
-    allowMissingFiles = true;
-    addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
-    serializeLibraryText('import "foo.dart"; C x;');
-    checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
-  }
-
-  test_import_offset() {
-    String libraryText = '    import "dart:async"; Future x;';
-    serializeLibraryText(libraryText);
-    expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
-    expect(unlinkedUnits[0].imports[0].uriOffset,
-        libraryText.indexOf('"dart:async"'));
-    expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
-  }
-
-  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(unlinkedUnits[0].imports, hasLength(2));
-    checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
-    expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
-  }
-
-  test_import_prefix_none() {
-    serializeLibraryText('import "dart:async"; Future x;');
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].prefixReference, 0);
-  }
-
-  test_import_prefix_not_in_public_namespace() {
-    serializeLibraryText('import "dart:async" as a; a.Future v;');
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v');
-    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v=');
-  }
-
-  test_import_prefix_reference() {
-    UnlinkedVariable variable =
-        serializeVariableText('import "dart:async" as a; a.Future v;');
-    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
-        expectedPrefix: 'a', numTypeParameters: 1);
-  }
-
-  test_import_prefixes_take_precedence_over_imported_names() {
-    addNamedSource('/a.dart', 'class b {} class A');
-    addNamedSource('/b.dart', 'class Cls {}');
-    addNamedSource('/c.dart', 'class Cls {}');
-    addNamedSource('/d.dart', 'class c {} class D');
-    serializeLibraryText('''
-import 'a.dart';
-import 'b.dart' as b;
-import 'c.dart' as c;
-import 'd.dart';
-A aCls;
-b.Cls bCls;
-c.Cls cCls;
-D dCls;
-''');
-    checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A');
-    checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls',
-        expectedPrefix: 'b');
-    checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls',
-        expectedPrefix: 'c');
-    checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D');
-  }
-
-  test_import_reference() {
-    UnlinkedVariable variable =
-        serializeVariableText('import "dart:async"; Future v;');
-    checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
-        numTypeParameters: 1);
-  }
-
-  test_import_reference_merged_no_prefix() {
-    serializeLibraryText('''
-import "dart:async" show Future;
-import "dart:async" show Stream;
-
-Future f;
-Stream s;
-''');
-    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
-        numTypeParameters: 1);
-    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
-        numTypeParameters: 1);
-  }
-
-  test_import_reference_merged_prefixed() {
-    serializeLibraryText('''
-import "dart:async" as a show Future;
-import "dart:async" as a show Stream;
-
-a.Future f;
-a.Stream s;
-''');
-    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
-        expectedPrefix: 'a', numTypeParameters: 1);
-    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
-        expectedPrefix: 'a', numTypeParameters: 1);
-  }
-
-  test_import_reference_merged_prefixed_separate_libraries() {
-    addNamedSource('/a.dart', 'class A {}');
-    addNamedSource('/b.dart', 'class B {}');
-    serializeLibraryText('''
-import 'a.dart' as p;
-import 'b.dart' as p;
-
-p.A a;
-p.B b;
-''');
-    checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A',
-        expectedPrefix: 'p');
-    checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B',
-        expectedPrefix: 'p');
-  }
-
-  test_import_show_order() {
-    String libraryText =
-        'import "dart:async" show Future, Stream; Future x; Stream y;';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    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);
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
-    expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
-  }
-
-  test_import_uri() {
-    String uriString = '"dart:async"';
-    String libraryText = 'import $uriString; Future x;';
-    serializeLibraryText(libraryText);
-    // Second import is the implicit import of dart:core
-    expect(unlinkedUnits[0].imports, hasLength(2));
-    expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
-  }
-
-  test_library_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-library foo;''';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
-    checkDocumentationComment(
-        unlinkedUnits[0].libraryDocumentationComment, text);
-  }
-
-  test_library_name_with_spaces() {
-    String text = 'library foo . bar ;';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryName, 'foo.bar');
-    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
-    expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
-  }
-
-  test_library_named() {
-    String text = 'library foo.bar;';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].libraryName, 'foo.bar');
-    expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
-    expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
-  }
-
-  test_library_unnamed() {
-    serializeLibraryText('');
-    expect(unlinkedUnits[0].libraryName, isEmpty);
-    expect(unlinkedUnits[0].libraryNameOffset, 0);
-    expect(unlinkedUnits[0].libraryNameLength, 0);
-  }
-
-  test_library_with_missing_part() {
-    // References to other parts should still be resolved.
-    allowMissingFiles = true;
-    addNamedSource('/bar.dart', 'part of my.lib; class C {}');
-    serializeLibraryText(
-        'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
-        allowErrors: true);
-    checkTypeRef(findVariable('c').type, null, null, 'C',
-        expectedTargetUnit: 2);
-  }
-
-  test_local_names_take_precedence_over_imported_names() {
-    addNamedSource('/a.dart', 'class C {} class D {}');
-    serializeLibraryText('''
-import 'a.dart';
-class C {}
-C c;
-D d;''');
-    checkTypeRef(findVariable('c').type, null, null, 'C');
-    checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D');
-  }
-
-  test_method_documented() {
-    String text = '''
-class C {
-  /**
-   * Docs
-   */
-  f() {}
-}''';
-    UnlinkedExecutable executable = serializeClassText(text).executables[0];
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_part_declaration() {
-    addNamedSource('/a.dart', 'part of my.lib;');
-    String text = 'library my.lib; part "a.dart"; // <-part';
-    serializeLibraryText(text);
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
-    expect(unlinkedUnits[0].parts, hasLength(1));
-    expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
-    expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
-  }
-
-  test_parts_defining_compilation_unit() {
-    serializeLibraryText('');
-    expect(prelinked.units, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts, isEmpty);
-  }
-
-  test_parts_included() {
-    addNamedSource('/part1.dart', 'part of my.lib;');
-    String partString = '"part1.dart"';
-    String libraryText = 'library my.lib; part $partString;';
-    serializeLibraryText(libraryText);
-    expect(prelinked.units, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
-  }
-
-  test_public_namespace_of_part() {
-    addNamedSource('/a.dart', 'part of foo; class C {}');
-    serializeLibraryText('library foo; part "a.dart";');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-    expect(unlinkedUnits[1].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
-  }
-
-  test_setter_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-void set f(value) {}''';
-    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
-    expect(executable.documentationComment, isNotNull);
-    checkDocumentationComment(executable.documentationComment, text);
-  }
-
-  test_type_arguments_explicit() {
-    UnlinkedTypeRef typeRef = serializeTypeText('List<int>');
-    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, hasLength(1));
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
-  }
-
-  test_type_arguments_explicit_dynamic() {
-    UnlinkedTypeRef typeRef = serializeTypeText('List<dynamic>');
-    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
-  }
-
-  test_type_arguments_explicit_dynamic_typedef() {
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
-        expectedKind: PrelinkedReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
-  }
-
-  test_type_arguments_explicit_typedef() {
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
-        expectedKind: PrelinkedReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, hasLength(1));
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
-  }
-
-  test_type_arguments_implicit() {
-    UnlinkedTypeRef typeRef = serializeTypeText('List');
-    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
-  }
-
-  test_type_arguments_implicit_typedef() {
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
-    checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
-        expectedKind: PrelinkedReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
-  }
-
-  test_type_arguments_order() {
-    UnlinkedTypeRef typeRef = serializeTypeText('Map<int, Object>');
-    checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    expect(typeRef.typeArguments, hasLength(2));
-    checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
-    checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
-  }
-
-  test_type_dynamic() {
-    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_from_part_withPrefix() {
-    addNamedSource('/a.dart', 'class C {}');
-    addNamedSource('/p.dart', 'part of foo; a.C v;');
-    serializeLibraryText(
-        'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
-        allowErrors: true);
-    checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
-        absUri('/a.dart'), 'a.dart', 'C',
-        expectedPrefix: 'a',
-        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', variables: cls.fields, failIfAbsent: true).type;
-      checkParamTypeRef(typeRef, 2);
-    }
-    {
-      UnlinkedTypeRef typeRef =
-          findVariable('u', variables: cls.fields, failIfAbsent: true).type;
-      checkParamTypeRef(typeRef, 1);
-    }
-  }
-
-  test_type_reference_to_import_of_export() {
-    addNamedSource('/a.dart', 'library a; export "b.dart";');
-    addNamedSource('/b.dart', 'library b; class C {}');
-    checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
-        absUri('/b.dart'), 'b.dart', 'C');
-  }
-
-  test_type_reference_to_import_of_export_via_prefix() {
-    addNamedSource('/a.dart', 'library a; export "b.dart";');
-    addNamedSource('/b.dart', 'library b; class C {}');
-    checkTypeRef(
-        serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
-        absUri('/b.dart'),
-        'b.dart',
-        'C',
-        expectedPrefix: 'p');
-  }
-
-  test_type_reference_to_imported_part() {
-    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
-    addNamedSource('/b.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'library my.lib; import "a.dart";'),
-        absUri('/a.dart'),
-        'a.dart',
-        'C',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_imported_part_with_prefix() {
-    addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
-    addNamedSource('/b.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('p.C',
-            otherDeclarations: 'library my.lib; import "a.dart" as p;'),
-        absUri('/a.dart'),
-        'a.dart',
-        'C',
-        expectedPrefix: 'p',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_internal_class() {
-    checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null,
-        null, 'C');
-  }
-
-  test_type_reference_to_internal_class_alias() {
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'class C = D with E; class D {} class E {}'),
-        null,
-        null,
-        'C');
-  }
-
-  test_type_reference_to_internal_enum() {
-    checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
-        null, null, 'E');
-  }
-
-  test_type_reference_to_local_part() {
-    addNamedSource('/a.dart', 'part of my.lib; class C {}');
-    checkTypeRef(
-        serializeTypeText('C',
-            otherDeclarations: 'library my.lib; part "a.dart";'),
-        null,
-        null,
-        'C',
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_part() {
-    addNamedSource('/a.dart', 'part of foo; class C { C(); }');
-    serializeLibraryText('library foo; part "a.dart"; C c;');
-    checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C',
-        expectedKind: PrelinkedReferenceKind.classOrEnum,
-        expectedTargetUnit: 1);
-  }
-
-  test_type_reference_to_typedef() {
-    checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
-        null, null, 'F',
-        expectedKind: PrelinkedReferenceKind.typedef);
-  }
-
-  test_type_unit_counts_unreferenced_units() {
-    addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
-    addNamedSource('/b.dart', 'part of a;');
-    addNamedSource('/c.dart', 'part of a; class C {}');
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('C', otherDeclarations: 'import "a.dart";');
-    // 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',
-        expectedTargetUnit: 2);
-  }
-
-  test_type_unresolved() {
-    UnlinkedTypeRef typeRef = serializeTypeText('Foo', allowErrors: true);
-    checkUnresolvedTypeRef(typeRef, null, 'Foo');
-  }
-
-  test_typedef_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-typedef F();''';
-    UnlinkedTypedef typedef = serializeTypedefText(text);
-    expect(typedef.documentationComment, isNotNull);
-    checkDocumentationComment(typedef.documentationComment, text);
-  }
-
-  test_typedef_name() {
-    String text = 'typedef F();';
-    UnlinkedTypedef type = serializeTypedefText(text);
-    expect(type.name, 'F');
-    expect(type.nameOffset, text.indexOf('F'));
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.typedef);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-  }
-
-  test_typedef_param_none() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
-    expect(type.parameters, isEmpty);
-  }
-
-  test_typedef_param_order() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
-    expect(type.parameters, hasLength(2));
-    expect(type.parameters[0].name, 'x');
-    expect(type.parameters[1].name, 'y');
-  }
-
-  test_typedef_private() {
-    serializeTypedefText('typedef _F();', '_F');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-
-  test_typedef_reference_generic() {
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
-    checkTypeRef(typeRef, null, null, 'F',
-        numTypeParameters: 2, expectedKind: PrelinkedReferenceKind.typedef);
-  }
-
-  test_typedef_reference_generic_imported() {
-    addNamedSource('/lib.dart', 'typedef void F<A, B>();');
-    UnlinkedTypeRef typeRef =
-        serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
-    checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
-        numTypeParameters: 2, expectedKind: PrelinkedReferenceKind.typedef);
-  }
-
-  test_typedef_return_type_explicit() {
-    UnlinkedTypedef type = serializeTypedefText('typedef int F();');
-    checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int');
-  }
-
-  test_typedef_type_param_in_parameter() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
-    checkParamTypeRef(type.parameters[0].type, 1);
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
-  }
-
-  test_typedef_type_param_in_return_type() {
-    UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
-    checkParamTypeRef(type.returnType, 1);
-  }
-
-  test_typedef_type_param_none() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F();');
-    expect(type.typeParameters, isEmpty);
-  }
-
-  test_typedef_type_param_order() {
-    UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
-    expect(type.typeParameters, hasLength(2));
-    expect(type.typeParameters[0].name, 'T');
-    expect(type.typeParameters[1].name, 'U');
-  }
-
-  test_variable() {
-    String text = 'int i;';
-    UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
-    expect(v.nameOffset, text.indexOf('i;'));
-    expect(findExecutable('i'), isNull);
-    expect(findExecutable('i='), isNull);
-    expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
-    expect(unlinkedUnits[0].publicNamespace.names[0].kind,
-        PrelinkedReferenceKind.other);
-    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
-    expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
-    expect(unlinkedUnits[0].publicNamespace.names[1].kind,
-        PrelinkedReferenceKind.other);
-    expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
-    expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
-  }
-
-  test_variable_const() {
-    UnlinkedVariable variable =
-        serializeVariableText('const int i = 0;', variableName: 'i');
-    expect(variable.isConst, isTrue);
-  }
-
-  test_variable_documented() {
-    String text = '''
-// Extra comment so doc comment offset != 0
-/**
- * Docs
- */
-var v;''';
-    UnlinkedVariable variable = serializeVariableText(text);
-    expect(variable.documentationComment, isNotNull);
-    checkDocumentationComment(variable.documentationComment, text);
-  }
-
-  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');
-    expect(variable.isFinal, isTrue);
-  }
-
-  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');
-  }
-
-  test_variable_no_flags() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isStatic, isFalse);
-    expect(variable.isConst, isFalse);
-    expect(variable.isFinal, isFalse);
-  }
-
-  test_variable_non_const() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i = 0;', variableName: 'i');
-    expect(variable.isConst, isFalse);
-  }
-
-  test_variable_non_final() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isFinal, isFalse);
-  }
-
-  test_variable_non_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { int i; }').fields[0];
-    expect(variable.isStatic, isFalse);
-  }
-
-  test_variable_non_static_top_level() {
-    // Top level variables are considered non-static.
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    expect(variable.isStatic, isFalse);
-  }
-
-  test_variable_static() {
-    UnlinkedVariable variable =
-        serializeClassText('class C { static int i; }').fields[0];
-    expect(variable.isStatic, isTrue);
-  }
-
-  test_variable_type() {
-    UnlinkedVariable variable =
-        serializeVariableText('int i;', variableName: 'i');
-    checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int');
-  }
-
-  test_varible_private() {
-    serializeVariableText('int _i;', variableName: '_i');
-    expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
-  }
-}
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 252c95f..d24342f 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -9,9 +9,12 @@
 import '../../utils.dart';
 import 'flat_buffers_test.dart' as flat_buffers_test;
 import 'name_filter_test.dart' as name_filter_test;
+import 'prelinker_test.dart' as prelinker_test;
+import 'resynthesize_strong_test.dart' as resynthesize_strong_test;
 import 'resynthesize_test.dart' as resynthesize_test;
-import 'summary_sdk_test.dart' as summary_sdk_test;
-import 'summary_test.dart' as summary_test;
+import 'summarize_ast_test.dart' as summarize_ast_test;
+import 'summarize_elements_strong_test.dart' as summarize_elements_strong_test;
+import 'summarize_elements_test.dart' as summarize_elements_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -19,8 +22,11 @@
   group('summary tests', () {
     flat_buffers_test.main();
     name_filter_test.main();
+    prelinker_test.main();
+    resynthesize_strong_test.main();
     resynthesize_test.main();
-    summary_sdk_test.main();
-    summary_test.main();
+    summarize_ast_test.main();
+    summarize_elements_strong_test.main();
+    summarize_elements_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 23930d8..e351c39 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4,14 +4,15 @@
 
 library analyzer.test.src.task.dart_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/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/engine.dart'
-    show AnalysisOptionsImpl, CacheState;
+    show AnalysisOptions, AnalysisOptionsImpl, CacheState;
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -31,6 +32,7 @@
 import '../../reflective_tests.dart';
 import '../../utils.dart';
 import '../context/abstract_context.dart';
+import '../mock_sdk.dart';
 
 main() {
   initializeTestEnvironment();
@@ -42,6 +44,7 @@
   runReflectiveTests(BuildPublicNamespaceTaskTest);
   runReflectiveTests(BuildSourceExportClosureTaskTest);
   runReflectiveTests(BuildTypeProviderTaskTest);
+  runReflectiveTests(BuildTypeProviderTaskTest_noAsync);
   runReflectiveTests(ComputeConstantDependenciesTaskTest);
   runReflectiveTests(ComputeConstantValueTaskTest);
   runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
@@ -1005,6 +1008,32 @@
 }
 
 @reflectiveTest
+class BuildTypeProviderTaskTest_noAsync extends _AbstractDartTaskTest {
+  void prepareAnalysisContext([AnalysisOptions options]) {
+    AnalysisOptionsImpl newOptions = new AnalysisOptionsImpl();
+    newOptions.enableAsync = false;
+    super.prepareAnalysisContext(newOptions);
+  }
+
+  void setUp() {
+    sdk = new MockSdk(dartAsync: false);
+    super.setUp();
+  }
+
+  test_perform_noAsync() {
+    expect(context, isNotNull);
+    computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
+        matcher: isBuildTypeProviderTask);
+    // validate
+    TypeProvider typeProvider = outputs[TYPE_PROVIDER];
+    expect(typeProvider, isNotNull);
+    expect(typeProvider.boolType, isNotNull);
+    expect(typeProvider.intType, isNotNull);
+    expect(typeProvider.futureType, isNotNull);
+  }
+}
+
+@reflectiveTest
 class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest {
   Annotation findClassAnnotation(CompilationUnit unit, String className) {
     for (CompilationUnitMember member in unit.declarations) {
@@ -2993,6 +3022,40 @@
     expect(outputs[UNITS], hasLength(1));
   }
 
+  test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
+    // Parse "lib.dart" to let the context know that "test.dart" is included.
+    computeResult(
+        newSource(
+            '/lib.dart',
+            r'''
+library lib;
+part 'test.dart';
+'''),
+        PARSED_UNIT);
+    // If there are no the "part of" directive, then it is not a part.
+    _performParseTask('');
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+  }
+
+  test_perform_computeSourceKind_noDirectives_noContainingLibrary() {
+    _performParseTask('');
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+  }
+
+  test_perform_doesNotExist() {
+    _performParseTask(null);
+    expect(outputs, hasLength(9));
+    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
+    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
+    expect(outputs[INCLUDED_PARTS], hasLength(0));
+    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
+    expect(outputs[PARSE_ERRORS], hasLength(0));
+    expect(outputs[PARSED_UNIT], isNotNull);
+    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(1));
+  }
+
   test_perform_enableAsync_false() {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.enableAsync = false;
@@ -3028,40 +3091,6 @@
     expect(outputs[UNITS], hasLength(1));
   }
 
-  test_perform_computeSourceKind_noDirectives_hasContainingLibrary() {
-    // Parse "lib.dart" to let the context know that "test.dart" is included.
-    computeResult(
-        newSource(
-            '/lib.dart',
-            r'''
-library lib;
-part 'test.dart';
-'''),
-        PARSED_UNIT);
-    // If there are no the "part of" directive, then it is not a part.
-    _performParseTask('');
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-  }
-
-  test_perform_computeSourceKind_noDirectives_noContainingLibrary() {
-    _performParseTask('');
-    expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
-  }
-
-  test_perform_doesNotExist() {
-    _performParseTask(null);
-    expect(outputs, hasLength(9));
-    expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
-    expect(outputs[INCLUDED_PARTS], hasLength(0));
-    expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
-    expect(outputs[PARSE_ERRORS], hasLength(0));
-    expect(outputs[PARSED_UNIT], isNotNull);
-    expect(outputs[SOURCE_KIND], SourceKind.UNKNOWN);
-    expect(outputs[UNITS], hasLength(1));
-  }
-
   test_perform_flushTokenStream() {
     _performParseTask(r'''
 class Test {}
@@ -3133,7 +3162,11 @@
   }
 
   void _performParseTask(String content) {
-    source = newSource('/test.dart', content);
+    if (content == null) {
+      source = resourceProvider.getFile('/test.dart').createSource();
+    } else {
+      source = newSource('/test.dart', content);
+    }
     computeResult(source, PARSED_UNIT, matcher: isParseDartTask);
   }
 
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index 7938cc9..315e061 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -4,8 +4,8 @@
 
 library analyzer.test.src.task.dart_work_manager_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show
         AnalysisErrorInfo,
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 114a452..8ef225a 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/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/generated/ast.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/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index 4db1ee2..a798472 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -103,7 +103,7 @@
 
 @reflectiveTest
 class TaskDescriptorImplTest extends EngineTestCase {
-  test_create() {
+  test_create_noOptionalArgs() {
     String name = 'name';
     BuildTask buildTask = (context, target) {};
     CreateTaskInputs createTaskInputs = (target) {};
@@ -114,12 +114,30 @@
     expect(descriptor.name, name);
     expect(descriptor.buildTask, equals(buildTask));
     expect(descriptor.createTaskInputs, equals(createTaskInputs));
+    expect(descriptor.suitabilityFor(null), TaskSuitability.LOWEST);
+    expect(descriptor.results, results);
+  }
+
+  test_create_withIsAppropriateFor() {
+    String name = 'name';
+    BuildTask buildTask = (context, target) {};
+    CreateTaskInputs createTaskInputs = (target) {};
+    List<ResultDescriptor> results = <ResultDescriptor>[];
+    SuitabilityFor suitabilityFor = (target) => TaskSuitability.NONE;
+    TaskDescriptorImpl descriptor = new TaskDescriptorImpl(
+        name, buildTask, createTaskInputs, results,
+        suitabilityFor: suitabilityFor);
+    expect(descriptor, isNotNull);
+    expect(descriptor.name, name);
+    expect(descriptor.buildTask, equals(buildTask));
+    expect(descriptor.createTaskInputs, equals(createTaskInputs));
+    expect(descriptor.suitabilityFor(null), TaskSuitability.NONE);
     expect(descriptor.results, results);
   }
 
   test_createTask() {
-    BuildTask buildTask = (context, target) =>
-        new TestAnalysisTask(context, target);
+    BuildTask buildTask =
+        (context, target) => new TestAnalysisTask(context, target);
     CreateTaskInputs createTaskInputs = (target) {};
     List<ResultDescriptor> results = <ResultDescriptor>[];
     TaskDescriptorImpl descriptor =
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 55b73a8..bb8216a 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -964,6 +964,16 @@
    '''
   });
 
+  testChecker('Function subtyping: uninferred closure', {
+    '/main.dart': '''
+      typedef num Num2Num(num x);
+      void main() {
+        Num2Num g = /*info:INFERRED_TYPE_CLOSURE,severe:STATIC_TYPE_ERROR*/(int x) { return x; };
+        print(g(42));
+      }
+    '''
+  });
+
   testChecker('Relaxed casts', {
     '/main.dart': '''
 
@@ -1141,6 +1151,21 @@
        '''
   });
 
+  testChecker('factory constructor downcast', {
+    '/main.dart': r'''
+        class Animal {
+          Animal();
+          factory Animal.cat() => return new Cat();
+        }
+
+        class Cat extends Animal {}
+
+        void main() {
+          Cat c = /*info:ASSIGNMENT_CAST*/new Animal.cat();
+          c = /*severe:STATIC_TYPE_ERROR*/new Animal();
+        }'''
+  });
+
   testChecker('field/field override', {
     '/main.dart': '''
           class A {}
@@ -1389,7 +1414,51 @@
           class DerivedFuture4<A> extends Future<A> {
             /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
           }
-       '''
+      '''
+  });
+
+  testChecker('generic function wrong number of arguments', {
+      '/main.dart': r'''
+          /*=T*/ foo/*<T>*/(/*=T*/ x, /*=T*/ y) => x;
+          /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
+
+          main() {
+            // resolving thses shouldn't crash.
+            foo(1, 2, 3);
+            String x = foo('1', '2', '3');
+            foo(1);
+            String x = foo('1');
+            x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3);
+            x = /*severe:STATIC_TYPE_ERROR*/foo(1);
+
+            // named arguments
+            bar(y: 1, x: 2, z: 3);
+            String x = bar(z: '1', x: '2', y: '3');
+            bar(y: 1);
+            x = bar(x: '1', z: 42);
+            x = /*severe:STATIC_TYPE_ERROR*/bar(y: 1, x: 2, z: 3);
+            x = /*severe:STATIC_TYPE_ERROR*/bar(x: 1);
+          }
+      '''
+  });
+
+  testChecker('type promotion from dynamic', {
+    '/main.dart': r'''
+          f() {
+            dynamic x;
+            if (x is int) {
+              int y = x;
+              String z = /*severe:STATIC_TYPE_ERROR*/x;
+            }
+          }
+          g() {
+            Object x;
+            if (x is int) {
+              int y = x;
+              String z = /*severe:STATIC_TYPE_ERROR*/x;
+            }
+          }
+    '''
   });
 
   testChecker('unary operators', {
@@ -1642,6 +1711,15 @@
         '''
   });
 
+  testChecker('loadLibrary', {
+    '/lib1.dart': '''library lib1;''',
+    '/main.dart': r'''
+        import 'lib1.dart' deferred as lib1;
+        main() {
+          Future f = lib1.loadLibrary();
+        }'''
+  });
+
   group('invalid overrides', () {
     testChecker('child override', {
       '/main.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 0141e38..f386377 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,12 @@
 // package:dev_compiler's tests
 library analyzer.test.src.task.strong.strong_test_helper;
 
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
 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/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -95,6 +96,7 @@
         }
         ''',
   'dart:async': '''
+        library dart.async;
         class Future<T> {
           Future(computation()) {}
           Future.value(T t) {}
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index 6859d48..097d5d4 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -4,9 +4,9 @@
 
 library analyzer.test.src.task.strong_mode_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index 41e568e..956a8e5 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -21,6 +21,7 @@
 import 'options_test.dart' as options_test;
 import 'options_work_manager_test.dart' as options_work_manager_test;
 import 'strong_mode_test.dart' as strong_mode_test;
+import 'yaml_test.dart' as yaml_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -39,5 +40,6 @@
     options_test.main();
     options_work_manager_test.main();
     strong_mode_test.main();
+    yaml_test.main();
   });
 }
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
new file mode 100644
index 0000000..5deb5f5
--- /dev/null
+++ b/pkg/analyzer/test/src/task/yaml_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.task.yaml_test;
+
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/yaml.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/yaml.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/yaml.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+import '../context/abstract_context.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(ParseYamlTaskTest);
+}
+
+isInstanceOf isParseYamlTask = new isInstanceOf<ParseYamlTask>();
+
+@reflectiveTest
+class ParseYamlTaskTest extends AbstractContextTest {
+  Source source;
+
+  test_perform() {
+    _performParseTask(r'''
+rules:
+  style_guide:
+    camel_case_types: false
+''');
+    expect(outputs, hasLength(3));
+    YamlDocument document = outputs[YAML_DOCUMENT];
+    expect(document, isNotNull);
+    var value = document.contents.value;
+    expect(value, new isInstanceOf<Map>());
+    expect(value['rules']['style_guide']['camel_case_types'], isFalse);
+    expect(outputs[YAML_ERRORS], hasLength(0));
+    LineInfo lineInfo = outputs[LINE_INFO];
+    expect(lineInfo, isNotNull);
+    expect(lineInfo.getOffsetOfLine(0), 0);
+    expect(lineInfo.getOffsetOfLine(1), 7);
+    expect(lineInfo.getOffsetOfLine(2), 22);
+    expect(lineInfo.getOffsetOfLine(3), 50);
+  }
+
+  test_perform_doesNotExist() {
+    _performParseTask(null);
+    expect(outputs, hasLength(3));
+    YamlDocument document = outputs[YAML_DOCUMENT];
+    expect(document, isNotNull);
+    expect(document.contents.value, isNull);
+    expect(outputs[YAML_ERRORS], hasLength(1));
+    LineInfo lineInfo = outputs[LINE_INFO];
+    expect(lineInfo, isNotNull);
+    expect(lineInfo.getOffsetOfLine(0), 0);
+  }
+
+  void _performParseTask(String content) {
+    if (content == null) {
+      source = resourceProvider.getFile('/test.yaml').createSource();
+    } else {
+      source = newSource('/test.yaml', content);
+    }
+    computeResult(source, YAML_DOCUMENT, matcher: isParseYamlTask);
+  }
+}
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index e162219..a8c39a5 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -4,9 +4,9 @@
 
 library analyzer.test.utils;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/ast.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/build_sdk_summary.dart b/pkg/analyzer/tool/summary/build_sdk_summary.dart
index db17c57..738e0a1 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summary.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summary.dart
@@ -45,9 +45,8 @@
   //
   // Serialize each SDK library.
   //
-  List<String> prelinkedLibraryUris = <String>[];
-  List<PrelinkedLibraryBuilder> prelinkedLibraries =
-      <PrelinkedLibraryBuilder>[];
+  List<String> linkedLibraryUris = <String>[];
+  List<LinkedLibraryBuilder> linkedLibraries = <LinkedLibraryBuilder>[];
   List<String> unlinkedUnitUris = <String>[];
   List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
   for (SdkLibrary lib in sdk.sdkLibraries) {
@@ -55,19 +54,20 @@
     Source librarySource = sdk.mapDartUri(lib.shortName);
     LibraryElement libraryElement =
         context.computeLibraryElement(librarySource);
+    // TODO(paulberry): also build a summary of the SDK in strong mode.
     LibrarySerializationResult libraryResult =
-        serializeLibrary(libraryElement, context.typeProvider);
-    prelinkedLibraryUris.add(lib.shortName);
-    prelinkedLibraries.add(libraryResult.prelinked);
+        serializeLibrary(libraryElement, context.typeProvider, false);
+    linkedLibraryUris.add(lib.shortName);
+    linkedLibraries.add(libraryResult.linked);
     unlinkedUnitUris.addAll(libraryResult.unitUris);
     unlinkedUnits.addAll(libraryResult.unlinkedUnits);
   }
   //
   // Write the whole SDK bundle.
   //
-  SdkBundleBuilder sdkBundle = encodeSdkBundle(
-      prelinkedLibraryUris: prelinkedLibraryUris,
-      prelinkedLibraries: prelinkedLibraries,
+  SdkBundleBuilder sdkBundle = new SdkBundleBuilder(
+      linkedLibraryUris: linkedLibraryUris,
+      linkedLibraries: linkedLibraries,
       unlinkedUnitUris: unlinkedUnitUris,
       unlinkedUnits: unlinkedUnits);
   File file = new File(outputFilePath);
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 1918074..afd790d 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -88,8 +88,12 @@
         if (type.isList) {
           if (_idl.classes.containsKey(type.typeName)) {
             // List of classes is ok
+          } else if (_idl.enums.containsKey(type.typeName)) {
+            // List of enums is ok
           } else if (type.typeName == 'int') {
             // List of ints is ok
+          } else if (type.typeName == 'double') {
+            // List of doubles is ok
           } else if (type.typeName == 'String') {
             // List of strings is ok
           } else {
@@ -116,12 +120,21 @@
   /**
    * Generate a Dart expression representing the default value for a field
    * having the given [type], or `null` if there is no default value.
+   *
+   * If [builder] is `true`, the returned type should be appropriate for use in
+   * a builder class.
    */
-  String defaultValue(idlModel.FieldType type) {
+  String defaultValue(idlModel.FieldType type, bool builder) {
     if (type.isList) {
-      return 'const <${type.typeName}>[]';
+      if (builder) {
+        idlModel.FieldType elementType =
+            new idlModel.FieldType(type.typeName, false);
+        return '<${encodedType(elementType)}>[]';
+      } else {
+        return 'const <${type.typeName}>[]';
+      }
     } else if (_idl.enums.containsKey(type.typeName)) {
-      return '${type.typeName}.${_idl.enums[type.typeName].values[0]}';
+      return '${type.typeName}.${_idl.enums[type.typeName].values[0].name}';
     } else if (type.typeName == 'int') {
       return '0';
     } else if (type.typeName == 'String') {
@@ -200,7 +213,9 @@
             new idlModel.EnumDeclaration(doc, decl.name.name);
         _idl.enums[enm.name] = enm;
         for (EnumConstantDeclaration constDecl in decl.constants) {
-          enm.values.add(constDecl.name.name);
+          String doc = _getNodeDoc(lineInfo, constDecl);
+          enm.values
+              .add(new idlModel.EnumValueDeclaration(doc, constDecl.name.name));
         }
       } else if (decl is TopLevelVariableDeclaration) {
         // Ignore top level variable declarations; they are present just to make
@@ -261,21 +276,14 @@
     out("import 'base.dart' as base;");
     out("import 'flat_buffers.dart' as fb;");
     out();
-    _idl.enums.forEach((String name, idlModel.EnumDeclaration enm) {
-      outDoc(enm.documentation);
-      out('enum $name {');
-      indent(() {
-        for (String value in enm.values) {
-          out('$value,');
-        }
-      });
-      out('}');
+    for (idlModel.EnumDeclaration enm in _idl.enums.values) {
+      _generateEnum(enm);
       out();
-    });
-    for (var cls in _idl.classes.values) {
-      List<String> builderParams = _generateBuilder(cls);
+      _generateEnumReader(enm);
       out();
-      _generateEncodeFunction(cls, builderParams);
+    }
+    for (idlModel.ClassDeclaration cls in _idl.classes.values) {
+      _generateBuilder(cls);
       out();
       _generateInterface(cls);
       out();
@@ -283,6 +291,8 @@
       out();
       _generateImpl(cls);
       out();
+      _generateMixin(cls);
+      out();
     }
   }
 
@@ -293,10 +303,13 @@
     return JSON.encode(s);
   }
 
-  List<String> _generateBuilder(idlModel.ClassDeclaration cls) {
-    String builderName = cls.name + 'Builder';
-    List<String> builderParams = <String>[];
-    out('class $builderName {');
+  void _generateBuilder(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String builderName = name + 'Builder';
+    String mixinName = '_${name}Mixin';
+    List<String> constructorParams = <String>[];
+    out('class $builderName extends Object with $mixinName '
+        'implements $name {');
     indent(() {
       out('bool _finished = false;');
       // Generate fields.
@@ -307,24 +320,45 @@
         String typeStr = encodedType(type);
         out('$typeStr _$fieldName;');
       }
-      // Generate constructor.
-      out();
-      out('$builderName();');
-      // Generate setters.
+      // Generate getters and setters.
       for (idlModel.FieldDeclaration field in cls.fields) {
         String fieldName = field.name;
-        String typeStr = encodedType(field.type);
+        idlModel.FieldType fieldType = field.type;
+        String typeStr = encodedType(fieldType);
+        String def = defaultValue(fieldType, true);
+        String defSuffix = def == null ? '' : ' ??= $def';
+        out();
+        out('@override');
+        out('$typeStr get $fieldName => _$fieldName$defSuffix;');
         out();
         outDoc(field.documentation);
-        builderParams.add('$typeStr $fieldName');
+        constructorParams.add('$typeStr $fieldName');
         out('void set $fieldName($typeStr _value) {');
         indent(() {
           String stateFieldName = '_' + fieldName;
           out('assert(!_finished);');
+          // Validate that int(s) are non-negative.
+          if (fieldType.typeName == 'int') {
+            if (!fieldType.isList) {
+              out('assert(_value == null || _value >= 0);');
+            } else {
+              out('assert(_value == null || _value.every((e) => e >= 0));');
+            }
+          }
+          // Set the value.
           out('$stateFieldName = _value;');
         });
         out('}');
       }
+      // Generate constructor.
+      out();
+      out('$builderName({${constructorParams.join(', ')}})');
+      for (int i = 0; i < cls.fields.length; i++) {
+        idlModel.FieldDeclaration field = cls.fields[i];
+        String prefix = i == 0 ? '  : ' : '    ';
+        String suffix = i == cls.fields.length - 1 ? ';' : ',';
+        out('${prefix}_${field.name} = ${field.name}$suffix');
+      }
       // Generate finish.
       if (cls.isTopLevel) {
         out();
@@ -362,8 +396,16 @@
               String itemCode = 'b.finish(fbBuilder)';
               String listCode = '$valueName.map((b) => $itemCode).toList()';
               writeCode = '$offsetName = fbBuilder.writeList($listCode);';
+            } else if (_idl.enums.containsKey(fieldType.typeName)) {
+              String itemCode = 'b.index';
+              String listCode = '$valueName.map((b) => $itemCode).toList()';
+              writeCode = '$offsetName = fbBuilder.writeListUint32($listCode);';
             } else if (fieldType.typeName == 'int') {
-              writeCode = '$offsetName = fbBuilder.writeListInt32($valueName);';
+              writeCode =
+                  '$offsetName = fbBuilder.writeListUint32($valueName);';
+            } else if (fieldType.typeName == 'double') {
+              writeCode =
+                  '$offsetName = fbBuilder.writeListFloat64($valueName);';
             } else {
               assert(fieldType.typeName == 'String');
               String itemCode = 'fbBuilder.writeString(b)';
@@ -404,11 +446,11 @@
             condition = '$valueName == true';
             writeCode = 'fbBuilder.addBool($index, true);';
           } else if (fieldType.typeName == 'int') {
-            condition += ' && $valueName != ${defaultValue(fieldType)}';
-            writeCode = 'fbBuilder.addInt32($index, $valueName);';
+            condition += ' && $valueName != ${defaultValue(fieldType, true)}';
+            writeCode = 'fbBuilder.addUint32($index, $valueName);';
           } else if (_idl.enums.containsKey(fieldType.typeName)) {
-            condition += ' && $valueName != ${defaultValue(fieldType)}';
-            writeCode = 'fbBuilder.addInt32($index, $valueName.index);';
+            condition += ' && $valueName != ${defaultValue(fieldType, true)}';
+            writeCode = 'fbBuilder.addUint32($index, $valueName.index);';
           }
           if (writeCode == null) {
             throw new UnimplementedError('Writing type ${fieldType.typeName}');
@@ -424,21 +466,43 @@
       out('}');
     });
     out('}');
-    return builderParams;
   }
 
-  void _generateEncodeFunction(
-      idlModel.ClassDeclaration cls, List<String> builderParams) {
-    String className = cls.name;
-    String builderName = className + 'Builder';
-    out('$builderName encode$className({${builderParams.join(', ')}}) {');
+  void _generateEnum(idlModel.EnumDeclaration enm) {
+    String name = enm.name;
+    outDoc(enm.documentation);
+    out('enum $name {');
     indent(() {
-      out('$builderName builder = new $builderName();');
-      for (idlModel.FieldDeclaration field in cls.fields) {
-        String fieldName = field.name;
-        out('builder.$fieldName = $fieldName;');
+      for (idlModel.EnumValueDeclaration value in enm.values) {
+        outDoc(value.documentation);
+        if (enm.values.last == value) {
+          out('${value.name}');
+        } else {
+          out('${value.name},');
+          out();
+        }
       }
-      out('return builder;');
+    });
+    out('}');
+  }
+
+  void _generateEnumReader(idlModel.EnumDeclaration enm) {
+    String name = enm.name;
+    String readerName = '_${name}Reader';
+    out('class $readerName extends fb.Reader<$name> {');
+    indent(() {
+      out('const $readerName() : super();');
+      out();
+      out('@override');
+      out('int get size => 4;');
+      out();
+      out('@override');
+      out('$name read(fb.BufferPointer bp) {');
+      indent(() {
+        out('int index = const fb.Uint32Reader().read(bp);');
+        out('return $name.values[index];');
+      });
+      out('}');
     });
     out('}');
   }
@@ -446,7 +510,8 @@
   void _generateImpl(idlModel.ClassDeclaration cls) {
     String name = cls.name;
     String implName = '_${name}Impl';
-    out('class $implName implements $name {');
+    String mixinName = '_${name}Mixin';
+    out('class $implName extends Object with $mixinName implements $name {');
     indent(() {
       out('final fb.BufferPointer _bp;');
       out();
@@ -458,59 +523,50 @@
         String fieldName = field.name;
         out('$returnType _$fieldName;');
       }
-      out();
-      // Write toMap().
-      out('@override');
-      out('Map<String, Object> toMap() => {');
-      indent(() {
-        for (idlModel.FieldDeclaration field in cls.fields) {
-          String fieldName = field.name;
-          out('${quoted(fieldName)}: $fieldName,');
-        }
-      });
-      out('};');
       // Write getters.
       cls.fields.asMap().forEach((index, field) {
         String fieldName = field.name;
         idlModel.FieldType type = field.type;
         String typeName = type.typeName;
-        // Prepare "readExpr" or "readCode" + "def"
-        String readExpr;
+        // Prepare "readCode" + "def"
         String readCode;
-        String def = defaultValue(type);
+        String def = defaultValue(type, false);
         if (type.isList) {
           if (typeName == 'int') {
-            String itemCode = 'const fb.Int32Reader()';
+            String itemCode = 'const fb.Uint32Reader()';
             readCode = 'const fb.ListReader<int>($itemCode)';
+          } else if (typeName == 'double') {
+            readCode = 'const fb.Float64ListReader()';
           } else if (typeName == 'String') {
             String itemCode = 'const fb.StringReader()';
             readCode = 'const fb.ListReader<String>($itemCode)';
-          } else {
+          } else if (_idl.classes.containsKey(typeName)) {
             String itemCode = '$typeName>(const _${typeName}Reader()';
             readCode = 'const fb.ListReader<$itemCode)';
+          } else {
+            assert(_idl.enums.containsKey(typeName));
+            String itemCode = 'const _${typeName}Reader()';
+            readCode = 'const fb.ListReader<$typeName>($itemCode)';
           }
         } else if (typeName == 'bool') {
           readCode = 'const fb.BoolReader()';
         } else if (typeName == 'int') {
-          readCode = 'const fb.Int32Reader()';
+          readCode = 'const fb.Uint32Reader()';
         } else if (typeName == 'String') {
           readCode = 'const fb.StringReader()';
         } else if (_idl.enums.containsKey(typeName)) {
-          readExpr =
-              '$typeName.values[const fb.Int32Reader().vTableGet(_bp, $index, 0)]';
+          readCode = 'const _${typeName}Reader()';
         } else if (_idl.classes.containsKey(typeName)) {
           readCode = 'const _${typeName}Reader()';
         }
-        if (readExpr == null) {
-          assert(readCode != null);
-          readExpr = '$readCode.vTableGet(_bp, $index, $def)';
-        }
+        assert(readCode != null);
         // Write the getter implementation.
         out();
         out('@override');
         String returnType = dartType(type);
         out('$returnType get $fieldName {');
         indent(() {
+          String readExpr = '$readCode.vTableGet(_bp, $index, $def)';
           out('_$fieldName ??= $readExpr;');
           out('return _$fieldName;');
         });
@@ -544,6 +600,25 @@
     out('}');
   }
 
+  void _generateMixin(idlModel.ClassDeclaration cls) {
+    String name = cls.name;
+    String mixinName = '_${name}Mixin';
+    out('abstract class $mixinName implements $name {');
+    indent(() {
+      // Write toMap().
+      out('@override');
+      out('Map<String, Object> toMap() => {');
+      indent(() {
+        for (idlModel.FieldDeclaration field in cls.fields) {
+          String fieldName = field.name;
+          out('${quoted(fieldName)}: $fieldName,');
+        }
+      });
+      out('};');
+    });
+    out('}');
+  }
+
   void _generateReader(idlModel.ClassDeclaration cls) {
     String name = cls.name;
     String readerName = '_${name}Reader';
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index 39e7a4a..cb2ee1d 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -10,26 +10,30 @@
  * The code generation process introduces the following non-typical semantics:
  * - Fields of type List are never null, and have a default value of the empty
  *   list.
- * - Fields of type int are never null, and have a default value of zero.
+ * - Fields of type int are unsigned 32-bit integers, never null, and have a
+ *   default value of zero.
  * - Fields of type String are never null, and have a default value of ''.
  * - Fields of type bool are never null, and have a default value of false.
  * - Fields whose type is an enum are never null, and have a default value of
  *   the first value declared in the enum.
  *
  * Terminology used in this document:
- * - "Unlinked" refers to information that can be determined from reading the
- *   .dart file for the library itself (including all parts) and no other
- *   files.
- * - "Prelinked" refers to information that can be determined from reading the
- *   unlinked information for the library itself and the unlinked information
- *   for all direct imports (plus the transitive closure of exports reachable
- *   from those direct imports).
- * - "Linked" refers to information that can be determined only from reading
- *   the unlinked and prelinked information for the library itself and the
- *   transitive closure of its imports.
+ * - "Unlinked" refers to information that can be determined from reading a
+ *   single .dart file in isolation.
+ * - "Prelinked" refers to information that can be determined from the defining
+ *   compilation unit of a library, plus direct imports, plus the transitive
+ *   closure of exports reachable from those libraries, plus all part files
+ *   constituting those libraries.
+ * - "Linked" refers to all other information; in theory, this information may
+ *   depend on all files in the transitive import/export closure.  However, in
+ *   practice we expect that the number of additional dependencies will usually
+ *   be small, since the additional dependencies only need to be consulted for
+ *   type propagation, type inference, and constant evaluation, which typically
+ *   have short dependency chains.
  *
- * TODO(paulberry): currently the summary format only contains unlinked and
- * prelinked information.
+ * Since we expect "linked" and "prelinked" dependencies to be similar, we only
+ * rarely distinguish between them; most information is that is not "unlinked"
+ * is typically considered "linked" for simplicity.
  *
  * Except as otherwise noted, synthetic elements are not stored in the summary;
  * they are re-synthesized at the time the summary is read.
@@ -63,10 +67,59 @@
 const topLevel = null;
 
 /**
+ * Summary information about a reference to a an entity such as a type, top
+ * level executable, or executable within a class.
+ */
+class EntityRef {
+  /**
+   * If this [EntityRef] is contained within [LinkedUnit.types], slot id (which
+   * is unique within the compilation unit) identifying the target of type
+   * propagation or type inference with which this [EntityRef] is associated.
+   *
+   * Otherwise zero.
+   */
+  int slot;
+
+  /**
+   * Index into [UnlinkedUnit.references] for the entity being referred to, or
+   * zero if this is a reference to a type parameter.
+   */
+  int reference;
+
+  /**
+   * If this is a reference to a type parameter, one-based index into the list
+   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
+   * Bruijn index conventions; that is, innermost parameters come first, and
+   * if a class or method has multiple parameters, they are indexed from right
+   * to left.  So for instance, if the enclosing declaration is
+   *
+   *     class C<T,U> {
+   *       m<V,W> {
+   *         ...
+   *       }
+   *     }
+   *
+   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
+   * respectively.
+   *
+   * If the type being referred to is not a type parameter, [paramReference] is
+   * zero.
+   */
+  int paramReference;
+
+  /**
+   * If this is an instantiation of a generic type or generic executable, the
+   * type arguments used to instantiate it.  Trailing type arguments of type
+   * `dynamic` are omitted.
+   */
+  List<EntityRef> typeArguments;
+}
+
+/**
  * Information about a dependency that exists between one library and another
  * due to an "import" declaration.
  */
-class PrelinkedDependency {
+class LinkedDependency {
   /**
    * The relative URI of the dependent library.  This URI is relative to the
    * importing library, even if there are intervening `export` declarations.
@@ -84,58 +137,109 @@
 }
 
 /**
- * Pre-linked summary of a library.
+ * Information about a single name in the export namespace of the library that
+ * is not in the public namespace.
+ */
+class LinkedExportName {
+  /**
+   * Name of the exported entity.  TODO(paulberry): do we include the trailing
+   * '=' for a setter?
+   */
+  String name;
+
+  /**
+   * Index into [LinkedLibrary.dependencies] for the library in which the
+   * entity is defined.
+   */
+  int dependency;
+
+  /**
+   * Integer index indicating which unit in the exported library contains the
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
+   * zero represents the defining compilation unit, and nonzero values
+   * represent parts in the order of the corresponding `part` declarations.
+   */
+  int unit;
+
+  /**
+   * The kind of the entity being referred to.
+   */
+  ReferenceKind kind;
+}
+
+/**
+ * Linked summary of a library.
  */
 @topLevel
-class PrelinkedLibrary {
+class LinkedLibrary {
   /**
-   * The pre-linked summary of all the compilation units constituting the
+   * The 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.
    */
-  List<PrelinkedUnit> units;
+  List<LinkedUnit> units;
 
   /**
    * The libraries that this library depends on (either via an explicit import
    * statement or via the implicit dependencies on `dart:core` and
    * `dart:async`).  The first element of this array is a pseudo-dependency
-   * representing the library itself (it is also used for "dynamic").
+   * representing the library itself (it is also used for `dynamic` and
+   * `void`).  This is followed by elements representing "prelinked"
+   * dependencies (direct imports and the transitive closure of exports).
+   * After the prelinked dependencies are elements representing "linked"
+   * dependencies.
    *
-   * TODO(paulberry): consider removing this entirely and just using
-   * [UnlinkedLibrary.imports].
+   * A library is only included as a "linked" dependency if it is a true
+   * dependency (e.g. a propagated or inferred type or constant value
+   * implicitly refers to an element declared in the library) or
+   * anti-dependency (e.g. the result of type propagation or type inference
+   * depends on the lack of a certain declaration in the library).
    */
-  List<PrelinkedDependency> dependencies;
+  List<LinkedDependency> dependencies;
 
   /**
    * For each import in [UnlinkedUnit.imports], an index into [dependencies]
    * of the library being imported.
-   *
-   * TODO(paulberry): if [dependencies] is removed, this can be removed as
-   * well, since there will effectively be a one-to-one mapping.
    */
   List<int> importDependencies;
+
+  /**
+   * Information about entities in the export namespace of the library that are
+   * not in the public namespace of the library (that is, entities that are
+   * brought into the namespace via `export` directives).
+   *
+   * Sorted by name.
+   */
+  List<LinkedExportName> exportNames;
+
+  /**
+   * The number of elements in [dependencies] which are not "linked"
+   * dependencies (that is, the number of libraries in the direct imports plus
+   * the transitive closure of exports, plus the library itself).
+   */
+  int numPrelinkedDependencies;
 }
 
 /**
  * Information about the resolution of an [UnlinkedReference].
  */
-class PrelinkedReference {
+class LinkedReference {
   /**
-   * Index into [PrelinkedLibrary.dependencies] indicating which imported library
+   * Index into [LinkedLibrary.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 is [PrelinkedReferenceKind.classOrEnum].
+   * The kind of the entity being referred to.  For the pseudo-types `dynamic`
+   * and `void`, the kind is [ReferenceKind.classOrEnum].
    */
-  PrelinkedReferenceKind kind;
+  ReferenceKind kind;
 
   /**
    * Integer index indicating which unit in the imported library contains the
-   * definition of the entity.  As with indices into [PrelinkedLibrary.units],
+   * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
    */
@@ -146,27 +250,80 @@
    * it accepts.  Otherwise zero.
    */
   int numTypeParameters;
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
+   */
+  String name;
+}
+
+/**
+ * Linked summary of a compilation unit.
+ */
+class LinkedUnit {
+  /**
+   * Information about the resolution of references within the compilation
+   * unit.  Each element of [UnlinkedUnit.references] has a corresponding
+   * element in this list (at the same index).  If this list has additional
+   * elements beyond the number of elements in [UnlinkedUnit.references], those
+   * additional elements are references that are only referred to implicitly
+   * (e.g. elements involved in inferred or propagated types).
+   */
+  List<LinkedReference> references;
+
+  /**
+   * List associating slot ids found inside the unlinked summary for the
+   * compilation unit with propagated and inferred types.
+   */
+  List<EntityRef> types;
 }
 
 /**
  * Enum used to indicate the kind of entity referred to by a
- * [PrelinkedReference].
+ * [LinkedReference].
  */
-enum PrelinkedReferenceKind {
+enum ReferenceKind {
   /**
    * The entity is a class or enum.
    */
   classOrEnum,
 
   /**
+   * The entity is a constructor.
+   */
+  constructor,
+
+  /**
+   * The entity is a static const field.
+   */
+  constField,
+
+  /**
+   * The entity is a static method.
+   */
+  staticMethod,
+
+  /**
+   * The `length` property access.
+   */
+  length,
+
+  /**
    * The entity is a typedef.
    */
   typedef,
 
   /**
-   * The entity is a variable or executable.
+   * The entity is a top level function.
    */
-  other,
+  topLevelFunction,
+
+  /**
+   * The entity is a top level getter or setter.
+   */
+  topLevelPropertyAccessor,
 
   /**
    * The entity is a prefix.
@@ -180,30 +337,19 @@
 }
 
 /**
- * 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;
-}
-
-/**
  * Information about SDK.
  */
 @topLevel
 class SdkBundle {
   /**
-   * The list of URIs of items in [prelinkedLibraries], e.g. `dart:core`.
+   * The list of URIs of items in [linkedLibraries], e.g. `dart:core`.
    */
-  List<String> prelinkedLibraryUris;
+  List<String> linkedLibraryUris;
 
   /**
-   * Pre-linked libraries.
+   * Linked libraries.
    */
-  List<PrelinkedLibrary> prelinkedLibraries;
+  List<LinkedLibrary> linkedLibraries;
 
   /**
    * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
@@ -248,17 +394,17 @@
    * explicitly declare a supertype (and hence has supertype `Object`), or (b)
    * the class *is* `Object` (and hence has no supertype).
    */
-  UnlinkedTypeRef supertype;
+  EntityRef supertype;
 
   /**
    * Mixins appearing in a `with` clause, if any.
    */
-  List<UnlinkedTypeRef> mixins;
+  List<EntityRef> mixins;
 
   /**
    * Interfaces appearing in an `implements` clause, if any.
    */
-  List<UnlinkedTypeRef> interfaces;
+  List<EntityRef> interfaces;
 
   /**
    * Field declarations contained in the class.
@@ -304,6 +450,336 @@
 }
 
 /**
+ * Unlinked summary information about a compile-time constant expression, or a
+ * potentially constant expression.
+ *
+ * Constant expressions are represented using a simple stack-based language
+ * where [operations] is a sequence of operations to execute starting with an
+ * empty stack.  Once all operations have been executed, the stack should
+ * contain a single value which is the value of the constant.  Note that some
+ * operations consume additional data from the other fields of this class.
+ */
+class UnlinkedConst {
+  /**
+   * Sequence of operations to execute (starting with an empty stack) to form
+   * the constant value.
+   */
+  List<UnlinkedConstOperation> operations;
+
+  /**
+   * Sequence of unsigned 32-bit integers consumed by the operations
+   * `pushArgument`, `pushInt`, `shiftOr`, `concatenate`, `invokeConstructor`,
+   * `makeList`, and `makeMap`.
+   */
+  List<int> ints;
+
+  /**
+   * Sequence of 64-bit doubles consumed by the operation `pushDouble`.
+   */
+  List<double> doubles;
+
+  /**
+   * Sequence of strings consumed by the operations `pushString` and
+   * `invokeConstructor`.
+   */
+  List<String> strings;
+
+  /**
+   * Sequence of language constructs consumed by the operations
+   * `pushReference`, `invokeConstructor`, `makeList`, and `makeMap`.  Note
+   * that in the case of `pushReference` (and sometimes `invokeConstructor` the
+   * actual entity being referred to may be something other than a type.
+   */
+  List<EntityRef> references;
+}
+
+/**
+ * Enum representing the various kinds of operations which may be performed to
+ * produce a constant value.  These options are assumed to execute in the
+ * context of a stack which is initially empty.
+ */
+enum UnlinkedConstOperation {
+  /**
+   * Push the value of the n-th constructor argument (where n is obtained from
+   * [UnlinkedConst.ints]) onto the stack.
+   */
+  pushArgument,
+
+  /**
+   * Push the next value from [UnlinkedConst.ints] (a 32-bit unsigned integer)
+   * onto the stack.
+   *
+   * Note that Dart supports integers larger than 32 bits; these are
+   * represented by composing 32 bit values using the [shiftOr] operation.
+   */
+  pushInt,
+
+  /**
+   * Pop the top value off the stack, which should be an integer.  Multiply it
+   * by 2^32, "or" in the next value from [UnlinkedConst.ints] (which is
+   * interpreted as a 32-bit unsigned integer), and push the result back onto
+   * the stack.
+   */
+  shiftOr,
+
+  /**
+   * Push the next value from [UnlinkedConst.doubles] (a double precision
+   * floating point value) onto the stack.
+   */
+  pushDouble,
+
+  /**
+   * Push the constant `true` onto the stack.
+   */
+  pushTrue,
+
+  /**
+   * Push the constant `false` onto the stack.
+   */
+  pushFalse,
+
+  /**
+   * Push the next value from [UnlinkedConst.strings] onto the stack.
+   */
+  pushString,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), convert them to strings (if they aren't already),
+   * concatenate them into a single string, and push it back onto the stack.
+   *
+   * This operation is used to represent constants whose value is a literal
+   * string containing string interpolations.
+   */
+  concatenate,
+
+  /**
+   * Pop the top value from the stack which should be string, convert it to
+   * a symbol, and push it back onto the stack.
+   */
+  makeSymbol,
+
+  /**
+   * Push the constant `null` onto the stack.
+   */
+  pushNull,
+
+  /**
+   * Evaluate a (potentially qualified) identifier expression and push the
+   * resulting value onto the stack.  The identifier to be evaluated is
+   * obtained from [UnlinkedConst.references].
+   *
+   * This operation is used to represent the following kinds of constants
+   * (which are indistinguishable from an unresolved AST alone):
+   *
+   * - A qualified reference to a static constant variable (e.g. `C.v`, where
+   *   C is a class and `v` is a constant static variable in `C`).
+   * - An identifier expression referring to a constant variable.
+   * - A simple or qualified identifier denoting a class or type alias.
+   * - A simple or qualified identifier denoting a top-level function or a
+   *   static method.
+   */
+  pushReference,
+
+  /**
+   * Pop the top `n` values from the stack (where `n` is obtained from
+   * [UnlinkedConst.ints]) into a list (filled from the end) and take the next
+   * `n` values from [UnlinkedConst.strings] and use the lists of names and
+   * values to create named arguments.  Then pop the top `m` values from the
+   * stack (where `m` is obtained from [UnlinkedConst.ints]) into a list (filled
+   * from the end) and use them as positional arguments.  Use the lists of
+   * positional and names arguments to invoke a constant constructor obtained
+   * from [UnlinkedConst.references], and push the resulting value back onto the
+   * stack.
+   *
+   * Note that for an invocation of the form `const a.b(...)` (where no type
+   * arguments are specified), it is impossible to tell from the unresolved AST
+   * alone whether `a` is a class name and `b` is a constructor name, or `a` is
+   * a prefix name and `b` is a class name.  For consistency between AST based
+   * and elements based summaries, references to default constructors are always
+   * recorded as references to corresponding classes.
+   */
+  invokeConstructor,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), place them in a [List], and push the result back
+   * onto the stack.  The type parameter for the [List] is implicitly `dynamic`.
+   */
+  makeUntypedList,
+
+  /**
+   * Pop the top 2*n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), interpret them as key/value pairs, place them in a
+   * [Map], and push the result back onto the stack.  The two type parameters
+   * for the [Map] are implicitly `dynamic`.
+   */
+  makeUntypedMap,
+
+  /**
+   * Pop the top n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), place them in a [List], and push the result back
+   * onto the stack.  The type parameter for the [List] is obtained from
+   * [UnlinkedConst.references].
+   */
+  makeTypedList,
+
+  /**
+   * Pop the top 2*n values from the stack (where n is obtained from
+   * [UnlinkedConst.ints]), interpret them as key/value pairs, place them in a
+   * [Map], and push the result back onto the stack.  The two type parameters for
+   * the [Map] are obtained from [UnlinkedConst.references].
+   */
+  makeTypedMap,
+
+  /**
+   * Pop the top 2 values from the stack, pass them to the predefined Dart
+   * function `identical`, and push the result back onto the stack.
+   */
+  identical,
+
+  /**
+   * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
+   * result back onto the stack.
+   *
+   * This is also used to represent `v1 != v2`, by composition with [not].
+   */
+  equal,
+
+  /**
+   * Pop the top value from the stack, compute its boolean negation, and push
+   * the result back onto the stack.
+   */
+  not,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 && v2`, and push the
+   * result back onto the stack.
+   */
+  and,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 || v2`, and push the
+   * result back onto the stack.
+   */
+  or,
+
+  /**
+   * Pop the top value from the stack, compute its integer complement, and push
+   * the result back onto the stack.
+   */
+  complement,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 ^ v2`, and push the
+   * result back onto the stack.
+   */
+  bitXor,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 & v2`, and push the
+   * result back onto the stack.
+   */
+  bitAnd,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 | v2`, and push the
+   * result back onto the stack.
+   */
+  bitOr,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 >> v2`, and push the
+   * result back onto the stack.
+   */
+  bitShiftRight,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 << v2`, and push the
+   * result back onto the stack.
+   */
+  bitShiftLeft,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 + v2`, and push the
+   * result back onto the stack.
+   */
+  add,
+
+  /**
+   * Pop the top value from the stack, compute its integer negation, and push
+   * the result back onto the stack.
+   */
+  negate,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 - v2`, and push the
+   * result back onto the stack.
+   */
+  subtract,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 * v2`, and push the
+   * result back onto the stack.
+   */
+  multiply,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 / v2`, and push the
+   * result back onto the stack.
+   */
+  divide,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 ~/ v2`, and push the
+   * result back onto the stack.
+   */
+  floorDivide,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 > v2`, and push the
+   * result back onto the stack.
+   */
+  greater,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 < v2`, and push the
+   * result back onto the stack.
+   */
+  less,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 >= v2`, and push the
+   * result back onto the stack.
+   */
+  greaterEqual,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 <= v2`, and push the
+   * result back onto the stack.
+   */
+  lessEqual,
+
+  /**
+   * Pop the top 2 values from the stack, compute `v1 % v2`, and push the
+   * result back onto the stack.
+   */
+  modulo,
+
+  /**
+   * Pop the top 3 values from the stack, compute `v1 ? v2 : v3`, and push the
+   * result back onto the stack.
+   */
+  conditional,
+
+  /**
+   * Pop the top value from the stack, evaluate `v.length`, and push the result
+   * back onto the stack.
+   */
+  length,
+}
+
+/**
  * Unlinked summary information about a documentation comment.
  */
 class UnlinkedDocumentationComment {
@@ -414,11 +890,10 @@
   List<UnlinkedTypeParam> typeParameters;
 
   /**
-   * Declared return type of the executable.  Absent if the return type is
-   * `void` or the executable is a constructor.  Note that when strong mode is
-   * enabled, the actual return type may be different due to type inference.
+   * Declared return type of the executable.  Absent if the executable is a
+   * constructor or the return type is implicit.
    */
-  UnlinkedTypeRef returnType;
+  EntityRef returnType;
 
   /**
    * Parameters of the executable, if any.  Note that getters have no
@@ -458,15 +933,18 @@
   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;
+
+  /**
+   * If this executable's return type is inferrable, nonzero slot id
+   * identifying which entry in [LinkedLibrary.types] contains the inferred
+   * return type.  If there is no matching entry in [LinkedLibrary.types], then
+   * no return type was inferred for this variable, so its static type is
+   * `dynamic`.
+   */
+  int inferredReturnTypeSlot;
 }
 
 /**
@@ -614,12 +1092,10 @@
 
   /**
    * If [isFunctionTyped] is `true`, the declared return type.  If
-   * [isFunctionTyped] is `false`, the declared type.  Absent if
-   * [isFunctionTyped] is `true` and the declared return type is `void`.  Note
-   * that when strong mode is enabled, the actual type may be different due to
-   * type inference.
+   * [isFunctionTyped] is `false`, the declared type.  Absent if the type is
+   * implicit.
    */
-  UnlinkedTypeRef type;
+  EntityRef type;
 
   /**
    * If [isFunctionTyped] is `true`, the parameters of the function type.
@@ -643,10 +1119,17 @@
   bool isInitializingFormal;
 
   /**
-   * Indicates whether this parameter lacks an explicit type declaration.
-   * Always false for a function-typed parameter.
+   * If this parameter's type is inferrable, nonzero slot id identifying which
+   * entry in [LinkedLibrary.types] contains the inferred type.  If there is no
+   * matching entry in [LinkedLibrary.types], then no type was inferred for
+   * this variable, so its static type is `dynamic`.
+   *
+   * Note that although strong mode considers initializing formals to be
+   * inferrable, they are not marked as such in the summary; if their type is
+   * not specified, they always inherit the static type of the corresponding
+   * field.
    */
-  bool hasImplicitType;
+  int inferredTypeSlot;
 }
 
 /**
@@ -692,12 +1175,6 @@
  * Unlinked summary information about a specific name contributed by a
  * compilation unit to a library's public namespace.
  *
- * TODO(paulberry): add a count of generic parameters, so that resynthesis
- * doesn't have to peek into the library to obtain this info.
- *
- * TODO(paulberry): for classes, add info about static members and
- * constructors, since this will be needed to prelink info about constants.
- *
  * TODO(paulberry): some of this information is redundant with information
  * elsewhere in the summary.  Consider reducing the redundancy to reduce
  * summary size.
@@ -711,13 +1188,20 @@
   /**
    * The kind of object referred to by the name.
    */
-  PrelinkedReferenceKind kind;
+  ReferenceKind kind;
 
   /**
    * If the entity being referred to is generic, the number of type parameters
    * it accepts.  Otherwise zero.
    */
   int numTypeParameters;
+
+  /**
+   * If this [UnlinkedPublicName] is a class, the list of members which can be
+   * referenced from constants - static constant fields, static methods, and
+   * constructors.  Otherwise empty.
+   */
+  List<UnlinkedPublicName> constMembers;
 }
 
 /**
@@ -752,8 +1236,8 @@
  */
 class UnlinkedReference {
   /**
-   * Name of the entity being referred to.  The empty string refers to the
-   * pseudo-type `dynamic`.
+   * Name of the entity being referred to.  For the pseudo-type `dynamic`, the
+   * string is "dynamic".  For the pseudo-type `void`, the string is "void".
    */
   String name;
 
@@ -796,9 +1280,9 @@
   List<UnlinkedTypeParam> typeParameters;
 
   /**
-   * Return type of the typedef.  Absent if the return type is `void`.
+   * Return type of the typedef.
    */
-  UnlinkedTypeRef returnType;
+  EntityRef returnType;
 
   /**
    * Parameters of the executable, if any.
@@ -825,51 +1309,7 @@
    * Bound of the type parameter, if a bound is explicitly declared.  Otherwise
    * null.
    */
-  UnlinkedTypeRef bound;
-}
-
-/**
- * Unlinked summary information about a reference to a type.
- */
-class UnlinkedTypeRef {
-  /**
-   * 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
-   * [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.
-   */
-  int reference;
-
-  /**
-   * If this is a reference to a type parameter, one-based index into the list
-   * of [UnlinkedTypeParam]s currently in effect.  Indexing is done using De
-   * Bruijn index conventions; that is, innermost parameters come first, and
-   * if a class or method has multiple parameters, they are indexed from right
-   * to left.  So for instance, if the enclosing declaration is
-   *
-   *     class C<T,U> {
-   *       m<V,W> {
-   *         ...
-   *       }
-   *     }
-   *
-   * Then [paramReference] values of 1, 2, 3, and 4 represent W, V, U, and T,
-   * respectively.
-   *
-   * If the type being referred to is not a type parameter, [paramReference] is
-   * zero.
-   */
-  int paramReference;
-
-  /**
-   * If this is an instantiation of a generic type, the type arguments used to
-   * instantiate it.  Trailing type arguments of type `dynamic` are omitted.
-   */
-  List<UnlinkedTypeRef> typeArguments;
+  EntityRef bound;
 }
 
 /**
@@ -910,8 +1350,10 @@
 
   /**
    * 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".
+   * zeroth element of this array is always populated and is used to represent
+   * the absence of a reference in places where a reference is optional (for
+   * example [UnlinkedReference.prefixReference or
+   * UnlinkedImport.prefixReference]).
    */
   List<UnlinkedReference> references;
 
@@ -981,10 +1423,15 @@
   UnlinkedDocumentationComment documentationComment;
 
   /**
-   * 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.
+   * Declared type of the variable.  Absent if the type is implicit.
    */
-  UnlinkedTypeRef type;
+  EntityRef type;
+
+  /**
+   * If [isConst] is true, and the variable has an initializer, the constant
+   * expression in the initializer.
+   */
+  UnlinkedConst constExpr;
 
   /**
    * Indicates whether the variable is declared using the `static` keyword.
@@ -1006,7 +1453,20 @@
   bool isConst;
 
   /**
-   * Indicates whether this variable lacks an explicit type declaration.
+   * If this variable is propagable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the propagated type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then this variable's
+   * propagated type is the same as its declared type.
+   *
+   * Non-propagable variables have a [propagatedTypeSlot] of zero.
    */
-  bool hasImplicitType;
+  int propagatedTypeSlot;
+
+  /**
+   * If this variable is inferrable, nonzero slot id identifying which entry in
+   * [LinkedLibrary.types] contains the inferred type for this variable.  If
+   * there is no matching entry in [LinkedLibrary.types], then no type was
+   * inferred for this variable, so its static type is `dynamic`.
+   */
+  int inferredTypeSlot;
 }
diff --git a/pkg/analyzer/tool/summary/idl_model.dart b/pkg/analyzer/tool/summary/idl_model.dart
index 07be039..9317215 100644
--- a/pkg/analyzer/tool/summary/idl_model.dart
+++ b/pkg/analyzer/tool/summary/idl_model.dart
@@ -51,13 +51,21 @@
   /**
    * List of enumerated values.
    */
-  final List<String> values = <String>[];
+  final List<EnumValueDeclaration> values = <EnumValueDeclaration>[];
 
   EnumDeclaration(String documentation, String name)
       : super(documentation, name);
 }
 
 /**
+ * Information about a single enum value defined in the IDL.
+ */
+class EnumValueDeclaration extends Declaration {
+  EnumValueDeclaration(String documentation, String name)
+      : super(documentation, name);
+}
+
+/**
  * Information about a single class field defined in the IDL.
  */
 class FieldDeclaration extends Declaration {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 0b6ae40..19b7af4 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
@@ -302,7 +303,8 @@
   /// Decide on the appropriate method for resolving URIs based on the given
   /// [options] and [customUrlMappings] settings, and return a
   /// [SourceFactory] that has been configured accordingly.
-  SourceFactory _chooseUriResolutionPolicy(CommandLineOptions options) {
+  SourceFactory _chooseUriResolutionPolicy(
+      CommandLineOptions options, EmbedderYamlLocator yamlLocator) {
     Packages packages;
     Map<String, List<fileSystem.Folder>> packageMap;
     UriResolver packageUriResolver;
@@ -356,9 +358,24 @@
     }
 
     // Now, build our resolver list.
+    List<UriResolver> resolvers = [];
 
     // 'dart:' URIs come first.
-    List<UriResolver> resolvers = [new DartUriResolver(sdk)];
+
+    // Setup embedding.
+    yamlLocator.refresh(packageMap);
+
+    EmbedderUriResolver embedderUriResolver =
+        new EmbedderUriResolver(yamlLocator.embedderYamls);
+    if (embedderUriResolver.length == 0) {
+      // The embedder uri resolver has no mappings. Use the default Dart SDK
+      // uri resolver.
+      resolvers.add(new DartUriResolver(sdk));
+    } else {
+      // The embedder uri resolver has mappings, use it instead of the default
+      // Dart SDK uri resolver.
+      resolvers.add(embedderUriResolver);
+    }
 
     // Next SdkExts.
     if (packageMap != null) {
@@ -401,13 +418,16 @@
       return;
     }
     _previousOptions = options;
+
+    // Create a context.
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+
     // Choose a package resolution policy and a diet parsing policy based on
     // the command-line options.
-    SourceFactory sourceFactory = _chooseUriResolutionPolicy(options);
+    SourceFactory sourceFactory = _chooseUriResolutionPolicy(
+        options, (context as InternalAnalysisContext).embedderYamlLocator);
     AnalyzeFunctionBodiesPredicate dietParsingPolicy =
         _chooseDietParsingPolicy(options);
-    // Create a context using these policies.
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
 
     context.sourceFactory = sourceFactory;
 
diff --git a/pkg/analyzer_cli/test/data/embedder_client/_packages b/pkg/analyzer_cli/test/data/embedder_client/_packages
new file mode 100644
index 0000000..03ed0f7
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/embedder_client/_packages
@@ -0,0 +1 @@
+package_with_embedder_yaml:../package_with_embedder_yaml/lib/
diff --git a/pkg/analyzer_cli/test/data/embedder_client/embedder_yaml_user.dart b/pkg/analyzer_cli/test/data/embedder_client/embedder_yaml_user.dart
new file mode 100644
index 0000000..2d88a2a
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/embedder_client/embedder_yaml_user.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:bear'; // Defined in package_with_embedder_yaml/lib/_embedder.yaml
+
+main() {
+  print(new Bear()); // Defined in 'dart:bear'
+}
diff --git a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml
new file mode 100644
index 0000000..5253771
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml
@@ -0,0 +1,4 @@
+embedder_libs:
+  "dart:bear": "grizzly.dart"
+  "dart:core": "core.dart"
+  "dart:async": "async.dart"
diff --git a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/async.dart b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/async.dart
new file mode 100644
index 0000000..3b69a2a
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/async.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart.async;
+
+abstract class Future<T> {}
+
+abstract class Stream<T> {}
diff --git a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/core.dart b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/core.dart
new file mode 100644
index 0000000..a7fa657
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/core.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart.core;
+
+class Object {
+  bool operator ==(other) => identical(this, other);
+  String toString() => 'a string';
+  int get hashCode => 0;
+}
+
+class Function {}
+
+class StackTrace {}
+
+class Symbol {}
+
+class Type {}
+
+abstract class Comparable<T> {
+  int compareTo(T other);
+}
+
+abstract class String implements Comparable<String> {
+  external factory String.fromCharCodes(Iterable<int> charCodes,
+      [int start = 0, int end]);
+  bool get isEmpty => false;
+  bool get isNotEmpty => false;
+  int get length => 0;
+  String toUpperCase();
+  List<int> get codeUnits;
+}
+
+class bool extends Object {}
+
+abstract class num implements Comparable<num> {
+  bool operator <(num other);
+  bool operator <=(num other);
+  bool operator >(num other);
+  bool operator >=(num other);
+  num operator +(num other);
+  num operator -(num other);
+  num operator *(num other);
+  num operator %(num other);
+  num operator /(num other);
+  int toInt();
+  num abs();
+  int round();
+}
+
+abstract class int extends num {
+  bool get isEven => false;
+  int operator -();
+  external static int parse(String source,
+      {int radix, int onError(String source)});
+}
+
+class double extends num {}
+
+class DateTime extends Object {}
+
+class Null extends Object {}
+
+class Deprecated extends Object {
+  final String expires;
+  const Deprecated(this.expires);
+}
+
+const Object deprecated = const Deprecated("next release");
+
+class Iterator<E> {
+  bool moveNext();
+  E get current;
+}
+
+abstract class Iterable<E> {
+  Iterator<E> get iterator;
+  bool get isEmpty;
+}
+
+abstract class List<E> implements Iterable<E> {
+  void add(E value);
+  E operator [](int index);
+  void operator []=(int index, E value);
+  Iterator<E> get iterator => null;
+  void clear();
+}
+
+abstract class Map<K, V> extends Object {
+  bool containsKey(Object key);
+  Iterable<K> get keys;
+}
+
+external bool identical(Object a, Object b);
+
+void print(Object object) {}
+
+class Uri {
+  static List<int> parseIPv6Address(String host, [int start = 0, int end]) {
+    int parseHex(int start, int end) {
+      return 0;
+    }
+    return null;
+  }
+}
diff --git a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/grizzly.dart b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/grizzly.dart
new file mode 100644
index 0000000..d575643
--- /dev/null
+++ b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/grizzly.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library grizzly;
+
+class Bear {}
diff --git a/pkg/analyzer_cli/test/embedder_test.dart b/pkg/analyzer_cli/test/embedder_test.dart
new file mode 100644
index 0000000..ded83fd
--- /dev/null
+++ b/pkg/analyzer_cli/test/embedder_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
+import 'package:path/path.dart' as path;
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+main() {
+  initializeTestEnvironment();
+
+  group('_embedder.yaml', () {
+    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;
+    });
+
+    test('resolution', wrap(() {
+      var testDir = path.join(testDirectory, 'data', 'embedder_client');
+      new Driver().start([
+        '--packages',
+        path.join(testDir, '_packages'),
+        path.join(testDir, 'embedder_yaml_user.dart')
+      ]);
+
+      expect(exitCode, 0);
+      expect(outSink.toString(), contains('No issues found'));
+    }));
+  });
+}
+
+/// Wrap a function call to dump stdout and stderr in case of an exception.
+Function wrap(Function f) {
+  return () {
+    try {
+      f();
+    } catch (e) {
+      if (outSink.toString().isNotEmpty) {
+        print('stdout:');
+        print(outSink);
+      }
+      if (errorSink.toString().isNotEmpty) {
+        print('stderr:');
+        print(errorSink);
+      }
+      throw e;
+    }
+  };
+}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 8f81d15..e84777f 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -33,6 +33,14 @@
 const bool forceIncrementalSupport =
     const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT');
 
+/// For every 'dart:' library, a corresponding environment variable is set
+/// to "true". The environment variable's name is the concatenation of
+/// this prefix and the name (without the 'dart:'.
+///
+/// For example 'dart:html' has the environment variable 'dart.library.html' set
+/// to "true".
+const String dartLibraryEnvironmentPrefix = 'dart.library.';
+
 /// Locations of the platform descriptor files relative to the library root.
 const String _clientPlatform = "lib/dart_client.platform";
 const String _serverPlatform = "lib/dart_server.platform";
@@ -580,7 +588,26 @@
     }
   }
 
-  fromEnvironment(String name) => environment[name];
+  fromEnvironment(String name) {
+    assert(invariant(NO_LOCATION_SPANNABLE,
+        sdkLibraries != null, message: "setupSdk() has not been run"));
+
+    var result = environment[name];
+    if (result != null || environment.containsKey(name)) return result;
+    if (!name.startsWith(dartLibraryEnvironmentPrefix)) return null;
+
+    String libraryName = name.substring(dartLibraryEnvironmentPrefix.length);
+    if (sdkLibraries.containsKey(libraryName)) {
+      // Dart2js always "supports" importing 'dart:mirrors' but will abort
+      // the compilation at a later point if the backend doesn't support
+      // mirrors. In this case 'mirrors' should not be in the environment.
+      if (name == dartLibraryEnvironmentPrefix + 'mirrors') {
+        return backend.supportsReflection ? "true" : null;
+      }
+      return "true";
+    }
+    return null;
+  }
 
   Uri lookupLibraryUri(String libraryName) {
     assert(invariant(NO_LOCATION_SPANNABLE,
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 53be699..4b37788 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1073,6 +1073,8 @@
       dumpInfoTask.dumpInfo();
     }
 
+    backend.sourceInformationStrategy.onComplete();
+
     checkQueues();
   }
 
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 945aaba..fde5cde 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -64,6 +64,8 @@
   bool get isMinusZero => false;
   bool get isZero => false;
   bool get isOne => false;
+  bool get isPositiveInfinity => false;
+  bool get isNegativeInfinity => false;
 
   // TODO(johnniwinther): Replace with a 'type' getter.
   DartType getType(CoreTypes types);
@@ -279,6 +281,10 @@
 
   bool get isOne => primitiveValue == 1.0;
 
+  bool get isPositiveInfinity => primitiveValue == double.INFINITY;
+
+  bool get isNegativeInfinity => primitiveValue == -double.INFINITY;
+
   DartType getType(CoreTypes types) => types.doubleType;
 
   bool operator ==(var other) {
diff --git a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
index 422aaa3..b55a433 100644
--- a/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
+++ b/pkg/compiler/lib/src/cps_ir/backward_null_check_remover.dart
@@ -77,7 +77,7 @@
       prim..replaceUsesWith(value)..destroy();
       let.remove();
     } else if (prim is GetLength || prim is GetField || prim is GetIndex) {
-      if (prim.hasNoEffectiveUses) {
+      if (prim.hasNoRefinedUses) {
         destroyRefinementsOfDeadPrimitive(prim);
         LetPrim let = prim.parent;
         prim..destroy();
diff --git a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
index 44cbbb0..798875f 100644
--- a/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
+++ b/pkg/compiler/lib/src/cps_ir/bounds_checker.dart
@@ -614,6 +614,16 @@
 
   @override
   void visitInvokeMethod(InvokeMethod node) {
+    if (node.selector.isGetter && node.selector.name == 'length') {
+      // If the receiver type is not known to be indexable, the length call
+      // was not rewritten to GetLength.  But if we can prove that the call only
+      // succeeds for indexables, we can trust that it returns the length.
+      TypeMask successType =
+          types.receiverTypeFor(node.selector, node.dartReceiver.type);
+      if (types.isDefinitelyIndexable(successType)) {
+        valueOf[node] = getLength(node.dartReceiver, currentEffectNumber);
+      }
+    }
     // TODO(asgerf): What we really need is a "changes length" side effect flag.
     if (world
         .getSideEffectsOfSelector(node.selector, node.mask)
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 0a80f33..470a96d 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -21,7 +21,8 @@
 import '../js/js.dart' as js show
     js,
     LiteralStatement,
-    Template;
+    Template,
+    isIdentityTemplate;
 import '../native/native.dart' show
     NativeBehavior;
 import '../tree/tree.dart' as ast;
@@ -166,6 +167,11 @@
   JumpCollector.retrn(this._continuation)
       : _continuationEnvironment = null, target = null;
 
+  /// Construct a collector for collecting goto jumps.
+  ///
+  /// There is no continuation or environment at the destination.
+  JumpCollector.goto(this.target) : _continuationEnvironment = null;
+
   /// True if the collector has not recorded any jumps to its continuation.
   bool get isEmpty;
 
@@ -421,6 +427,31 @@
   }
 }
 
+/// Collect 'goto' jumps, continue to a labeled case from within a switch.
+///
+/// These jumps are unrestricted within the switch.  They can be forward or
+/// backward.  They are implemented by assigning to a state variable.
+class GotoJumpCollector extends JumpCollector {
+  bool isEmpty = true;
+  final ir.Continuation continuation = null;
+  final Environment environment = null;
+
+  int _stateVariableIndex;
+  int _stateValue;
+  JumpCollector _breakJoin;
+
+  GotoJumpCollector(JumpTarget target, this._stateVariableIndex,
+      this._stateValue, this._breakJoin) : super.goto(target);
+
+  void addJump(IrBuilder builder,
+      [ir.Primitive value, SourceInformation sourceInformation]) {
+    isEmpty = false;
+    ir.Primitive constant = builder.buildIntegerConstant(_stateValue);
+    builder.environment.index2value[_stateVariableIndex] = constant;
+    builder.jumpTo(_breakJoin);
+  }
+}
+
 /// Function for building a node in the context of the current builder.
 typedef ir.Node BuildFunction(node);
 
@@ -532,7 +563,7 @@
 ///
 /// The IR fragment is an expression with a hole in it. The hole represents
 /// the focus where new expressions can be added. The fragment is implemented
-/// by [_root] which is the root of the expression and [_current] which is the
+/// by [root] which is the root of the expression and [_current] which is the
 /// expression that immediately contains the hole. Not all expressions have a
 /// hole (e.g., invocations, which always occur in tail position, do not have a
 /// hole). Expressions with a hole have a plug method.
@@ -559,7 +590,7 @@
   /// side effects.
   Map<Local, ir.MutableVariable> mutableVariables;
 
-  ir.Expression _root = null;
+  ir.Expression root = null;
   ir.Expression _current = null;
 
   GlobalProgramInformation get program => state.program;
@@ -613,7 +644,7 @@
     return mutableVariables[local];
   }
 
-  bool get isOpen => _root == null || _current != null;
+  bool get isOpen => root == null || _current != null;
 
   List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
                                         {ClosureScope closureScope,
@@ -640,8 +671,8 @@
   /// new value of current.
   void add(ir.Expression expr) {
     assert(isOpen);
-    if (_root == null) {
-      _root = _current = expr;
+    if (root == null) {
+      root = _current = expr;
     } else {
       _current = _current.plug(expr);
     }
@@ -789,8 +820,8 @@
     //     if condition (then, else)
     ir.Continuation thenContinuation = new ir.Continuation([]);
     ir.Continuation elseContinuation = new ir.Continuation([]);
-    thenContinuation.body = thenBuilder._root;
-    elseContinuation.body = elseBuilder._root;
+    thenContinuation.body = thenBuilder.root;
+    elseContinuation.body = elseBuilder.root;
     add(new ir.LetCont(join.continuation,
             new ir.LetCont.two(thenContinuation, elseContinuation,
                 new ir.Branch.strict(condition,
@@ -812,7 +843,7 @@
     _current = null;
   }
 
-  /// Create a [ir.FunctionDefinition] using [_root] as the body.
+  /// Create a [ir.FunctionDefinition] using [root] as the body.
   ///
   /// The protocol for building a function is:
   /// 1. Call [buildFunctionHeader].
@@ -825,7 +856,7 @@
         state.thisParameter,
         state.functionParameters,
         state.returnContinuation,
-        _root);
+        root);
   }
 
   /// Create a invocation of the [method] on the super class where the call
@@ -1107,17 +1138,17 @@
     // case that one of them is null, it must be the only one that is open
     // and thus contains the new hole in the context.  This case is handled
     // after the branch is plugged into the current hole.
-    thenContinuation.body = thenBuilder._root;
-    elseContinuation.body = elseBuilder._root;
+    thenContinuation.body = thenBuilder.root;
+    elseContinuation.body = elseBuilder.root;
 
     add(result);
     if (join == null) {
       // At least one subexpression is closed.
       if (thenBuilder.isOpen) {
-        if (thenBuilder._root != null) _current = thenBuilder._current;
+        if (thenBuilder.root != null) _current = thenBuilder._current;
         environment = thenBuilder.environment;
       } else if (elseBuilder.isOpen) {
-        if (elseBuilder._root != null) _current = elseBuilder._current;
+        if (elseBuilder.root != null) _current = elseBuilder._current;
         environment = elseBuilder.environment;
       } else {
         _current = null;
@@ -1243,16 +1274,16 @@
     // it is guaranteed that the updateBuilder has a non-empty term.
     if (hasContinues) {
       outerBodyBuilder.add(new ir.LetCont(continueCollector.continuation,
-          innerBodyBuilder._root));
-      continueCollector.continuation.body = updateBuilder._root;
+          innerBodyBuilder.root));
+      continueCollector.continuation.body = updateBuilder.root;
     } else {
-      outerBodyBuilder.add(innerBodyBuilder._root);
+      outerBodyBuilder.add(innerBodyBuilder.root);
     }
 
     // Create loop exit and body entry continuations and a branch to them.
     ir.Continuation exitContinuation = new ir.Continuation([]);
     ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = outerBodyBuilder._root;
+    bodyContinuation.body = outerBodyBuilder.root;
     // Note the order of continuations: the first one is the one that will
     // be filled by LetCont.plug.
     ir.LetCont branch =
@@ -1268,7 +1299,7 @@
     if (hasBreaks) {
       IrBuilder exitBuilder = makeDelimitedBuilder();
       exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder._root;
+      exitContinuation.body = exitBuilder.root;
       letBreak = new ir.LetCont(breakCollector.continuation, branch);
       add(letBreak);
       environment = breakCollector.environment;
@@ -1411,7 +1442,7 @@
     // in branch condition (body, exit)
     ir.Continuation exitContinuation = new ir.Continuation([]);
     ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = bodyBuilder._root;
+    bodyContinuation.body = bodyBuilder.root;
     // Note the order of continuations: the first one is the one that will
     // be filled by LetCont.plug.
     ir.LetCont branch =
@@ -1427,7 +1458,7 @@
     if (hasBreaks) {
       IrBuilder exitBuilder = makeDelimitedBuilder();
       exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder._root;
+      exitContinuation.body = exitBuilder.root;
       letBreak = new ir.LetCont(breakCollector.continuation, branch);
       add(letBreak);
       environment = breakCollector.environment;
@@ -1486,7 +1517,7 @@
     // Create body entry and loop exit continuations and a branch to them.
     ir.Continuation exitContinuation = new ir.Continuation([]);
     ir.Continuation bodyContinuation = new ir.Continuation([]);
-    bodyContinuation.body = bodyBuilder._root;
+    bodyContinuation.body = bodyBuilder.root;
     // Note the order of continuations: the first one is the one that will
     // be filled by LetCont.plug.
     ir.LetCont branch =
@@ -1502,7 +1533,7 @@
     if (hasBreaks) {
       IrBuilder exitBuilder = makeDelimitedBuilder();
       exitBuilder.jumpTo(breakCollector);
-      exitContinuation.body = exitBuilder._root;
+      exitContinuation.body = exitBuilder.root;
       letBreak = new ir.LetCont(breakCollector.continuation, branch);
       add(letBreak);
       environment = breakCollector.environment;
@@ -1569,18 +1600,18 @@
     ir.Continuation exitContinuation = new ir.Continuation([]);
     IrBuilder exitBuilder = continueBuilder.makeDelimitedBuilder();
     exitBuilder.jumpTo(breakCollector);
-    exitContinuation.body = exitBuilder._root;
+    exitContinuation.body = exitBuilder.root;
     ir.Continuation repeatContinuation = new ir.Continuation([]);
     IrBuilder repeatBuilder = continueBuilder.makeDelimitedBuilder();
     repeatBuilder.jumpTo(loop);
-    repeatContinuation.body = repeatBuilder._root;
+    repeatContinuation.body = repeatBuilder.root;
 
     continueBuilder.add(
         new ir.LetCont.two(exitContinuation, repeatContinuation,
             new ir.Branch.strict(condition,
                                  repeatContinuation,
                                  exitContinuation)));
-    continueCollector.continuation.body = continueBuilder._root;
+    continueCollector.continuation.body = continueBuilder.root;
 
     // Construct the loop continuation (i.e., the body and condition).
     // <Loop> =
@@ -1589,56 +1620,25 @@
     // in [[body]]; continue(v, ...)
     loopBuilder.add(
         new ir.LetCont(continueCollector.continuation,
-            bodyBuilder._root));
+            bodyBuilder.root));
 
     // And tie it all together.
-    add(new ir.LetCont(breakCollector.continuation, loopBuilder._root));
+    add(new ir.LetCont(breakCollector.continuation, loopBuilder.root));
     environment = breakCollector.environment;
   }
 
-  void buildSimpleSwitch(JumpTarget target,
-                         ir.Primitive value,
+  void buildSimpleSwitch(JumpCollector join,
                          List<SwitchCaseInfo> cases,
-                         SwitchCaseInfo defaultCase,
-                         Element error,
-                         SourceInformation sourceInformation) {
-    assert(isOpen);
-    JumpCollector join = new ForwardJumpCollector(environment, target: target);
-
+                         SubbuildFunction buildDefaultBody) {
     IrBuilder casesBuilder = makeDelimitedBuilder();
-    casesBuilder.state.breakCollectors.add(join);
     for (SwitchCaseInfo caseInfo in cases) {
-      buildConditionsFrom(int index) => (IrBuilder builder) {
-        ir.Primitive comparison = builder.buildIdentical(
-            value, caseInfo.constants[index]);
-        return (index == caseInfo.constants.length - 1)
-            ? comparison
-            : builder.buildLogicalOperator(
-                comparison, buildConditionsFrom(index + 1), isLazyOr: true);
-      };
-
-      ir.Primitive condition = buildConditionsFrom(0)(casesBuilder);
+      ir.Primitive condition = caseInfo.buildCondition(casesBuilder);
       IrBuilder thenBuilder = makeDelimitedBuilder();
       caseInfo.buildBody(thenBuilder);
-      if (thenBuilder.isOpen) {
-        // It is a runtime error to reach the end of a switch case, unless
-        // it is the last case.
-        if (caseInfo == cases.last && defaultCase == null) {
-          thenBuilder.jumpTo(join);
-        } else {
-          ir.Primitive exception = thenBuilder.buildInvokeStatic(
-              error,
-              new Selector.fromElement(error),
-              <ir.Primitive>[],
-              sourceInformation);
-          thenBuilder.buildThrow(exception);
-        }
-      }
-
       ir.Continuation thenContinuation = new ir.Continuation([]);
-      thenContinuation.body = thenBuilder._root;
+      thenContinuation.body = thenBuilder.root;
       ir.Continuation elseContinuation = new ir.Continuation([]);
-      // A LetCont.many term has a hole as the body of the first listed
+      // A LetCont.two term has a hole as the body of the first listed
       // continuation, to be plugged by the translation.  Therefore put the
       // else continuation first.
       casesBuilder.add(
@@ -1648,18 +1648,17 @@
                                    elseContinuation)));
     }
 
-    if (defaultCase != null) {
-      defaultCase.buildBody(casesBuilder);
+    if (buildDefaultBody == null) {
+      casesBuilder.jumpTo(join);
+    } else {
+      buildDefaultBody(casesBuilder);
     }
-    if (casesBuilder.isOpen) casesBuilder.jumpTo(join);
-
-    casesBuilder.state.breakCollectors.removeLast();
 
     if (!join.isEmpty) {
-      add(new ir.LetCont(join.continuation, casesBuilder._root));
+      add(new ir.LetCont(join.continuation, casesBuilder.root));
       environment = join.environment;
-    } else if (casesBuilder._root != null) {
-      add(casesBuilder._root);
+    } else if (casesBuilder.root != null) {
+      add(casesBuilder.root);
       _current = casesBuilder._current;
       environment = casesBuilder.environment;
     } else {
@@ -1721,11 +1720,11 @@
 
     List<ir.Parameter> catchParameters = buildCatch(catchBuilder, join);
     ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
-    catchContinuation.body = catchBuilder._root;
+    catchContinuation.body = catchBuilder.root;
     tryCatchBuilder.add(
-        new ir.LetHandler(catchContinuation, tryBuilder._root));
+        new ir.LetHandler(catchContinuation, tryBuilder.root));
 
-    leaveTryCatch(this, join, tryCatchBuilder._root);
+    leaveTryCatch(this, join, tryCatchBuilder.root);
   }
 
   /// Translates a try/catch.
@@ -1829,7 +1828,7 @@
         }
         clause.buildCatchBlock(clauseBuilder);
         if (clauseBuilder.isOpen) clauseBuilder.jumpTo(join);
-        return clauseBuilder._root;
+        return clauseBuilder.root;
       }
 
       // Expand multiple catch clauses into an explicit if/then/else.  Iterate
@@ -1855,7 +1854,7 @@
             new ir.Branch.strict(typeMatches,
                                  thenContinuation,
                                  elseContinuation)));
-        catchBody = checkBuilder._root;
+        catchBody = checkBuilder.root;
       }
       builder.add(catchBody);
 
@@ -1960,7 +1959,7 @@
         IrBuilder builder = makeDelimitedBuilder(newCollector.environment);
         buildFinallyBlock(builder);
         if (builder.isOpen) builder.jumpTo(originalCollector);
-        newCollector.continuation.body = builder._root;
+        newCollector.continuation.body = builder.root;
         exits.add(newCollector.continuation);
       }
       for (int i = 0; i < newBreaks.length; ++i) {
@@ -1974,7 +1973,7 @@
         ir.Primitive value = builder.environment.discard(1);
         buildFinallyBlock(builder);
         if (builder.isOpen) builder.buildReturn(value: value);
-        newReturn.continuation.body = builder._root;
+        newReturn.continuation.body = builder.root;
         exits.add(newReturn.continuation);
       }
       builder.add(new ir.LetCont.many(exits, body));
@@ -2062,7 +2061,8 @@
     ir.Primitive value = buildForeignCode(
         js.js.uncachedExpressionTemplate(code),
         arguments,
-        behavior);
+        behavior,
+        type: program.getTypeMaskForNativeFunction(function));
     buildReturn(value: value, sourceInformation: source);
   }
 
@@ -2100,10 +2100,10 @@
     bool hasBreaks = !join.isEmpty;
     if (hasBreaks) {
       if (innerBuilder.isOpen) innerBuilder.jumpTo(join);
-      add(new ir.LetCont(join.continuation, innerBuilder._root));
+      add(new ir.LetCont(join.continuation, innerBuilder.root));
       environment = join.environment;
-    } else if (innerBuilder._root != null) {
-      add(innerBuilder._root);
+    } else if (innerBuilder.root != null) {
+      add(innerBuilder.root);
       _current = innerBuilder._current;
       environment = innerBuilder.environment;
     } else {
@@ -2239,8 +2239,8 @@
     ir.Continuation leftFalseContinuation = new ir.Continuation([]);
     ir.Continuation rightTrueContinuation = new ir.Continuation([]);
     ir.Continuation rightFalseContinuation = new ir.Continuation([]);
-    rightTrueContinuation.body = rightTrueBuilder._root;
-    rightFalseContinuation.body = rightFalseBuilder._root;
+    rightTrueContinuation.body = rightTrueBuilder.root;
+    rightFalseContinuation.body = rightFalseBuilder.root;
     // The right subexpression has two continuations.
     rightBuilder.add(
         new ir.LetCont.two(rightTrueContinuation, rightFalseContinuation,
@@ -2251,11 +2251,11 @@
     // either the right subexpression or an invocation of the join-point
     // continuation.
     if (isLazyOr) {
-      leftTrueContinuation.body = emptyBuilder._root;
-      leftFalseContinuation.body = rightBuilder._root;
+      leftTrueContinuation.body = emptyBuilder.root;
+      leftFalseContinuation.body = rightBuilder.root;
     } else {
-      leftTrueContinuation.body = rightBuilder._root;
-      leftFalseContinuation.body = emptyBuilder._root;
+      leftTrueContinuation.body = rightBuilder.root;
+      leftFalseContinuation.body = emptyBuilder.root;
     }
 
     add(new ir.LetCont(join.continuation,
@@ -2411,7 +2411,7 @@
       arguments.add(value);
     }
     return addPrimitive(new ir.CreateInstance(
-        classElement, arguments, const <ir.Primitive>[], sourceInformation));
+        classElement, arguments, null, sourceInformation));
   }
 
   /// Create a read access of [local] function, variable, or parameter.
@@ -2577,7 +2577,8 @@
         ir.Primitive value = buildTypeVariableAccess(variable);
         arguments.add(value);
       });
-      return addPrimitive(new ir.TypeExpression(type, arguments));
+      return addPrimitive(new ir.TypeExpression(ir.TypeExpressionKind.COMPLETE,
+                                                type, arguments));
     } else if (type.treatAsDynamic) {
       return buildNullConstant();
     } else {
@@ -2634,9 +2635,19 @@
   ir.Primitive buildForeignCode(js.Template codeTemplate,
                                 List<ir.Primitive> arguments,
                                 NativeBehavior behavior,
-                                {Element dependency}) {
+                                {Element dependency,
+                                 TypeMask type}) {
     assert(behavior != null);
-    TypeMask type = program.getTypeMaskForForeign(behavior);
+    if (type == null) {
+      type = program.getTypeMaskForForeign(behavior);
+    }
+    if (js.isIdentityTemplate(codeTemplate) && !program.isArrayType(type)) {
+      // JS expression is just a refinement.
+      // Do not do this for arrays - those are special because array types can
+      // change after creation.  The input and output must therefore be modeled
+      // as distinct values.
+      return addPrimitive(new ir.Refinement(arguments.single, type));
+    }
     ir.Primitive result = addPrimitive(new ir.ForeignCode(
         codeTemplate,
         type,
@@ -2834,10 +2845,8 @@
 }
 
 class SwitchCaseInfo {
-  final List<ir.Primitive> constants = <ir.Primitive>[];
+  final SubbuildFunction buildCondition;
   final SubbuildFunction buildBody;
 
-  SwitchCaseInfo(this.buildBody);
-
-  void addConstant(ir.Primitive constant) => constants.add(constant);
+  SwitchCaseInfo(this.buildCondition, this.buildBody);
 }
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 5c55f63..f98c9dd 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
@@ -382,7 +382,7 @@
     IrBuilder builder = getBuilderFor(constructor);
 
     final bool requiresTypeInformation =
-    builder.program.requiresRuntimeTypesFor(classElement);
+        builder.program.requiresRuntimeTypesFor(classElement);
 
     return withBuilder(builder, () {
       // Setup parameters and create a box if anything is captured.
@@ -410,11 +410,15 @@
           closureScope: getClosureScopeForFunction(constructor));
 
       // Create a list of the values of all type argument parameters, if any.
-      List<ir.Primitive> typeInformation;
+      ir.Primitive typeInformation;
       if (requiresTypeInformation) {
-        typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex);
+        typeInformation = new ir.TypeExpression(
+            ir.TypeExpressionKind.INSTANCE,
+            classElement.thisType,
+            irParameters.sublist(firstTypeArgumentParameterIndex));
+        irBuilder.add(new ir.LetPrim(typeInformation));
       } else {
-        typeInformation = const <ir.Primitive>[];
+        typeInformation = null;
       }
 
       // -- Load values for type variables declared on super classes --
@@ -753,7 +757,8 @@
     TryBoxedVariables variables = _analyzeTryBoxedVariables(node);
     tryStatements = variables.tryStatements;
     IrBuilder builder = getBuilderFor(element);
-    return withBuilder(builder, () => _makeFunctionBody(element, node));
+    return withBuilder(builder,
+        () => _makeFunctionBody(builder, element, node));
   }
 
   ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
@@ -875,17 +880,24 @@
     }
   }
 
-  ir.FunctionDefinition _makeFunctionBody(FunctionElement element,
-                                          ast.FunctionExpression node) {
+  ir.FunctionDefinition _makeFunctionBody(
+      IrBuilder builder,
+      FunctionElement element,
+      ast.FunctionExpression node) {
     FunctionSignature signature = element.functionSignature;
     List<Local> parameters = <Local>[];
     signature.orderedForEachParameter(
         (LocalParameterElement e) => parameters.add(e));
 
+    bool requiresRuntimeTypes = false;
     if (element.isFactoryConstructor) {
-      // Type arguments are passed in as extra parameters.
-      for (DartType typeVariable in element.enclosingClass.typeVariables) {
-        parameters.add(new closure.TypeVariableLocal(typeVariable, element));
+      requiresRuntimeTypes =
+          builder.program.requiresRuntimeTypesFor(element.enclosingElement);
+      if (requiresRuntimeTypes) {
+        // Type arguments are passed in as extra parameters.
+        for (DartType typeVariable in element.enclosingClass.typeVariables) {
+          parameters.add(new closure.TypeVariableLocal(typeVariable, element));
+        }
       }
     }
 
@@ -893,7 +905,45 @@
                                   closureScope: getClosureScopeForNode(node),
                                   env: getClosureEnvironment());
 
-    visit(node.body);
+    if (element == helpers.jsArrayTypedConstructor) {
+      // Generate a body for JSArray<E>.typed(allocation):
+      //
+      //    t1 = setRuntimeTypeInfo(allocation, TypeExpression($E));
+      //    return Refinement(t1, <JSArray>);
+      //
+      assert(parameters.length == 1 || parameters.length == 2);
+      ir.Primitive allocation = irBuilder.buildLocalGet(parameters[0]);
+      ClassElement classElement = element.enclosingElement;
+
+      // Only call setRuntimeTypeInfo if JSArray requires the type parameter.
+      if (requiresRuntimeTypes) {
+        assert(parameters.length == 2);
+        closure.TypeVariableLocal typeParameter = parameters[1];
+        ir.Primitive typeArgument =
+            irBuilder.buildTypeVariableAccess(typeParameter.typeVariable);
+
+        ir.Primitive typeInformation = irBuilder.addPrimitive(
+            new ir.TypeExpression(ir.TypeExpressionKind.INSTANCE,
+                                  element.enclosingClass.thisType,
+                                  <ir.Primitive>[typeArgument]));
+
+        MethodElement helper = helpers.setRuntimeTypeInfo;
+        CallStructure callStructure = CallStructure.TWO_ARGS;
+        Selector selector = new Selector.call(helper.memberName, callStructure);
+        allocation = irBuilder.buildInvokeStatic(
+            helper, selector, <ir.Primitive>[allocation, typeInformation],
+            sourceInformationBuilder.buildGeneric(node));
+      }
+
+      ir.Primitive refinement = irBuilder.addPrimitive(
+          new ir.Refinement(allocation, typeMaskSystem.arrayType));
+
+      irBuilder.buildReturn(value: refinement,
+          sourceInformation:
+              sourceInformationBuilder.buildImplicitReturn(element));
+    } else {
+      visit(node.body);
+    }
     return irBuilder.makeFunctionDefinition();
   }
 
@@ -1172,44 +1222,270 @@
   }
 
   visitSwitchStatement(ast.SwitchStatement node) {
+    // Dart switch cases can be labeled and be the target of continue from
+    // within the switch.  Such cases are 'recursive'.  If there are any
+    // recursive cases, we implement the switch using a pair of switches with
+    // the second one switching over a state variable in a loop.  The first
+    // switch contains the non-recursive cases, and the second switch contains
+    // the recursive ones.
+    //
+    // For example, for the Dart switch:
+    //
+    // switch (E) {
+    //   case 0:
+    //     BODY0;
+    //     break;
+    //   LABEL0: case 1:
+    //     BODY1;
+    //     break;
+    //   case 2:
+    //     BODY2;
+    //     continue LABEL1;
+    //   LABEL1: case 3:
+    //     BODY3;
+    //     continue LABEL0;
+    //   default:
+    //     BODY4;
+    // }
+    //
+    // We translate it as if it were the JavaScript:
+    //
+    // var state = -1;
+    // switch (E) {
+    //   case 0:
+    //     BODY0;
+    //     break;
+    //   case 1:
+    //     state = 0;  // Recursive, label ID = 0.
+    //     break;
+    //   case 2:
+    //     BODY2;
+    //     state = 1;  // Continue to label ID = 1.
+    //     break;
+    //   case 3:
+    //     state = 1;  // Recursive, label ID = 1.
+    //     break;
+    //   default:
+    //     BODY4;
+    // }
+    // L: while (state != -1) {
+    //   case 0:
+    //     BODY1;
+    //     break L;  // Break from switch becomes break from loop.
+    //   case 1:
+    //     BODY2;
+    //     state = 0;  // Continue to label ID = 0.
+    //     break;
+    // }
     assert(irBuilder.isOpen);
-    // We do not handle switch statements with continue to labeled cases.
-    for (ast.SwitchCase switchCase in node.cases) {
+    // Preprocess: compute a list of cases that are the target of continue.
+    // These are the so-called 'recursive' cases.
+    List<JumpTarget> continueTargets = <JumpTarget>[];
+    List<ast.Node> switchCases = node.cases.nodes.toList();
+    for (ast.SwitchCase switchCase in switchCases) {
       for (ast.Node labelOrCase in switchCase.labelsAndCases) {
         if (labelOrCase is ast.Label) {
           LabelDefinition definition = elements.getLabelDefinition(labelOrCase);
           if (definition != null && definition.isContinueTarget) {
-            return giveup(node, "continue to a labeled switch case");
+            continueTargets.add(definition.target);
           }
         }
       }
     }
 
-    // Each switch case contains a list of interleaved labels and expressions
-    // and a non-empty body.  We can ignore the labels because they are not
-    // jump targets.
-    List<SwitchCaseInfo> cases = <SwitchCaseInfo>[];
-    SwitchCaseInfo defaultCase;
-    for (ast.SwitchCase switchCase in node.cases) {
-      SwitchCaseInfo caseInfo =
-          new SwitchCaseInfo(subbuildSequence(switchCase.statements));
-      if (switchCase.isDefaultCase) {
-        defaultCase = caseInfo;
-      } else {
-        cases.add(caseInfo);
-        for (ast.Node labelOrCase in switchCase.labelsAndCases) {
-          if (labelOrCase is ast.CaseMatch) {
-            ir.Primitive constant = translateConstant(labelOrCase.expression);
-            caseInfo.addConstant(constant);
-          }
-        }
-      }
+    // If any cases are continue targets, use an anonymous local value to
+    // implement a state machine.  The initial value is -1.
+    ir.Primitive initial;
+    int stateIndex;
+    if (continueTargets.isNotEmpty) {
+      initial = irBuilder.buildIntegerConstant(-1);
+      stateIndex = irBuilder.environment.length;
+      irBuilder.environment.extend(null, initial);
     }
+
+    // Use a simple switch for the non-recursive cases.  A break will go to the
+    // join-point after the switch.  A continue to a labeled case will assign
+    // to the state variable and go to the join-point.
     ir.Primitive value = visit(node.expression);
-    JumpTarget target = elements.getTargetDefinition(node);
-    Element error = helpers.fallThroughError;
-    irBuilder.buildSimpleSwitch(target, value, cases, defaultCase, error,
-        sourceInformationBuilder.buildGeneric(node));
+    JumpCollector join = new ForwardJumpCollector(irBuilder.environment,
+        target: elements.getTargetDefinition(node));
+    irBuilder.state.breakCollectors.add(join);
+    for (int i = 0; i < continueTargets.length; ++i) {
+      // The state value is i, the case's position in the list of recursive
+      // cases.
+      irBuilder.state.continueCollectors.add(new GotoJumpCollector(
+          continueTargets[i], stateIndex, i, join));
+    }
+
+    // For each non-default case use a pair of functions, one to translate the
+    // condition and one to translate the body.  For the default case use a
+    // function to translate the body.  Use continueTargetIterator as a pointer
+    // to the next recursive case.
+    Iterator<JumpTarget> continueTargetIterator = continueTargets.iterator;
+    continueTargetIterator.moveNext();
+    List<SwitchCaseInfo> cases = <SwitchCaseInfo>[];
+    SubbuildFunction buildDefaultBody;
+    for (ast.SwitchCase switchCase in switchCases) {
+      JumpTarget nextContinueTarget = continueTargetIterator.current;
+      if (switchCase.isDefaultCase) {
+        if (nextContinueTarget != null &&
+            switchCase == nextContinueTarget.statement) {
+          // In this simple switch, recursive cases are as if they immediately
+          // continued to themselves.
+          buildDefaultBody = nested(() {
+            irBuilder.buildContinue(nextContinueTarget);
+          });
+          continueTargetIterator.moveNext();
+        } else {
+          // Non-recursive cases consist of the translation of the body.
+          // For the default case, there is implicitly a break if control
+          // flow reaches the end.
+          buildDefaultBody = nested(() {
+            irBuilder.buildSequence(switchCase.statements, visit);
+            if (irBuilder.isOpen) irBuilder.jumpTo(join);
+          });
+        }
+        continue;
+      }
+
+      ir.Primitive buildCondition(IrBuilder builder) {
+        // There can be multiple cases sharing the same body, because empty
+        // cases are allowed to fall through to the next one.  Each case is
+        // a comparison, build a short-circuited disjunction of all of them.
+        return withBuilder(builder, () {
+          ir.Primitive condition;
+          for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+            if (labelOrCase is ast.CaseMatch) {
+              ir.Primitive buildComparison() {
+                ir.Primitive constant =
+                    translateConstant(labelOrCase.expression);
+                return irBuilder.buildIdentical(value, constant);
+              }
+
+              if (condition == null) {
+                condition = buildComparison();
+              } else {
+                condition = irBuilder.buildLogicalOperator(condition,
+                    nested(buildComparison), isLazyOr: true);
+              }
+            }
+          }
+          return condition;
+        });
+      }
+
+      SubbuildFunction buildBody;
+      if (nextContinueTarget != null &&
+          switchCase == nextContinueTarget.statement) {
+        // Recursive cases are as if they immediately continued to themselves.
+        buildBody = nested(() {
+          irBuilder.buildContinue(nextContinueTarget);
+        });
+        continueTargetIterator.moveNext();
+      } else {
+        // Non-recursive cases consist of the translation of the body.  It is a
+        // runtime error if control-flow reaches the end of the body of any but
+        // the last case.
+        buildBody = (IrBuilder builder) {
+          withBuilder(builder, () {
+            irBuilder.buildSequence(switchCase.statements, visit);
+            if (irBuilder.isOpen) {
+              if (switchCase == switchCases.last) {
+                irBuilder.jumpTo(join);
+              } else {
+                Element error = helpers.fallThroughError;
+                ir.Primitive exception = irBuilder.buildInvokeStatic(
+                    error,
+                    new Selector.fromElement(error),
+                    <ir.Primitive>[],
+                    sourceInformationBuilder.buildGeneric(node));
+                irBuilder.buildThrow(exception);
+              }
+            }
+          });
+          return null;
+        };
+      }
+
+      cases.add(new SwitchCaseInfo(buildCondition, buildBody));
+    }
+
+    irBuilder.buildSimpleSwitch(join, cases, buildDefaultBody);
+    irBuilder.state.breakCollectors.removeLast();
+    irBuilder.state.continueCollectors.length -= continueTargets.length;
+    if (continueTargets.isEmpty) return;
+
+    // If there were recursive cases build a while loop whose body is a
+    // switch containing (only) the recursive cases.  The condition is
+    // 'state != initialValue' so the loop is not taken when the state variable
+    // has not been assigned.
+    //
+    // 'loop' is the join-point of the exits from the inner switch which will
+    // perform another iteration of the loop.  'exit' is the join-point of the
+    // breaks from the switch, outside the loop.
+    JumpCollector loop = new ForwardJumpCollector(irBuilder.environment);
+    JumpCollector exit = new ForwardJumpCollector(irBuilder.environment,
+        target: elements.getTargetDefinition(node));
+    irBuilder.state.breakCollectors.add(exit);
+    for (int i = 0; i < continueTargets.length; ++i) {
+      irBuilder.state.continueCollectors.add(new GotoJumpCollector(
+          continueTargets[i], stateIndex, i, loop));
+    }
+    cases.clear();
+    for (int i = 0; i < continueTargets.length; ++i) {
+      // The conditions compare to the recursive case index.
+      ir.Primitive buildCondition(IrBuilder builder) {
+        ir.Primitive constant = builder.buildIntegerConstant(i);
+        return builder.buildIdentical(
+            builder.environment.index2value[stateIndex], constant);
+      }
+
+      ir.Primitive buildBody(IrBuilder builder) {
+        withBuilder(builder, () {
+          ast.SwitchCase switchCase = continueTargets[i].statement;
+          irBuilder.buildSequence(switchCase.statements, visit);
+          if (irBuilder.isOpen) {
+            if (switchCase == switchCases.last) {
+              irBuilder.jumpTo(exit);
+            } else {
+              Element error = helpers.fallThroughError;
+              ir.Primitive exception = irBuilder.buildInvokeStatic(
+                  error,
+                  new Selector.fromElement(error),
+                  <ir.Primitive>[],
+                  sourceInformationBuilder.buildGeneric(node));
+              irBuilder.buildThrow(exception);
+            }
+          }
+        });
+        return null;
+      }
+
+      cases.add(new SwitchCaseInfo(buildCondition, buildBody));
+    }
+
+    // A loop with a simple switch in the body.
+    IrBuilder whileBuilder = irBuilder.makeDelimitedBuilder();
+    whileBuilder.buildWhile(
+        buildCondition: (IrBuilder builder) {
+          ir.Primitive condition = builder.buildIdentical(
+              builder.environment.index2value[stateIndex], initial);
+          return builder.buildNegation(condition);
+        },
+        buildBody: (IrBuilder builder) {
+          builder.buildSimpleSwitch(loop, cases, null);
+        });
+    // Jump to the exit continuation.  This jump is the body of the loop exit
+    // continuation, so the loop exit continuation can be eta-reduced.  The
+    // jump is here for simplicity because `buildWhile` does not expose the
+    // loop's exit continuation directly and has already emitted all jumps
+    // to it anyway.
+    whileBuilder.jumpTo(exit);
+    irBuilder.add(new ir.LetCont(exit.continuation, whileBuilder.root));
+    irBuilder.environment = exit.environment;
+    irBuilder.environment.discard(1);  // Discard the state variable.
+    irBuilder.state.breakCollectors.removeLast();
+    irBuilder.state.continueCollectors.length -= continueTargets.length;
   }
 
   visitTryStatement(ast.TryStatement node) {
@@ -1325,8 +1601,25 @@
     }
     List<ir.Primitive> values = node.elements.nodes.mapToList(visit);
     InterfaceType type = elements.getType(node);
-    return irBuilder.buildListLiteral(type, values,
-        allocationSiteType: getAllocationSiteType(node));
+    TypeMask allocationSiteType = getAllocationSiteType(node);
+    // TODO(sra): In checked mode, the elements must be checked as though
+    // operator[]= is called.
+    ir.Primitive list = irBuilder.buildListLiteral(type, values,
+          allocationSiteType: allocationSiteType);
+    if (type.treatAsRaw) return list;
+    // Call JSArray<E>.typed(allocation) to install the reified type.
+    ConstructorElement constructor = helpers.jsArrayTypedConstructor;
+    ir.Primitive tagged = irBuilder.buildConstructorInvocation(
+        constructor.effectiveTarget,
+        CallStructure.ONE_ARG,
+        constructor.computeEffectiveTargetType(type),
+        <ir.Primitive>[list],
+        sourceInformationBuilder.buildNew(node));
+
+    if (allocationSiteType == null) return tagged;
+
+    return irBuilder.addPrimitive(
+        new ir.Refinement(tagged, allocationSiteType));
   }
 
   ir.Primitive visitLiteralMap(ast.LiteralMap node) {
@@ -1334,12 +1627,48 @@
     if (node.isConst) {
       return translateConstant(node);
     }
+
     InterfaceType type = elements.getType(node);
-    List<ir.LiteralMapEntry> entries =
-        node.entries.nodes.mapToList((ast.LiteralMapEntry e) {
-          return new ir.LiteralMapEntry(visit(e.key), visit(e.value));
-        });
-    return irBuilder.addPrimitive(new ir.LiteralMap(type, entries));
+
+    if (node.entries.nodes.isEmpty) {
+      if (type.treatAsRaw) {
+        return irBuilder.buildStaticFunctionInvocation(
+            helpers.mapLiteralUntypedEmptyMaker,
+            <ir.Primitive>[],
+            sourceInformation: sourceInformationBuilder.buildNew(node));
+      } else {
+        ConstructorElement constructor = helpers.mapLiteralConstructorEmpty;
+        return irBuilder.buildConstructorInvocation(
+            constructor.effectiveTarget,
+            CallStructure.NO_ARGS,
+            constructor.computeEffectiveTargetType(type),
+            <ir.Primitive>[],
+            sourceInformationBuilder.buildNew(node));
+      }
+    }
+
+    List<ir.Primitive> keysAndValues = <ir.Primitive>[];
+    for (ast.LiteralMapEntry entry in node.entries.nodes.toList()) {
+      keysAndValues.add(visit(entry.key));
+      keysAndValues.add(visit(entry.value));
+    }
+    ir.Primitive keysAndValuesList =
+        irBuilder.buildListLiteral(null, keysAndValues);
+
+    if (type.treatAsRaw) {
+      return irBuilder.buildStaticFunctionInvocation(
+          helpers.mapLiteralUntypedMaker,
+          <ir.Primitive>[keysAndValuesList],
+          sourceInformation: sourceInformationBuilder.buildNew(node));
+    } else {
+      ConstructorElement constructor = helpers.mapLiteralConstructor;
+      return irBuilder.buildConstructorInvocation(
+          constructor.effectiveTarget,
+          CallStructure.ONE_ARG,
+          constructor.computeEffectiveTargetType(type),
+          <ir.Primitive>[keysAndValuesList],
+          sourceInformationBuilder.buildNew(node));
+    }
   }
 
   ir.Primitive visitLiteralSymbol(ast.LiteralSymbol node) {
@@ -1869,7 +2198,10 @@
 
     List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
     // Use default values from the effective target, not the immediate target.
-    ConstructorElement target = constructor.effectiveTarget;
+    ConstructorElement target = constructor.implementation;
+    while (target.isRedirectingFactory && !target.isCyclicRedirection) {
+      target = target.effectiveTarget.implementation;
+    }
 
     callStructure = normalizeStaticArguments(callStructure, target, arguments);
     TypeMask allocationSiteType;
@@ -1880,10 +2212,11 @@
         Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
       allocationSiteType = getAllocationSiteType(send);
     }
+    ConstructorElement constructorImplementation = constructor.implementation;
     return irBuilder.buildConstructorInvocation(
         target,
         callStructure,
-        constructor.computeEffectiveTargetType(type),
+        constructorImplementation.computeEffectiveTargetType(type),
         arguments,
         sourceInformationBuilder.buildNew(node),
         allocationSiteType: allocationSiteType);
@@ -2900,7 +3233,7 @@
         return irBuilder.buildForeignCode(
             js.js.parseForeignJS(backend.namer.staticStateHolder),
             const <ir.Primitive>[],
-            NativeBehavior.PURE);
+            NativeBehavior.DEPENDS_OTHER);
 
       case 'JS_SET_STATIC_STATE':
         validateArgumentCount(exactly: 1);
@@ -2910,7 +3243,7 @@
         return irBuilder.buildForeignCode(
             js.js.parseForeignJS("$isolateName = #"),
             <ir.Primitive>[value],
-            NativeBehavior.PURE);
+            NativeBehavior.CHANGES_OTHER);
 
       case 'JS_CALL_IN_ISOLATE':
         validateArgumentCount(exactly: 2);
@@ -3544,6 +3877,14 @@
     return TypeMaskFactory.fromNativeBehavior(behavior, _compiler);
   }
 
+  bool isArrayType(TypeMask type) {
+    return type.satisfies(_backend.helpers.jsArrayClass, _compiler.world);
+  }
+
+  TypeMask getTypeMaskForNativeFunction(FunctionElement function) {
+    return  _compiler.typesTask.getGuaranteedReturnTypeOfElement(function);
+  }
+
   FieldElement locateSingleField(Selector selector, TypeMask type) {
     return _compiler.world.locateSingleField(selector, type);
   }
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 49c8a6b..e73dd84 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -5,6 +5,7 @@
 
 import 'dart:collection';
 import 'cps_fragment.dart' show CpsFragment;
+import 'cps_ir_nodes_sexpr.dart';
 import '../constants/values.dart' as values;
 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
 import '../elements/elements.dart';
@@ -39,6 +40,37 @@
   ///
   /// All constructors call this method to initialize parent pointers.
   void setParentPointers();
+
+  /// Returns the SExpression for the subtree rooted at this node.
+  ///
+  /// [annotations] maps strings to nodes and/or nodes to values that will be
+  /// converted to strings. Each binding causes the annotation to appear on the
+  /// given node.
+  ///
+  /// For example, the following could be used to diagnose a problem with nodes
+  /// not appearing in an environment map:
+  ///
+  ///     if (environment[node] == null)
+  ///       root.debugPrint({
+  ///         'currentNode': node,
+  ///         'caller': someContinuation
+  ///       });
+  ///       throw 'Node was not in environment';
+  ///     }
+  ///
+  /// If two strings map to the same node, it will be given both annotations.
+  ///
+  /// Avoid using nodes as keys if there is a chance that two keys are the
+  /// same node.
+  String debugString([Map annotations]) {
+    return new SExpressionStringifier()
+        .withAnnotations(annotations).visit(this);
+  }
+
+  /// Prints the result of [debugString].
+  void debugPrint([Map annotations]) {
+    print(debugString(annotations));
+  }
 }
 
 /// Expressions can be evaluated, and may diverge, throw, and/or have
@@ -195,9 +227,9 @@
   }
 }
 
-class EffectiveUseIterable extends IterableBase<Reference<Primitive>> {
+class RefinedUseIterable extends IterableBase<Reference<Primitive>> {
   Primitive primitive;
-  EffectiveUseIterable(this.primitive);
+  RefinedUseIterable(this.primitive);
   EffectiveUseIterator get iterator => new EffectiveUseIterator(primitive);
 }
 
@@ -238,6 +270,9 @@
   // TODO(asgerf): Also do this for [TypeCast]?
   Primitive get effectiveDefinition => this;
 
+  /// Like [effectiveDefinition] but only unfolds [Refinement] nodes.
+  Primitive get unrefined => this;
+
   /// True if the two primitives are (refinements of) the same value.
   bool sameValue(Primitive other) {
     return effectiveDefinition == other.effectiveDefinition;
@@ -252,15 +287,15 @@
   /// - References to this primitive created during iteration will not be seen.
   /// - References to a refinement of this primitive may not be created during
   ///   iteration.
-  EffectiveUseIterable get effectiveUses => new EffectiveUseIterable(this);
+  RefinedUseIterable get refinedUses => new RefinedUseIterable(this);
 
-  bool get hasMultipleEffectiveUses {
-    Iterator it = effectiveUses.iterator;
+  bool get hasMultipleRefinedUses {
+    Iterator it = refinedUses.iterator;
     return it.moveNext() && it.moveNext();
   }
 
-  bool get hasNoEffectiveUses {
-    return effectiveUses.isEmpty;
+  bool get hasNoRefinedUses {
+    return refinedUses.isEmpty;
   }
 
   /// Unlinks all references contained in this node.
@@ -734,6 +769,8 @@
 
   Primitive get effectiveDefinition => value.definition.effectiveDefinition;
 
+  Primitive get unrefined => value.definition.unrefined;
+
   void setParentPointers() {
     value.parent = this;
   }
@@ -1446,15 +1483,17 @@
   /// May be `null` to indicate that no type information is needed because the
   /// compiler determined that the type information for instances of this class
   /// is not needed at runtime.
-  final List<Reference<Primitive>> typeInformation;
+  final Reference<Primitive> typeInformation;
 
   final SourceInformation sourceInformation;
 
   CreateInstance(this.classElement, List<Primitive> arguments,
-      List<Primitive> typeInformation,
+      Primitive typeInformation,
       this.sourceInformation)
       : this.arguments = _referenceList(arguments),
-        this.typeInformation = _referenceList(typeInformation);
+        this.typeInformation = typeInformation == null
+            ? null
+            : new Reference<Primitive>(typeInformation);
 
   accept(Visitor visitor) => visitor.visitCreateInstance(this);
 
@@ -1466,7 +1505,7 @@
 
   void setParentPointers() {
     _setParentsOnList(arguments, this);
-    if (typeInformation != null) _setParentsOnList(typeInformation, this);
+    if (typeInformation != null) typeInformation.parent = this;
   }
 }
 
@@ -1529,12 +1568,12 @@
 
 class ForeignCode extends UnsafePrimitive {
   final js.Template codeTemplate;
-  final TypeMask type;
+  final TypeMask storedType;
   final List<Reference<Primitive>> arguments;
   final native.NativeBehavior nativeBehavior;
   final FunctionElement dependency;
 
-  ForeignCode(this.codeTemplate, this.type, List<Primitive> arguments,
+  ForeignCode(this.codeTemplate, this.storedType, List<Primitive> arguments,
       this.nativeBehavior, {this.dependency})
       : this.arguments = _referenceList(arguments);
 
@@ -1596,35 +1635,6 @@
   }
 }
 
-class LiteralMapEntry {
-  final Reference<Primitive> key;
-  final Reference<Primitive> value;
-
-  LiteralMapEntry(Primitive key, Primitive value)
-      : this.key = new Reference<Primitive>(key),
-        this.value = new Reference<Primitive>(value);
-}
-
-class LiteralMap extends Primitive {
-  final InterfaceType dartType;
-  final List<LiteralMapEntry> entries;
-
-  LiteralMap(this.dartType, this.entries);
-
-  accept(Visitor visitor) => visitor.visitLiteralMap(this);
-
-  bool get hasValue => true;
-  bool get isSafeForElimination => true;
-  bool get isSafeForReordering => true;
-
-  void setParentPointers() {
-    for (LiteralMapEntry entry in entries) {
-      entry.key.parent = this;
-      entry.value.parent = this;
-    }
-  }
-}
-
 class Parameter extends Primitive {
   Parameter(Entity hint) {
     super.hint = hint;
@@ -1651,8 +1661,25 @@
   // A continuation is recursive if it has any recursive invocations.
   bool isRecursive;
 
+  /// True if this is the return continuation.  The return continuation is bound
+  /// by [FunctionDefinition].
   bool get isReturnContinuation => body == null;
 
+  /// True if this is a branch continuation.  Branch continuations are bound
+  /// by [LetCont] and can only have one use.
+  bool get isBranchContinuation => firstRef?.parent is Branch;
+
+  /// True if this is the exception handler bound by a [LetHandler].
+  bool get isHandlerContinuation => parent is LetHandler;
+
+  /// True if this is a non-return continuation that can be targeted by
+  /// [InvokeContinuation].
+  bool get isJoinContinuation {
+    return body != null &&
+           parent is! LetHandler &&
+           (firstRef == null || firstRef.parent is InvokeContinuation);
+  }
+
   Continuation(this.parameters, {this.isRecursive: false});
 
   Continuation.retrn()
@@ -1773,21 +1800,74 @@
   }
 }
 
-/// Representation of a closed type (that is, a type without type variables).
+enum TypeExpressionKind {
+  COMPLETE,
+  INSTANCE
+}
+
+/// Constructs a representation of a closed or ground-term type (that is, a type
+/// without type variables).
 ///
-/// The resulting value is constructed from [dartType] by replacing the type
+/// There are two forms:
+///
+/// - COMPLETE: A complete form that is self contained, used for the values of
+///   type parameters and non-raw is-checks.
+///
+/// - INSTANCE: A headless flat form for representing the sequence of values of
+///   the type parameters of an instance of a generic type.
+///
+/// The COMPLETE form value is constructed from [dartType] by replacing the type
 /// variables with consecutive values from [arguments], in the order generated
 /// by [DartType.forEachTypeVariable].  The type variables in [dartType] are
 /// treated as 'holes' in the term, which means that it must be ensured at
 /// construction, that duplicate occurences of a type variable in [dartType]
 /// are assigned the same value.
+///
+/// The INSTANCE form is constructed as a list of [arguments]. This is the same
+/// as the COMPLETE form for the 'thisType', except the root term's type is
+/// missing; this is implicit as the raw type of instance.  The [dartType] of
+/// the INSTANCE form must be the thisType of some class.
+///
+/// While we would like to remove the constrains on the INSTANCE form, we can
+/// get by with a tree of TypeExpressions.  Consider:
+///
+///     class Foo<T> {
+///       ... new Set<List<T>>()
+///     }
+///     class Set<E1> {
+///       factory Set() => new _LinkedHashSet<E1>();
+///     }
+///     class List<E2> { ... }
+///     class _LinkedHashSet<E3> { ... }
+///
+/// After inlining the factory constructor for `Set<E1>`, the CreateInstance
+/// should have type `_LinkedHashSet<List<T>>` and the TypeExpression should be
+/// a tree:
+///
+///    CreateInstance(dartType: _LinkedHashSet<List<T>>,
+///        [], // No arguments
+///        TypeExpression(INSTANCE,
+///            dartType: _LinkedHashSet<E3>, // _LinkedHashSet's thisType
+///            TypeExpression(COMPLETE,  // E3 = List<T>
+///                dartType: List<E2>,
+///                ReadTypeVariable(this, T)))) // E2 = T
+//
+// TODO(sra): The INSTANCE form requires the actual instance for full
+// interpretation. I want to move to a representation where the INSTANCE form is
+// also a complete form (possibly the same).
 class TypeExpression extends Primitive {
+  final TypeExpressionKind kind;
   final DartType dartType;
   final List<Reference<Primitive>> arguments;
 
-  TypeExpression(this.dartType,
-                 [List<Primitive> arguments = const <Primitive>[]])
-      : this.arguments = _referenceList(arguments);
+  TypeExpression(this.kind,
+                 this.dartType,
+                 List<Primitive> arguments)
+      : this.arguments = _referenceList(arguments) {
+    assert(kind == TypeExpressionKind.INSTANCE
+           ? dartType == (dartType.element as ClassElement).thisType
+           : true);
+  }
 
   @override
   accept(Visitor visitor) {
@@ -1801,6 +1881,13 @@
   void setParentPointers() {
     _setParentsOnList(arguments, this);
   }
+
+  String get kindAsString {
+    switch (kind) {
+      case TypeExpressionKind.COMPLETE: return 'COMPLETE';
+      case TypeExpressionKind.INSTANCE: return 'INSTANCE';
+    }
+  }
 }
 
 class Await extends UnsafePrimitive {
@@ -1965,7 +2052,6 @@
   T visitAwait(Await node);
   T visitYield(Yield node);
   T visitLiteralList(LiteralList node);
-  T visitLiteralMap(LiteralMap node);
   T visitConstant(Constant node);
   T visitGetMutable(GetMutable node);
   T visitParameter(Parameter node);
@@ -2016,7 +2102,6 @@
     processFunctionDefinition(node);
     if (node.thisParameter != null) visit(node.thisParameter);
     node.parameters.forEach(visit);
-    visit(node.returnContinuation);
     visit(node.body);
   }
 
@@ -2147,15 +2232,6 @@
     node.values.forEach(processReference);
   }
 
-  processLiteralMap(LiteralMap node) {}
-  visitLiteralMap(LiteralMap node) {
-    processLiteralMap(node);
-    for (LiteralMapEntry entry in node.entries) {
-      processReference(entry.key);
-      processReference(entry.value);
-    }
-  }
-
   processConstant(Constant node) {}
   visitConstant(Constant node)  {
     processConstant(node);
@@ -2187,7 +2263,7 @@
   visitCreateInstance(CreateInstance node) {
     processCreateInstance(node);
     node.arguments.forEach(processReference);
-    node.typeInformation.forEach(processReference);
+    if (node.typeInformation != null) processReference(node.typeInformation);
   }
 
   processSetField(SetField node) {}
@@ -2377,7 +2453,6 @@
     processFunctionDefinition(node);
     if (node.thisParameter != null) visit(node.thisParameter);
     node.parameters.forEach(visit);
-    visit(node.returnContinuation);
     visit(node.body);
   }
 
@@ -2574,13 +2649,6 @@
         ..allocationSiteType = node.allocationSiteType;
   }
 
-  Definition visitLiteralMap(LiteralMap node) {
-    List<LiteralMapEntry> entries = node.entries.map((LiteralMapEntry entry) {
-      return new LiteralMapEntry(getCopy(entry.key), getCopy(entry.value));
-    }).toList();
-    return new LiteralMap(node.dartType, entries);
-  }
-
   Definition visitConstant(Constant node) {
     return new Constant(node.value, sourceInformation: node.sourceInformation);
   }
@@ -2607,8 +2675,10 @@
   }
 
   Definition visitCreateInstance(CreateInstance node) {
-    return new CreateInstance(node.classElement, getList(node.arguments),
-        getList(node.typeInformation),
+    return new CreateInstance(
+        node.classElement,
+        getList(node.arguments),
+        node.typeInformation == null ? null : getCopy(node.typeInformation),
         node.sourceInformation);
   }
 
@@ -2630,7 +2700,8 @@
   }
 
   Definition visitTypeExpression(TypeExpression node) {
-    return new TypeExpression(node.dartType, getList(node.arguments));
+    return new TypeExpression(
+        node.kind, node.dartType, getList(node.arguments));
   }
 
   Definition visitCreateInvocationMirror(CreateInvocationMirror node) {
@@ -2695,7 +2766,7 @@
   }
 
   Definition visitForeignCode(ForeignCode node) {
-    return new ForeignCode(node.codeTemplate, node.type,
+    return new ForeignCode(node.codeTemplate, node.storedType,
         getList(node.arguments),
         node.nativeBehavior,
         dependency: node.dependency);
@@ -2723,6 +2794,7 @@
       assert(_current != null);
       InteriorExpression interior = _current;
       interior.body = body;
+      body.parent = interior;
     }
     _current = body;
   }
@@ -2740,7 +2812,9 @@
       Expression savedFirst = _first;
       _first = _current = null;
       _processBlock(cont.body);
-      _copies[cont].body = _first;
+      Continuation contCopy = _copies[cont];
+      contCopy.body = _first;
+      _first.parent = contCopy;
       _first = savedFirst;
       _current = null;
     });
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 bde9b0e..37836bf 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
@@ -29,7 +29,52 @@
     }
   }
 
+  /// Create a stringifier with an extra layer of decoration.
+  SExpressionStringifier withDecorator(Decorator subDecorator) {
+    return new SExpressionStringifier((node, String s) {
+      return subDecorator(node, decorator(node, s));
+    });
+  }
+
+  /// Create a stringifier that displays type information.
+  SExpressionStringifier withTypes() => withDecorator(typeDecorator);
+
+  /// Creates a stringifier that adds annotations from a map;
+  /// see [Node.debugString].
+  SExpressionStringifier withAnnotations(Map annotations) {
+    return withDecorator(decoratorFromMap(annotations));
+  }
+
+  static Decorator decoratorFromMap(Map annotations) {
+    Map<Node, String> nodeMap = {};
+    for (var key in annotations.keys) {
+      if (key is Node) {
+        nodeMap[key] = '${annotations[key]}';
+      } else {
+        String text = key;
+        Node node = annotations[key];
+        if (nodeMap.containsKey(node)) {
+          // In case two annotations belong to the same node,
+          // put both annotations on that node.
+          nodeMap[node] += ' $text';
+        } else {
+          nodeMap[node] = text;
+        }
+      }
+    }
+    return (node, string) {
+      String text = nodeMap[node];
+      if (text != null) return '***$string*** $text';
+      return string;
+    };
+  }
+
+  static String typeDecorator(node, String string) {
+    return node is Variable ? '$string:${node.type}' : string;
+  }
+
   String access(Reference<Definition> r) {
+    if (r == null) return '**** NULL ****';
     return decorator(r, namer.getName(r.definition));
   }
 
@@ -71,24 +116,42 @@
   String visitLetPrim(LetPrim node) {
     String name = newValueName(node.primitive);
     String value = visit(node.primitive);
+    String bindings = '($name $value)';
+    String skip = ' ' * '(LetPrim ('.length;
+    while (node.body is LetPrim) {
+      node = node.body;
+      name = newValueName(node.primitive);
+      value = visit(node.primitive);
+      String binding = decorator(node, '($name $value)');
+      bindings += '\n${indentation}$skip$binding';
+    }
     String body = indentBlock(() => visit(node.body));
-    return '$indentation(LetPrim ($name $value)\n$body)';
+    return '$indentation(LetPrim ($bindings)\n$body)';
+  }
+
+  bool isBranchTarget(Continuation cont) {
+    return cont.hasExactlyOneUse && cont.firstRef.parent is Branch;
   }
 
   String visitLetCont(LetCont node) {
     String conts;
     bool first = true;
+    String skip = ' ' * '(LetCont ('.length;
     for (Continuation continuation in node.continuations) {
+      // Branch continuations will be printed at their use site.
+      if (isBranchTarget(continuation)) continue;
       if (first) {
         first = false;
         conts = visit(continuation);
       } else {
         // Each subsequent line is indented additional spaces to align it
         // with the previous continuation.
-        String indent = '$indentation${' ' * '(LetCont ('.length}';
-        conts = '$conts\n$indent${visit(continuation)}';
+        conts += '\n${indentation}$skip${visit(continuation)}';
       }
     }
+    // If there were no continuations printed, just print the body.
+    if (first) return visit(node.body);
+
     String body = indentBlock(() => visit(node.body));
     return '$indentation(LetCont ($conts)\n$body)';
   }
@@ -175,7 +238,9 @@
   String visitInvokeContinuation(InvokeContinuation node) {
     String name = access(node.continuation);
     if (node.isRecursive) name = 'rec $name';
-    String args = node.arguments.map(access).join(' ');
+    String args = node.arguments == null
+        ? '**** NULL ****'
+	: node.arguments.map(access).join(' ');
     String escaping = node.isEscapingTry ? ' escape' : '';
     return '$indentation(InvokeContinuation $name ($args)$escaping)';
   }
@@ -191,10 +256,14 @@
 
   String visitBranch(Branch node) {
     String condition = access(node.condition);
-    String trueCont = access(node.trueContinuation);
-    String falseCont = access(node.falseContinuation);
+    assert(isBranchTarget(node.trueContinuation.definition));
+    assert(isBranchTarget(node.falseContinuation.definition));
+    String trueCont =
+        indentBlock(() => visit(node.trueContinuation.definition));
+    String falseCont =
+        indentBlock(() => visit(node.falseContinuation.definition));
     String strict = node.isStrictCheck ? 'Strict' : 'NonStrict';
-    return '$indentation(Branch $condition $trueCont $falseCont $strict)';
+    return '$indentation(Branch $strict $condition\n$trueCont\n$falseCont)';
   }
 
   String visitUnreachable(Unreachable node) {
@@ -207,11 +276,17 @@
   }
 
   String visitContinuation(Continuation node) {
+    if (isBranchTarget(node)) {
+      assert(node.parameters.isEmpty);
+      assert(!node.isRecursive);
+      return indentBlock(() => visit(node.body));
+    }
     String name = newContinuationName(node);
     if (node.isRecursive) name = 'rec $name';
-    // TODO(karlklose): this should be changed to `.map(visit).join(' ')`  and
-    // should recurse to [visit].  Currently we can't do that, because the
-    // unstringifier_test produces [LetConts] with dummy arguments on them.
+    // TODO(karlklose): this should be changed to `.map(visit).join(' ')`
+    // and should recurse to [visit].  Currently we can't do that, because
+    // the unstringifier_test produces [LetConts] with dummy arguments on
+    // them.
     String parameters = node.parameters
         .map((p) => '${decorator(p, newValueName(p))}')
         .join(' ');
@@ -250,12 +325,6 @@
     return '(LiteralList ($values))';
   }
 
-  String visitLiteralMap(LiteralMap node) {
-    String keys = node.entries.map((e) => access(e.key)).join(' ');
-    String values = node.entries.map((e) => access(e.value)).join(' ');
-    return '(LiteralMap ($keys) ($values))';
-  }
-
   String visitSetField(SetField node) {
     String object = access(node.object);
     String field = node.field.name;
@@ -292,7 +361,7 @@
   String visitCreateInstance(CreateInstance node) {
     String className = node.classElement.name;
     String arguments = node.arguments.map(access).join(' ');
-    String typeInformation = node.typeInformation.map(access).join(' ');
+    String typeInformation = optionalAccess(node.typeInformation);
     return '(CreateInstance $className ($arguments) ($typeInformation))';
   }
 
@@ -310,7 +379,7 @@
 
   String visitTypeExpression(TypeExpression node) {
     String args = node.arguments.map(access).join(' ');
-    return '(TypeExpression ${node.dartType} ($args))';
+    return '(TypeExpression ${node.kindAsString} ${node.dartType} ($args))';
   }
 
   String visitCreateInvocationMirror(CreateInvocationMirror node) {
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 e732f3d..db1592d 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -29,7 +29,7 @@
       builder.visit(node);
 
       for (Block block in builder.entries) {
-        printBlock(block, entryPointParameters: node.parameters);
+        printBlock(block, entryPoint: node);
       }
       for (Block block in builder.cont2block.values) {
         printBlock(block);
@@ -63,9 +63,8 @@
     return count;
   }
 
-  /// If [entryPointParameters] is given, this block is an entry point
-  /// and [entryPointParameters] is the list of function parameters.
-  printBlock(Block block, {List<cps_ir.Definition> entryPointParameters}) {
+  /// If [entryPoint] is given, this block is an entry point.
+  printBlock(Block block, {cps_ir.FunctionDefinition entryPoint}) {
     tag("block", () {
       printProperty("name", block.name);
       printProperty("from_bci", -1);
@@ -84,9 +83,12 @@
         String formatParameter(cps_ir.Parameter param) {
           return '${names.name(param)} ${param.type}';
         }
-        if (entryPointParameters != null) {
-          String params = entryPointParameters.map(formatParameter).join(', ');
-          printStmt('x0', 'Entry ($params)');
+        if (entryPoint != null) {
+          String thisParam = entryPoint.thisParameter != null
+              ? formatParameter(entryPoint.thisParameter)
+              : 'no receiver';
+          String params = entryPoint.parameters.map(formatParameter).join(', ');
+          printStmt('x0', 'Entry ($thisParam) ($params)');
         }
         String params = block.parameters.map(formatParameter).join(', ');
         printStmt('x0', 'Parameters ($params)');
@@ -192,16 +194,6 @@
     return "LiteralList ($values)";
   }
 
-  visitLiteralMap(cps_ir.LiteralMap node) {
-    List<String> entries = new List<String>();
-    for (cps_ir.LiteralMapEntry entry in node.entries) {
-      String key = formatReference(entry.key);
-      String value = formatReference(entry.value);
-      entries.add("$key: $value");
-    }
-    return "LiteralMap (${entries.join(', ')})";
-  }
-
   visitTypeCast(cps_ir.TypeCast node) {
     String value = formatReference(node.value);
     String args = node.typeArguments.map(formatReference).join(', ');
@@ -303,8 +295,7 @@
   visitCreateInstance(cps_ir.CreateInstance node) {
     String className = node.classElement.name;
     String arguments = node.arguments.map(formatReference).join(', ');
-    String typeInformation =
-        node.typeInformation.map(formatReference).join(', ');
+    String typeInformation = formatReference(node.typeInformation);
     return 'CreateInstance $className ($arguments) <$typeInformation>';
   }
 
@@ -328,7 +319,7 @@
   }
 
   visitTypeExpression(cps_ir.TypeExpression node) {
-    return "TypeExpression ${node.dartType} "
+    return "TypeExpression ${node.kindAsString} ${node.dartType}"
         "${node.arguments.map(formatReference).join(', ')}";
   }
 
@@ -578,10 +569,6 @@
     unexpectedNode(node);
   }
 
-  visitLiteralMap(cps_ir.LiteralMap node) {
-    unexpectedNode(node);
-  }
-
   visitConstant(cps_ir.Constant node) {
     unexpectedNode(node);
   }
diff --git a/pkg/compiler/lib/src/cps_ir/duplicate_branch.dart b/pkg/compiler/lib/src/cps_ir/duplicate_branch.dart
new file mode 100644
index 0000000..7b1d294
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/duplicate_branch.dart
@@ -0,0 +1,123 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+library dart2js.cps_ir.duplicate_branch;
+
+import 'cps_ir_nodes.dart';
+import 'optimizers.dart';
+import 'cps_fragment.dart';
+
+/// Removes branches that branch on the same value as a previously seen branch.
+/// For example:
+///
+///     if (x == y) {
+///       if (x == y) TRUE else FALSE
+///     }
+///
+/// ==> ([GVN] pass merges identical expressions)
+///
+///     var b = (x == y)
+///     if (b) {
+///       if (b) TRUE else FALSE
+///     }
+///
+///  ==> (this pass removes the duplicate branch)
+///
+///     var b = (x == y)
+///     if (b) {
+///       TRUE
+///     }
+//
+// TODO(asgerf): A kind of redundant join can arise where a branching condition
+// is known to be true/false on all but one predecessor for a branch. We could
+// try to reduce those.
+//
+// TODO(asgerf): Could be more precise if GVN shared expressions that are not
+// in direct scope of one another, e.g. by using phis pass the shared value.
+//
+class DuplicateBranchEliminator extends TrampolineRecursiveVisitor
+                                implements Pass {
+  String get passName => 'Duplicate branch elimination';
+
+  static const int TRUE = 1 << 0;
+  static const int OTHER_TRUTHY = 1 << 1;
+  static const int FALSE = 1 << 2;
+  static const int OTHER_FALSY = 1 << 3;
+
+  static const int TRUTHY = TRUE | OTHER_TRUTHY;
+  static const int FALSY = FALSE | OTHER_FALSY;
+  static const int ANY = TRUTHY | FALSY;
+
+  /// The possible values of the given primitive (or ANY if absent) at the
+  /// current traversal position.
+  Map<Primitive, int> valueOf = <Primitive, int>{};
+
+  /// The possible values of each primitive at the entry to a continuation.
+  ///
+  /// Unreachable continuations are absent from the map.
+  final Map<Continuation, Map<Primitive, int>> valuesAt =
+      <Continuation, Map<Primitive, int>>{};
+
+  void rewrite(FunctionDefinition node) {
+    visit(node);
+  }
+
+  Map<Primitive, int> copy(Map<Primitive, int> map) {
+    return new Map<Primitive, int>.from(map);
+  }
+
+  Expression traverseLetHandler(LetHandler node) {
+    valuesAt[node.handler] = copy(valueOf);
+    push(node.handler);
+    return node.body;
+  }
+
+  Expression traverseContinuation(Continuation cont) {
+    valueOf = valuesAt[cont];
+    if (valueOf == null) {
+      // Do not go into unreachable code.
+      destroyAndReplace(cont.body, new Unreachable());
+    }
+    return cont.body;
+  }
+
+  void visitInvokeContinuation(InvokeContinuation node) {
+    Continuation cont = node.continuation.definition;
+    if (cont.isReturnContinuation) return;
+    if (node.isRecursive) return;
+    Map<Primitive, int> target = valuesAt[cont];
+    if (target == null) {
+      valuesAt[cont] = valueOf;
+    } else {
+      for (Primitive prim in target.keys) {
+        target[prim] |= valueOf[prim] ?? ANY;
+      }
+    }
+  }
+
+  visitBranch(Branch node) {
+    Primitive condition = node.condition.definition.effectiveDefinition;
+    Continuation trueCont = node.trueContinuation.definition;
+    Continuation falseCont = node.falseContinuation.definition;
+    if (condition.hasExactlyOneUse) {
+      // Handle common case specially. Do not add [condition] to the map if
+      // there are no other uses.
+      valuesAt[trueCont] = copy(valueOf);
+      valuesAt[falseCont] = valueOf;
+      return;
+    }
+    int values = valueOf[condition] ?? ANY;
+    int positiveValues = node.isStrictCheck ? TRUE : TRUTHY;
+    int negativeValues = (~positiveValues) & ANY;
+    if (values & positiveValues == 0) {
+      destroyAndReplace(node, new InvokeContinuation(falseCont, []));
+      valuesAt[falseCont] = valueOf;
+    } else if (values & negativeValues == 0) {
+      destroyAndReplace(node, new InvokeContinuation(trueCont, []));
+      valuesAt[trueCont] = valueOf;
+    } else {
+      valuesAt[trueCont] = copy(valueOf)..[condition] = values & positiveValues;
+      valuesAt[falseCont] = valueOf..[condition] = values & negativeValues;
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/finalize.dart b/pkg/compiler/lib/src/cps_ir/finalize.dart
index 1406a58..7e3b6e1 100644
--- a/pkg/compiler/lib/src/cps_ir/finalize.dart
+++ b/pkg/compiler/lib/src/cps_ir/finalize.dart
@@ -5,6 +5,7 @@
 import 'optimizers.dart' show Pass;
 import '../js_backend/js_backend.dart' show JavaScriptBackend;
 import '../js_backend/backend_helpers.dart';
+import '../js/js.dart' as js;
 
 /// A transformation pass that must run immediately before the tree IR builder.
 ///
@@ -78,4 +79,18 @@
       node..witness.unlink()..witness = null;
     }
   }
+
+  void visitForeignCode(ForeignCode node) {
+    if (js.isIdentityTemplate(node.codeTemplate)) {
+      // The CPS builder replaces identity templates with refinements, except
+      // when the refined type is an array type.  Some optimizations assume the
+      // type of an object is immutable, but the type of an array can change
+      // after allocation.  After the finalize pass, this assumption is no
+      // longer needed, so we can replace the remaining idenitity templates.
+      Refinement refinement = new Refinement(
+          node.arguments.single.definition,
+          node.type)..type = node.type;
+      node.replaceWith(refinement);
+    }
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
index cc046ee..554e93e 100644
--- a/pkg/compiler/lib/src/cps_ir/inline.dart
+++ b/pkg/compiler/lib/src/cps_ir/inline.dart
@@ -86,6 +86,9 @@
   static const int ABSENT = -1;
   static const int NO_INLINE = 0;
 
+  final Map<ExecutableElement, FunctionDefinition> unoptimized =
+      <ExecutableElement, FunctionDefinition>{};
+
   final Map<ExecutableElement, List<CacheEntry>> map =
       <ExecutableElement, List<CacheEntry>>{};
 
@@ -144,6 +147,29 @@
     }
     return ABSENT;
   }
+
+  /// Cache the unoptimized CPS term for a function.
+  ///
+  /// The unoptimized term should not have any inlining-context-specific
+  /// optimizations applied to it.  It will be used to compile the
+  /// non-specialized version of the function.
+  void putUnoptimized(ExecutableElement element, FunctionDefinition function) {
+    unoptimized.putIfAbsent(element, () => copier.copy(function));
+  }
+
+  /// Look up the unoptimized CPS term for a function.
+  ///
+  /// The unoptimized term will not have any inlining-context-specific
+  /// optimizations applied to it.  It can be used to compile the
+  /// non-specialized version of the function.
+  FunctionDefinition getUnoptimized(ExecutableElement element) {
+    FunctionDefinition function = unoptimized[element];
+    if (function != null) {
+      function = copier.copy(function);
+      ParentVisitor.setParents(function);
+    }
+    return function;
+  }
 }
 
 class Inliner implements Pass {
@@ -323,7 +349,7 @@
         outgoingNames.add(formal.name);
       });
       newCallStructure =
-      new CallStructure(signature.parameterCount, outgoingNames);
+          new CallStructure(signature.parameterCount, outgoingNames);
     } else {
       signature.forEachOptionalParameter((ParameterElement formal) {
         if (parameterIndex < parameters.length) {
@@ -372,6 +398,13 @@
       return null;
     }
 
+    // Don't inline methods that never return. They are usually helper functions
+    // that throw an exception.
+    if (invoke.type.isEmpty && !invoke.type.isNullable) {
+      // TODO(sra): It would be ok to inline if doing so was shrinking.
+      return null;
+    }
+
     Reference<Primitive> dartReceiver = invoke.dartReceiverReference;
     TypeMask abstractReceiver =
         dartReceiver == null ? null : abstractType(dartReceiver);
@@ -434,9 +467,14 @@
       // The argument count at the call site does not match the target's
       // formal parameter count.  Build the IR term for an adapter function
       // body.
-      function = buildAdapter(invoke, target);
+      if (backend.isNative(target)) {
+        // TODO(25548): Generate correct adaptor for native methods.
+        return doNotInline();
+      } else {
+        function = buildAdapter(invoke, target);
+      }
     } else {
-      function = _inliner.functionCompiler.compileToCpsIr(target);
+      function = compileToCpsIr(target);
       void setValue(Variable variable, Reference<Primitive> value) {
         variable.type = value.definition.type;
       }
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 812b204..599476f 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -25,6 +25,7 @@
 export 'inline.dart' show Inliner;
 export 'eagerly_load_statics.dart' show EagerlyLoadStatics;
 export 'loop_invariant_branch.dart' show LoopInvariantBranchMotion;
+export 'duplicate_branch.dart' show DuplicateBranchEliminator;
 export 'parent_visitor.dart' show ParentVisitor;
 
 /// An optimization pass over the CPS IR.
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_join.dart b/pkg/compiler/lib/src/cps_ir/redundant_join.dart
index 92f64ae..808c1c7 100644
--- a/pkg/compiler/lib/src/cps_ir/redundant_join.dart
+++ b/pkg/compiler/lib/src/cps_ir/redundant_join.dart
@@ -8,15 +8,15 @@
 import 'optimizers.dart';
 
 /// Eliminates redundant join points.
-/// 
+///
 /// A redundant join point is a continuation that immediately branches
 /// based on one of its parameters, and that parameter is a constant value
 /// at every invocation. Each invocation is redirected to jump directly
 /// to the branch target.
-/// 
+///
 /// Internally in this pass, parameters are treated as names with lexical
 /// scoping, and a given parameter "name" may be declared by more than
-/// one continuation. The reference chains for parameters are therefore 
+/// one continuation. The reference chains for parameters are therefore
 /// meaningless during this pass, until repaired by [AlphaRenamer] at
 /// the end.
 class RedundantJoinEliminator extends TrampolineRecursiveVisitor implements Pass {
@@ -113,11 +113,11 @@
       return;
     }
 
-    // Lift any continuations bound inside branchCont so they are in scope at 
+    // Lift any continuations bound inside branchCont so they are in scope at
     // the call sites. When lifting, the parameters of branchCont fall out of
     // scope, so they are added as parameters on each lifted continuation.
     // Schematically:
-    // 
+    //
     //   (LetCont (branchCont (x1, x2, x3) =
     //        (LetCont (innerCont (y) = ...) in
     //        [... innerCont(y') ...]))
@@ -127,8 +127,8 @@
     //   (LetCont (innerCont (y, x1, x2, x3) = ...) in
     //   (LetCont (branchCont (x1, x2, x3) =
     //        [... innerCont(y', x1, x2, x3) ...])
-    // 
-    // Parameter objects become shared between branchCont and the lifted 
+    //
+    // Parameter objects become shared between branchCont and the lifted
     // continuations. [AlphaRenamer] will clean up at the end of this pass.
     LetCont outerLetCont = branchCont.parent;
     while (branchCont.body is LetCont) {
@@ -202,13 +202,13 @@
 /// Ensures parameter objects are not shared between different continuations,
 /// akin to alpha-renaming variables so every variable is named uniquely.
 /// For example:
-/// 
+///
 ///   LetCont (k1 x = (return x)) in
 ///   LetCont (k2 x = (InvokeContinuation k3 x)) in ...
-///     => 
+///     =>
 ///   LetCont (k1 x = (return x)) in
 ///   LetCont (k2 x' = (InvokeContinuation k3 x')) in ...
-/// 
+///
 /// After lifting LetConts in the main pass above, parameter objects can have
 /// multiple bindings. Each reference implicitly refers to the binding that
 /// is currently in scope.
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
index 7f16af9..f5d5423 100644
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
@@ -61,10 +61,10 @@
     /// Returns the unique definition of parameter i if it exists and null
     /// otherwise. A definition is unique if it is the only value used to
     /// invoke the continuation, excluding feedback.
-    Definition uniqueDefinitionOf(int i) {
-      Definition value = null;
+    Primitive uniqueDefinitionOf(int i) {
+      Primitive value = null;
       for (InvokeContinuation invoke in invokes) {
-        Definition def = invoke.arguments[i].definition;
+        Primitive def = invoke.arguments[i].definition.effectiveDefinition;
 
         if (cont.parameters[i] == def) {
           // Invocation param == param in LetCont (i.e. a recursive call).
@@ -104,7 +104,7 @@
     int dst = 0;
     for (int src = 0; src < cont.parameters.length; src++) {
       // Is the current phi redundant?
-      Definition uniqueDefinition = uniqueDefinitionOf(src);
+      Primitive uniqueDefinition = uniqueDefinitionOf(src);
       if (uniqueDefinition == null || !safeForHandlers(uniqueDefinition)) {
         // Reorganize parameters and arguments in case of deletions.
         if (src != dst) {
@@ -117,7 +117,7 @@
         continue;
       }
 
-      Definition oldDefinition = cont.parameters[src];
+      Primitive oldDefinition = cont.parameters[src];
 
       // Add continuations of about-to-be modified invokes to worklist since
       // we might introduce new optimization opportunities.
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index 16a1d15..42ae6cd 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -6,7 +6,6 @@
 
 import 'cps_ir_nodes.dart';
 import 'optimizers.dart';
-import 'cps_fragment.dart';
 
 /**
  * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
@@ -15,26 +14,68 @@
 class ShrinkingReducer extends Pass {
   String get passName => 'Shrinking reductions';
 
-  List<_ReductionTask> _worklist;
-
-  static final _DeletedNode _DELETED = new _DeletedNode();
+  final List<_ReductionTask> _worklist = new List<_ReductionTask>();
 
   /// Applies shrinking reductions to root, mutating root in the process.
   @override
   void rewrite(FunctionDefinition root) {
-    _worklist = new List<_ReductionTask>();
     _RedexVisitor redexVisitor = new _RedexVisitor(_worklist);
 
     // Sweep over the term, collecting redexes into the worklist.
     redexVisitor.visit(root);
 
-    // Process the worklist.
+    _iterateWorklist();
+  }
+
+  void _iterateWorklist() {
     while (_worklist.isNotEmpty) {
       _ReductionTask task = _worklist.removeLast();
       _processTask(task);
     }
   }
 
+  /// Call instead of [_iterateWorklist] to check at every step that no
+  /// redex was missed.
+  void _debugWorklist(FunctionDefinition root) {
+    while (_worklist.isNotEmpty) {
+      _ReductionTask task = _worklist.removeLast();
+      String irBefore = root.debugString({
+        task.node: '${task.kind} applied here'
+      });
+      _processTask(task);
+      Set seenRedexes = _worklist.where(isValidTask).toSet();
+      Set actualRedexes = (new _RedexVisitor([])..visit(root)).worklist.toSet();
+      if (!seenRedexes.containsAll(actualRedexes)) {
+        _ReductionTask missedTask =
+            actualRedexes.firstWhere((x) => !seenRedexes.contains(x));
+        print('\nBEFORE $task:\n');
+        print(irBefore);
+        print('\nAFTER $task:\n');
+        root.debugPrint({
+          missedTask.node: 'MISSED ${missedTask.kind}'
+        });
+        throw 'Missed $missedTask after processing $task';
+      }
+    }
+  }
+
+  bool isValidTask(_ReductionTask task) {
+    switch (task.kind) {
+      case _ReductionKind.DEAD_VAL:
+        return _isDeadVal(task.node);
+      case _ReductionKind.DEAD_CONT:
+        return _isDeadCont(task.node);
+      case _ReductionKind.BETA_CONT_LIN:
+        return _isBetaContLin(task.node);
+      case _ReductionKind.ETA_CONT:
+        return _isEtaCont(task.node);
+      case _ReductionKind.DEAD_PARAMETER:
+        return _isDeadParameter(task.node);
+      case _ReductionKind.BRANCH:
+        return _isBranchRedex(task.node);
+    }
+  }
+
   /// Removes the given node from the CPS graph, replacing it with its body
   /// and marking it as deleted. The node's parent must be a [[InteriorNode]].
   void _removeNode(InteriorNode node) {
@@ -44,7 +85,14 @@
 
     body.parent = parent;
     parent.body = body;
-    node.parent = _DELETED;
+    node.parent = null;
+
+    // The removed node could be the last node between a continuation and
+    // an InvokeContinuation in the body.
+    if (parent is Continuation) {
+      _checkEtaCont(parent);
+      _checkUselessBranchTarget(parent);
+    }
   }
 
   /// Remove a given continuation from the CPS graph.  The LetCont itself is
@@ -56,12 +104,12 @@
     } else {
       parent.continuations.remove(cont);
     }
-    cont.parent = _DELETED;
+    cont.parent = null;
   }
 
   void _processTask(_ReductionTask task) {
     // Skip tasks for deleted nodes.
-    if (task.node.parent == _DELETED) {
+    if (task.node.parent == null) {
       return;
     }
 
@@ -81,6 +129,9 @@
       case _ReductionKind.DEAD_PARAMETER:
         _reduceDeadParameter(task);
         break;
+      case _ReductionKind.BRANCH:
+        _reduceBranch(task);
+        break;
       default:
         assert(false);
     }
@@ -89,15 +140,31 @@
   /// Applies the dead-val reduction:
   ///   letprim x = V in E -> E (x not free in E).
   void _reduceDeadVal(_ReductionTask task) {
+    if (_isRemoved(task.node)) return;
     assert(_isDeadVal(task.node));
 
-    // Remove dead primitive.
-    LetPrim letPrim = task.node;
-    destroyRefinementsOfDeadPrimitive(letPrim.primitive);
-    _removeNode(letPrim);
+    LetPrim deadLet = task.node;
+    Primitive deadPrim = deadLet.primitive;
+    assert(deadPrim.hasNoRefinedUses);
+    // The node has no effective uses but can have refinement uses, which
+    // themselves can have more refinements uses (but only refinement uses).
+    // We must remove the entire refinement tree while looking for redexes
+    // whenever we remove one.
+    List<Primitive> deadlist = <Primitive>[deadPrim];
+    while (deadlist.isNotEmpty) {
+      Primitive node = deadlist.removeLast();
+      while (node.firstRef != null) {
+        Reference ref = node.firstRef;
+        Refinement use = ref.parent;
+        deadlist.add(use);
+        ref.unlink();
+      }
+      LetPrim binding = node.parent;
+      _removeNode(binding); // Remove the binding and check for eta redexes.
+    }
 
     // Perform bookkeeping on removed body and scan for new redexes.
-    new _RemovalVisitor(_worklist).visit(letPrim.primitive);
+    new _RemovalVisitor(_worklist).visit(deadPrim);
   }
 
   /// Applies the dead-cont reduction:
@@ -127,25 +194,36 @@
       return;
     }
 
-    // Remove the continuation.
     Continuation cont = task.node;
-    _removeContinuation(cont);
-
-    // Replace its invocation with the continuation body.
     InvokeContinuation invoke = cont.firstRef.parent;
     InteriorNode invokeParent = invoke.parent;
+    Expression body = cont.body;
 
-    cont.body.parent = invokeParent;
-    invokeParent.body = cont.body;
+    // Replace the invocation with the continuation body.
+    invokeParent.body = body;
+    body.parent = invokeParent;
+    cont.body = null;
 
     // Substitute the invocation argument for the continuation parameter.
     for (int i = 0; i < invoke.arguments.length; i++) {
-      cont.parameters[i].replaceUsesWith(invoke.arguments[i].definition);
-      invoke.arguments[i].definition.useElementAsHint(cont.parameters[i].hint);
+      Parameter param = cont.parameters[i];
+      Primitive argument = invoke.arguments[i].definition;
+      param.replaceUsesWith(argument);
+      argument.useElementAsHint(param.hint);
+      _checkConstantBranchCondition(argument);
     }
 
+    // Remove the continuation after inlining it so we can check for eta redexes
+    // which may arise after removing the LetCont.
+    _removeContinuation(cont);
+
     // Perform bookkeeping on substituted body and scan for new redexes.
     new _RemovalVisitor(_worklist).visit(invoke);
+
+    if (invokeParent is Continuation) {
+      _checkEtaCont(invokeParent);
+      _checkUselessBranchTarget(invokeParent);
+    }
   }
 
   /// Applies the eta-cont reduction:
@@ -184,13 +262,48 @@
       }
     }
 
-    // Replace all occurrences with the wrapped continuation.
-    cont.replaceUsesWith(wrappedCont);
+    // Replace all occurrences with the wrapped continuation and find redexes.
+    while (cont.firstRef != null) {
+      Reference ref = cont.firstRef;
+      ref.changeTo(wrappedCont);
+      Node use = ref.parent;
+      if (use is InvokeContinuation && use.parent is Continuation) {
+        _checkUselessBranchTarget(use.parent);
+      }
+    }
 
     // Perform bookkeeping on removed body and scan for new redexes.
     new _RemovalVisitor(_worklist).visit(cont);
   }
 
+  void _reduceBranch(_ReductionTask task) {
+    Branch branch = task.node;
+    // Replace Branch with InvokeContinuation of one of the targets. When the
+    // branch is deleted the other target becomes unreferenced and the chosen
+    // target becomes available for eta-cont and further reductions.
+    Continuation target;
+    Primitive condition = branch.condition.definition;
+    if (condition is Constant) {
+      target = isTruthyConstant(condition.value, strict: branch.isStrictCheck)
+          ? branch.trueContinuation.definition
+          : branch.falseContinuation.definition;
+    } else if (_isBranchTargetOfUselessIf(branch.trueContinuation.definition)) {
+      target = branch.trueContinuation.definition;
+    } else {
+      return;
+    }
+
+    InvokeContinuation invoke = new InvokeContinuation(
+        target, <Primitive>[]
+        // TODO(sra): Add sourceInformation.
+        /*, sourceInformation: branch.sourceInformation*/);
+    branch.parent.body = invoke;
+    invoke.parent = branch.parent;
+    branch.parent = null;
+
+    new _RemovalVisitor(_worklist).visit(branch);
+  }
+
   void _reduceDeadParameter(_ReductionTask task) {
     // Continuation eta-reduction can destroy a dead parameter redex.  For
     // example, in the term:
@@ -207,61 +320,105 @@
     // Where the dead parameter reduction is no longer valid because we do not
     // allow removing the paramter of call continuations.  We disallow such eta
     // reductions in [_isEtaCont].
-    assert(_isDeadParameter(task.node));
-
     Parameter parameter = task.node;
+    if (_isParameterRemoved(parameter)) return;
+    assert(_isDeadParameter(parameter));
+
     Continuation continuation = parameter.parent;
     int index = continuation.parameters.indexOf(parameter);
     assert(index != -1);
+    continuation.parameters.removeAt(index);
+    parameter.parent = null; // Mark as removed.
 
     // Remove the index'th argument from each invocation.
-    Reference<Continuation> current = continuation.firstRef;
-    while (current != null) {
-      InvokeContinuation invoke = current.parent;
+    for (Reference ref = continuation.firstRef; ref != null; ref = ref.next) {
+      InvokeContinuation invoke = ref.parent;
       Reference<Primitive> argument = invoke.arguments[index];
       argument.unlink();
-      // Removing an argument can create a dead parameter or dead value redex.
-      if (argument.definition is Parameter) {
-        if (_isDeadParameter(argument.definition)) {
-          _worklist.add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER,
-                                           argument.definition));
-        }
-      } else {
-        Node parent = argument.definition.parent;
-        if (parent is LetPrim) {
-          if (_isDeadVal(parent)) {
-            _worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, parent));
-          }
-        }
-      }
       invoke.arguments.removeAt(index);
-      current = current.next;
+      // Removing an argument can create a dead primitive or an eta-redex
+      // in case the parent is a continuation that now has matching parameters.
+      _checkDeadPrimitive(argument.definition);
+      if (invoke.parent is Continuation) {
+        _checkEtaCont(invoke.parent);
+        _checkUselessBranchTarget(invoke.parent);
+      }
     }
-    continuation.parameters.removeAt(index);
 
-    // Removing an unused parameter can create an eta-redex.
+    // Removing an unused parameter can create an eta-redex, in case the
+    // body is an InvokeContinuation that now has matching arguments.
+    _checkEtaCont(continuation);
+  }
+
+  void _checkEtaCont(Continuation continuation) {
     if (_isEtaCont(continuation)) {
       _worklist.add(new _ReductionTask(_ReductionKind.ETA_CONT, continuation));
     }
   }
+
+  void _checkUselessBranchTarget(Continuation continuation) {
+    if (_isBranchTargetOfUselessIf(continuation)) {
+      _worklist.add(new _ReductionTask(_ReductionKind.BRANCH,
+          continuation.firstRef.parent));
+    }
+  }
+
+  void _checkConstantBranchCondition(Primitive primitive) {
+    if (primitive is! Constant) return;
+    for (Reference ref = primitive.firstRef; ref != null; ref = ref.next) {
+      Node use = ref.parent;
+      if (use is Branch) {
+        _worklist.add(new _ReductionTask(_ReductionKind.BRANCH, use));
+      }
+    }
+  }
+
+  void _checkDeadPrimitive(Primitive primitive) {
+    primitive = primitive.unrefined;
+    if (primitive is Parameter) {
+      if (_isDeadParameter(primitive)) {
+        _worklist.add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER,
+                                         primitive));
+      }
+    } else if (primitive.parent is LetPrim) {
+      LetPrim letPrim = primitive.parent;
+      if (_isDeadVal(letPrim)) {
+        _worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, letPrim));
+      }
+    }
+  }
+}
+
+bool _isRemoved(InteriorNode node) {
+  return node.parent == null;
+}
+
+bool _isParameterRemoved(Parameter parameter) {
+  // A parameter can be removed directly or because its continuation is removed.
+  return parameter.parent == null || _isRemoved(parameter.parent);
 }
 
 /// Returns true iff the bound primitive is unused, and has no effects
 /// preventing it from being eliminated.
 bool _isDeadVal(LetPrim node) {
-  return node.primitive.hasNoEffectiveUses &&
+  return !_isRemoved(node) &&
+         node.primitive.hasNoRefinedUses &&
          node.primitive.isSafeForElimination;
 }
 
 /// Returns true iff the continuation is unused.
 bool _isDeadCont(Continuation cont) {
-  return !cont.isReturnContinuation && !cont.hasAtLeastOneUse;
+  return !_isRemoved(cont) &&
+         !cont.isReturnContinuation &&
+         !cont.hasAtLeastOneUse;
 }
 
 /// Returns true iff the continuation has a body (i.e., it is not the return
 /// continuation), it is used exactly once, and that use is as the continuation
 /// of a continuation invocation.
 bool _isBetaContLin(Continuation cont) {
+  if (_isRemoved(cont)) return false;
+
   // There is a restriction on continuation eta-redexes that the body is not an
   // invocation of the return continuation, because that leads to worse code
   // when translating back to direct style (it duplicates returns).  There is no
@@ -275,26 +432,21 @@
   if (cont.firstRef.parent is! InvokeContinuation) return false;
 
   InvokeContinuation invoke = cont.firstRef.parent;
-  if (cont != invoke.continuation.definition) return false;
 
   // Beta-reduction will move the continuation's body to its unique invocation
   // site.  This is not safe if the body is moved into an exception handler
-  // binding.  Search from the invocation to the continuation binding to
-  // make sure that there is no binding for a handler.
-  Node current = invoke.parent;
-  while (current != cont.parent) {
-    // There is no need to reduce a beta-redex inside a deleted subterm.
-    if (current == ShrinkingReducer._DELETED) return false;
-    if (current is LetHandler) return false;
-    current = current.parent;
-  }
+  // binding.
+  if (invoke.isEscapingTry) return false;
+
   return true;
 }
 
 /// Returns true iff the continuation consists of a continuation
 /// invocation, passing on all parameters. Special cases exist (see below).
 bool _isEtaCont(Continuation cont) {
-  if (cont.isReturnContinuation || cont.body is! InvokeContinuation) {
+  if (_isRemoved(cont)) return false;
+
+  if (!cont.isJoinContinuation || cont.body is! InvokeContinuation) {
     return false;
   }
 
@@ -307,25 +459,6 @@
     return false;
   }
 
-  // Do not perform reductions replace a function call continuation with a
-  // non-call continuation.  The invoked continuation is definitely not a call
-  // continuation, because it has a direct invocation in this continuation's
-  // body.
-  bool isCallContinuation(Continuation continuation) {
-    Reference<Continuation> current = cont.firstRef;
-    while (current != null) {
-      if (current.parent is InvokeContinuation) {
-        InvokeContinuation invoke = current.parent;
-        if (invoke.continuation.definition == continuation) return false;
-      }
-      current = current.next;
-    }
-    return true;
-  }
-  if (isCallContinuation(cont)) {
-    return false;
-  }
-
   // Translation to direct style generates different statements for recursive
   // and non-recursive invokes. It should still be possible to apply eta-cont if
   // this is not a self-invocation.
@@ -371,15 +504,61 @@
   return true;
 }
 
-bool _isDeadParameter(Parameter parameter) {
-  // We cannot remove function parameters as an intraprocedural optimization.
-  if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) {
+Expression _unfoldDeadRefinements(Expression node) {
+  while (node is LetPrim) {
+    LetPrim let = node;
+    Primitive prim = let.primitive;
+    if (prim.hasAtLeastOneUse || prim is! Refinement) return node;
+    node = node.next;
+  }
+  return node;
+}
+
+bool _isBranchRedex(Branch branch) {
+  return _isUselessIf(branch) || branch.condition.definition is Constant;
+}
+
+bool _isBranchTargetOfUselessIf(Continuation cont) {
+  // A useless-if has an empty then and else branch, e.g. `if (cond);`.
+  //
+  // Detect T or F in
+  //
+  //     let cont Join() = ...
+  //       in let cont T() = Join()
+  //                   F() = Join()
+  //         in branch condition T F
+  //
+  if (!cont.hasExactlyOneUse) return false;
+  Node use = cont.firstRef.parent;
+  if (use is! Branch) return false;
+  return _isUselessIf(use);
+}
+
+bool _isUselessIf(Branch branch) {
+  Continuation trueCont = branch.trueContinuation.definition;
+  Expression trueBody = _unfoldDeadRefinements(trueCont.body);
+  if (trueBody is! InvokeContinuation) return false;
+  Continuation falseCont = branch.falseContinuation.definition;
+  Expression falseBody = _unfoldDeadRefinements(falseCont.body);
+  if (falseBody is! InvokeContinuation) return false;
+  InvokeContinuation trueInvoke = trueBody;
+  InvokeContinuation falseInvoke = falseBody;
+  if (trueInvoke.continuation.definition !=
+      falseInvoke.continuation.definition) {
     return false;
   }
+  assert(trueInvoke.arguments.length == falseInvoke.arguments.length);
+  // Matching zero arguments should be adequate, since isomorphic true and false
+  // invocations should result in redundant phis which are removed elsewhere.
+  if (trueInvoke.arguments.isNotEmpty) return false;
+  return true;
+}
 
-  // We cannot remove exception handler parameters, they have a fixed arity
-  // of two.
-  if (parameter.parent.parent is LetHandler) {
+bool _isDeadParameter(Parameter parameter) {
+  if (_isParameterRemoved(parameter)) return false;
+
+  // We cannot remove function parameters as an intraprocedural optimization.
+  if (parameter.parent is! Continuation || parameter.hasAtLeastOneUse) {
     return false;
   }
 
@@ -388,14 +567,8 @@
   // exactly one argument).  The return continuation is a call continuation, so
   // we cannot remove its dummy parameter.
   Continuation continuation = parameter.parent;
-  if (continuation.isReturnContinuation) return false;
-  Reference<Continuation> current = continuation.firstRef;
-  while (current != null) {
-    if (current.parent is! InvokeContinuation) return false;
-    InvokeContinuation invoke = current.parent;
-    if (invoke.continuation.definition != continuation) return false;
-    current = current.next;
-  }
+  if (!continuation.isJoinContinuation) return false;
+
   return true;
 }
 
@@ -411,6 +584,12 @@
     }
   }
 
+  void processBranch(Branch node) {
+    if (_isBranchRedex(node)) {
+      worklist.add(new _ReductionTask(_ReductionKind.BRANCH, node));
+    }
+  }
+
   void processContinuation(Continuation node) {
     // While it would be nice to remove exception handlers that are provably
     // unnecessary (e.g., the body cannot throw), that takes more sophisticated
@@ -452,23 +631,26 @@
   _RemovalVisitor(this.worklist);
 
   void processLetPrim(LetPrim node) {
-    node.parent = ShrinkingReducer._DELETED;
+    node.parent = null;
   }
 
   void processContinuation(Continuation node) {
-    node.parent = ShrinkingReducer._DELETED;
+    node.parent = null;
   }
 
   void processReference(Reference reference) {
     reference.unlink();
 
     if (reference.definition is Primitive) {
-      Primitive primitive = reference.definition;
+      Primitive primitive = reference.definition.unrefined;
       Node parent = primitive.parent;
       // The parent might be the deleted sentinel, or it might be a
       // Continuation or FunctionDefinition if the primitive is an argument.
       if (parent is LetPrim && _isDeadVal(parent)) {
         worklist.add(new _ReductionTask(_ReductionKind.DEAD_VAL, parent));
+      } else if (primitive is Parameter && _isDeadParameter(primitive)) {
+        worklist.add(new _ReductionTask(_ReductionKind.DEAD_PARAMETER,
+            primitive));
       }
     } else if (reference.definition is Continuation) {
       Continuation cont = reference.definition;
@@ -486,29 +668,22 @@
           worklist.add(new _ReductionTask(_ReductionKind.DEAD_CONT, cont));
         } else if (_isBetaContLin(cont)) {
           worklist.add(new _ReductionTask(_ReductionKind.BETA_CONT_LIN, cont));
+        } else if (_isBranchTargetOfUselessIf(cont)) {
+          worklist.add(
+              new _ReductionTask(_ReductionKind.BRANCH, cont.firstRef.parent));
         }
       }
     }
   }
 }
 
-
-
-class _ReductionKind {
-  final String name;
-  final int hashCode;
-
-  const _ReductionKind(this.name, this.hashCode);
-
-  static const _ReductionKind DEAD_VAL = const _ReductionKind('dead-val', 0);
-  static const _ReductionKind DEAD_CONT = const _ReductionKind('dead-cont', 1);
-  static const _ReductionKind BETA_CONT_LIN =
-      const _ReductionKind('beta-cont-lin', 2);
-  static const _ReductionKind ETA_CONT = const _ReductionKind('eta-cont', 3);
-  static const _ReductionKind DEAD_PARAMETER =
-      const _ReductionKind('dead-parameter', 4);
-
-  String toString() => name;
+enum _ReductionKind {
+  DEAD_VAL,
+  DEAD_CONT,
+  BETA_CONT_LIN,
+  ETA_CONT,
+  DEAD_PARAMETER,
+  BRANCH
 }
 
 /// Represents a reduction task on the worklist. Implements both hashCode and
@@ -518,12 +693,12 @@
   final Node node;
 
   int get hashCode {
-    assert(kind.hashCode < (1 << 3));
-    return (node.hashCode << 3) | kind.hashCode;
+    return (node.hashCode << 3) | kind.index;
   }
 
   _ReductionTask(this.kind, this.node) {
-    assert(node is Continuation || node is LetPrim || node is Parameter);
+    assert(node is Continuation || node is LetPrim || node is Parameter ||
+           node is Branch);
   }
 
   bool operator==(_ReductionTask that) {
@@ -532,10 +707,3 @@
 
   String toString() => "$kind: $node";
 }
-
-/// A dummy class used solely to mark nodes as deleted once they are removed
-/// from a term.
-class _DeletedNode extends Node {
-  accept(_) {}
-  setParentPointers() {}
-}
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
index 25fb1c9..0a21c3f 100644
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
@@ -448,10 +448,8 @@
   }
 
   @override
-  bool areDisjoint(TypeMask leftType, TypeMask rightType) {
-    TypeMask intersected = intersection(leftType, rightType);
-    return intersected.isEmpty && !intersected.isNullable;
-  }
+  bool areDisjoint(TypeMask leftType, TypeMask rightType) =>
+      leftType.isDisjoint(rightType, classWorld);
 
   @override
   bool isMorePreciseOrEqual(TypeMask t1, TypeMask t2) {
@@ -468,8 +466,8 @@
     }
     if (type is types.InterfaceType) {
       TypeMask typeAsMask = allowNull
-      ? new TypeMask.subtype(type.element, classWorld)
-      : new TypeMask.nonNullSubtype(type.element, classWorld);
+          ? new TypeMask.subtype(type.element, classWorld)
+          : new TypeMask.nonNullSubtype(type.element, classWorld);
       if (areDisjoint(value, typeAsMask)) {
         // Disprove the subtype relation based on the class alone.
         return AbstractBool.False;
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index aa26e31..6277667 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -714,8 +714,10 @@
   final CpsFunctionCompiler _functionCompiler;
   final Map<Variable, ConstantValue> _values= <Variable, ConstantValue>{};
   final ConstantPropagationLattice _lattice;
+  final bool recomputeAll;
 
-  TypePropagator(CpsFunctionCompiler functionCompiler)
+  TypePropagator(CpsFunctionCompiler functionCompiler,
+      {this.recomputeAll: false})
       : _functionCompiler = functionCompiler,
         _lattice = new ConstantPropagationLattice(functionCompiler);
 
@@ -731,7 +733,7 @@
         _values,
         _internalError);
 
-    analyzer.analyze(root);
+    analyzer.analyze(root, recomputeAll);
 
     // Transform. Uses the data acquired in the previous analysis phase to
     // replace branches with fixed targets and side-effect-free expressions
@@ -1047,6 +1049,16 @@
       push(invoke);
       return;
     }
+
+    // Shortcut negation to help simplify control flow. The tree IR will insert
+    // a negation again if that's useful.
+    if (condition is ApplyBuiltinOperator &&
+        condition.operator == BuiltinOperator.IsFalsy) {
+      node.condition.changeTo(condition.arguments.single.definition);
+      node.trueContinuation.changeTo(falseCont);
+      node.falseContinuation.changeTo(trueCont);
+      return;
+    }
   }
 
   void visitInvokeContinuation(InvokeContinuation node) {
@@ -1142,7 +1154,7 @@
       return cps;
     }
 
-    if (node.selector.isOperator && node.arguments.length == 2) {
+    if (node.selector.isOperator && node.dartArgumentsLength == 1) {
       Primitive leftArg = node.dartReceiver;
       Primitive rightArg = node.dartArgument(0);
       AbstractConstantValue left = getValue(leftArg);
@@ -1223,7 +1235,7 @@
         }
       }
     }
-    if (node.selector.isOperator && node.arguments.length == 1) {
+    if (node.selector.isOperator && node.dartArgumentsLength == 0) {
       Primitive argument = node.dartReceiver;
       AbstractConstantValue value = getValue(argument);
 
@@ -1244,7 +1256,7 @@
       Primitive receiver = node.dartReceiver;
       AbstractConstantValue receiverValue = getValue(receiver);
       if (name == 'remainder') {
-        if (node.arguments.length == 2) {
+        if (node.dartArgumentsLength == 1) {
           Primitive arg = node.dartArgument(0);
           AbstractConstantValue argValue = getValue(arg);
           if (lattice.isDefinitelyInt(receiverValue, allowNull: true) &&
@@ -1255,7 +1267,7 @@
           }
         }
       } else if (name == 'codeUnitAt') {
-        if (node.arguments.length == 2) {
+        if (node.dartArgumentsLength == 1) {
           Primitive index = node.dartArgument(0);
           if (lattice.isDefinitelyString(receiverValue) &&
               lattice.isDefinitelyInt(getValue(index))) {
@@ -1534,7 +1546,7 @@
         // Check that all uses of the iterator are 'moveNext' and 'current'.
         assert(!isInterceptedSelector(Selectors.moveNext));
         assert(!isInterceptedSelector(Selectors.current));
-        for (Reference ref in iterator.effectiveUses) {
+        for (Reference ref in iterator.refinedUses) {
           if (ref.parent is! InvokeMethod) return null;
           InvokeMethod use = ref.parent;
           if (ref != use.receiver) return null;
@@ -1551,7 +1563,7 @@
         MutableVariable current = new MutableVariable(new LoopItemEntity());
 
         // Rewrite all uses of the iterator.
-        for (Reference ref in iterator.effectiveUses) {
+        for (Reference ref in iterator.refinedUses) {
           InvokeMethod use = ref.parent;
           if (use.selector == Selectors.current) {
             // Rewrite iterator.current to a use of the 'current' variable.
@@ -1760,7 +1772,7 @@
 
       // If there are multiple uses, we cannot eliminate the getter call and
       // therefore risk duplicating its side effects.
-      if (!isPure && tearOff.hasMultipleEffectiveUses) return null;
+      if (!isPure && tearOff.hasMultipleRefinedUses) return null;
 
       // If the getter call is impure, we risk reordering side effects,
       // unless it is immediately prior to the closure call.
@@ -1776,7 +1788,7 @@
         sourceInformation: node.sourceInformation);
       node.receiver.changeTo(new Parameter(null)); // Remove the tear off use.
 
-      if (tearOff.hasNoEffectiveUses) {
+      if (tearOff.hasNoRefinedUses) {
         // Eliminate the getter call if it has no more uses.
         // This cannot be delegated to other optimizations because we need to
         // avoid duplication of side effects.
@@ -1991,7 +2003,7 @@
   //     Nothing happens. The primitive remains as it is.
   //
 
-  void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
+  visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
     ast.DartString getString(AbstractConstantValue value) {
       StringConstantValue constant = value.constant;
       return constant.primitiveValue;
@@ -2051,42 +2063,70 @@
         Primitive rightArg = node.arguments[1].definition;
         AbstractConstantValue left = getValue(leftArg);
         AbstractConstantValue right = getValue(rightArg);
-        if (lattice.isDefinitelyBool(left) &&
-            right.isConstant &&
-            right.constant.isTrue) {
-          // Replace identical(x, true) by x when x is known to be a boolean.
-          // Note that this is not safe if x is null, because the value might
-          // not be used as a condition.
-          node.replaceUsesWith(leftArg);
-        } else if (lattice.isDefinitelyBool(right) &&
-            left.isConstant &&
-            left.constant.isTrue) {
-          node.replaceUsesWith(rightArg);
-        } else if (left.isNullConstant || right.isNullConstant) {
+        BuiltinOperator newOperator;
+        if (left.isNullConstant || right.isNullConstant) {
           // Use `==` for comparing against null, so JS undefined and JS null
           // are considered equal.
-          node.operator = BuiltinOperator.LooseEq;
+          newOperator = BuiltinOperator.LooseEq;
         } else if (!left.isNullable || !right.isNullable) {
           // If at most one operand can be Dart null, we can use `===`.
           // This is not safe when we might compare JS null and JS undefined.
-          node.operator = BuiltinOperator.StrictEq;
+          newOperator = BuiltinOperator.StrictEq;
         } else if (lattice.isDefinitelyNum(left, allowNull: true) &&
                    lattice.isDefinitelyNum(right, allowNull: true)) {
           // If both operands can be null, but otherwise are of the same type,
           // we can use `==` for comparison.
           // This is not safe e.g. for comparing strings against numbers.
-          node.operator = BuiltinOperator.LooseEq;
+          newOperator = BuiltinOperator.LooseEq;
         } else if (lattice.isDefinitelyString(left, allowNull: true) &&
                    lattice.isDefinitelyString(right, allowNull: true)) {
-          node.operator = BuiltinOperator.LooseEq;
+          newOperator = BuiltinOperator.LooseEq;
         } else if (lattice.isDefinitelyBool(left, allowNull: true) &&
                    lattice.isDefinitelyBool(right, allowNull: true)) {
-          node.operator = BuiltinOperator.LooseEq;
+          newOperator = BuiltinOperator.LooseEq;
+        }
+        if (newOperator != null) {
+          return new ApplyBuiltinOperator(newOperator,
+              node.arguments.map((ref) => ref.definition).toList(),
+              node.sourceInformation);
+        }
+        break;
+
+      case BuiltinOperator.StrictEq:
+      case BuiltinOperator.LooseEq:
+      case BuiltinOperator.StrictNeq:
+      case BuiltinOperator.LooseNeq:
+        bool negated =
+            node.operator == BuiltinOperator.StrictNeq ||
+            node.operator == BuiltinOperator.LooseNeq;
+        for (int firstIndex in [0, 1]) {
+          int secondIndex = 1 - firstIndex;
+          Primitive firstArg = node.arguments[firstIndex].definition;
+          Primitive secondArg = node.arguments[secondIndex].definition;
+          AbstractConstantValue first = getValue(firstArg);
+          if (!lattice.isDefinitelyBool(first)) continue;
+          AbstractConstantValue second = getValue(secondArg);
+          if (!second.isConstant || !second.constant.isBool) continue;
+          bool isTrueConstant = second.constant.isTrue;
+          if (isTrueConstant == !negated) {
+            // (x === true) ==> x
+            // (x !== false) ==> x
+            node.replaceUsesWith(firstArg);
+            return null;
+          } else {
+            // (x === false) ==> !x
+            // (x !== true) ==> !x
+            return new ApplyBuiltinOperator(
+                BuiltinOperator.IsFalsy,
+                [firstArg],
+                node.sourceInformation);
+          }
         }
         break;
 
       default:
     }
+    return null;
   }
 
   void visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
@@ -2288,8 +2328,11 @@
                          this.values,
                          this.internalError);
 
-  void analyze(FunctionDefinition root) {
+  void analyze(FunctionDefinition root, bool recomputeAll) {
     reachableContinuations.clear();
+    if (recomputeAll) {
+      new ResetAnalysisInfo(reachableContinuations, values).visit(root);
+    }
 
     // Initially, only the root node is reachable.
     push(root);
@@ -2532,7 +2575,7 @@
 
     // Calculate the resulting constant if possible.
     String opname = node.selector.name;
-    if (node.arguments.length == 1) {
+    if (node.dartArgumentsLength == 0) {
       // Unary operator.
       if (opname == "unary-") {
         opname = "-";
@@ -2540,7 +2583,7 @@
       UnaryOperator operator = UnaryOperator.parse(opname);
       AbstractConstantValue result = lattice.unaryOp(operator, receiver);
       return finish(result, canReplace: !receiver.isNullable);
-    } else if (node.arguments.length == 2) {
+    } else if (node.dartArgumentsLength == 1) {
       // Binary operator.
       AbstractConstantValue right = getValue(node.dartArgument(0));
       BinaryOperator operator = BinaryOperator.parse(opname);
@@ -2619,37 +2662,34 @@
 
       case BuiltinOperator.Identical:
       case BuiltinOperator.StrictEq:
+      case BuiltinOperator.StrictNeq:
       case BuiltinOperator.LooseEq:
-        AbstractConstantValue leftConst =
-            getValue(node.arguments[0].definition);
-        AbstractConstantValue rightConst =
-            getValue(node.arguments[1].definition);
-        ConstantValue leftValue = leftConst.constant;
-        ConstantValue rightValue = rightConst.constant;
-        if (leftConst.isNothing || rightConst.isNothing) {
+      case BuiltinOperator.LooseNeq:
+        bool negated =
+            node.operator == BuiltinOperator.StrictNeq ||
+            node.operator == BuiltinOperator.LooseNeq;
+        AbstractConstantValue left = getValue(node.arguments[0].definition);
+        AbstractConstantValue right = getValue(node.arguments[1].definition);
+        if (left.isNothing || right.isNothing) {
           setValue(node, lattice.nothing);
-          return; // And come back later.
-        } else if (!leftConst.isConstant || !rightConst.isConstant) {
-          TypeMask leftType = leftConst.type;
-          TypeMask rightType = rightConst.type;
-          if (typeSystem.areDisjoint(leftType, rightType)) {
-            setValue(node,
-                constantValue(new FalseConstantValue(), typeSystem.boolType));
-          } else {
-            setValue(node, nonConstant(typeSystem.boolType));
-          }
           return;
-        } else if (leftValue.isPrimitive && rightValue.isPrimitive) {
-          assert(leftConst.isConstant && rightConst.isConstant);
-          PrimitiveConstantValue left = leftValue;
-          PrimitiveConstantValue right = rightValue;
-          // Should this be constantSystem.identity.fold(left, right)?
-          ConstantValue result =
-            new BoolConstantValue(left.primitiveValue == right.primitiveValue);
-          setValue(node, constantValue(result, typeSystem.boolType));
-        } else {
-          setValue(node, nonConstant(typeSystem.boolType));
         }
+        if (left.isConstant && right.isConstant) {
+          ConstantValue equal = lattice.constantSystem.identity.fold(
+              left.constant, right.constant);
+          if (equal != null && equal.isBool) {
+            ConstantValue result =
+                new BoolConstantValue(equal.isTrue == !negated);
+            setValue(node, constantValue(result, typeSystem.boolType));
+            return;
+          }
+        }
+        if (typeSystem.areDisjoint(left.type, right.type)) {
+          ConstantValue result = new BoolConstantValue(negated);
+          setValue(node, constantValue(result, typeSystem.boolType));
+          return;
+        }
+        setValue(node, nonConstant(typeSystem.boolType));
         break;
 
       case BuiltinOperator.NumAdd:
@@ -2862,12 +2902,6 @@
     }
   }
 
-  void visitLiteralMap(LiteralMap node) {
-    // Constant maps are translated into (Constant MapConstant(...)) IR nodes,
-    // and thus LiteralMap nodes are NonConst.
-    setValue(node, nonConstant(typeSystem.mapType));
-  }
-
   void visitConstant(Constant node) {
     ConstantValue value = node.value;
     if (value.isDummy || !value.isConstant) {
@@ -2980,7 +3014,21 @@
 
   @override
   void visitForeignCode(ForeignCode node) {
-    setValue(node, nonConstant(node.type));
+    bool firstArgumentIsNullable = false;
+    if (node.arguments.length > 0) {
+      AbstractConstantValue first = getValue(node.arguments.first.definition);
+      if (first.isNothing) {
+        setValue(node, nothing);
+        return;
+      }
+      firstArgumentIsNullable = first.isNullable;
+    }
+    setValue(node, nonConstant(node.storedType));
+    node.isSafeForElimination =
+        !node.nativeBehavior.sideEffects.hasSideEffects() &&
+        (!node.nativeBehavior.throwBehavior.canThrow ||
+         (!firstArgumentIsNullable &&
+          node.nativeBehavior.throwBehavior.isOnlyNullNSMGuard));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/cps_ir/update_refinements.dart b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
index d93e747..48e3242 100644
--- a/pkg/compiler/lib/src/cps_ir/update_refinements.dart
+++ b/pkg/compiler/lib/src/cps_ir/update_refinements.dart
@@ -20,7 +20,7 @@
 
   final TypeMaskSystem typeSystem;
 
-  Map<Primitive, Refinement> refinementFor = <Primitive, Refinement>{};
+  Map<Primitive, Primitive> refinementFor = <Primitive, Primitive>{};
 
   UpdateRefinements(this.typeSystem);
 
@@ -29,11 +29,33 @@
   }
 
   Expression traverseLetPrim(LetPrim node) {
+    Expression next = node.body;
     visit(node.primitive);
-    return node.body;
+    return next;
   }
 
-  @override
+  visitNullCheck(NullCheck node) {
+    if (refine(node.value)) {
+      Primitive value = node.value.definition;
+      if (value.type.isNullable) {
+        // Update the type if the input has changed.
+        node.type = value.type.nonNullable();
+      } else {
+        node..replaceUsesWith(value)..destroy();
+        LetPrim letPrim = node.parent;
+        letPrim.remove();
+        return;
+      }
+    }
+    // Use the NullCheck as a refinement.
+    Primitive value = node.effectiveDefinition;
+    Primitive old = refinementFor[value];
+    refinementFor[value] = node;
+    pushAction(() {
+      refinementFor[value] = old;
+    });
+  }
+
   visitRefinement(Refinement node) {
     if (refine(node.value)) {
       // Update the type if the input has changed.
@@ -41,14 +63,13 @@
           node.refineType);
     }
     Primitive value = node.effectiveDefinition;
-    Refinement old = refinementFor[value];
+    Primitive old = refinementFor[value];
     refinementFor[value] = node;
     pushAction(() {
       refinementFor[value] = old;
     });
   }
 
-  @override
   processReference(Reference ref) {
     refine(ref);
   }
@@ -56,7 +77,7 @@
   bool refine(Reference ref) {
     Definition def = ref.definition;
     if (def is Primitive) {
-      Refinement refinement = refinementFor[def.effectiveDefinition];
+      Primitive refinement = refinementFor[def.effectiveDefinition];
       if (refinement != null && refinement != ref.definition) {
         ref.changeTo(refinement);
         return true;
diff --git a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
deleted file mode 100644
index 90d4ecf..0000000
--- a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
+++ /dev/null
@@ -1,3732 +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.
-
-// The messages in this file should meet the following guide lines:
-//
-// 1. The message should be a complete sentence starting with an uppercase
-// letter, and ending with a period.
-//
-// 2. Reserved words and embedded identifiers should be in single quotes, so
-// prefer double quotes for the complete message. For example, "The
-// class '#{className}' can't use 'super'." Notice that the word 'class' in the
-// preceding message is not quoted as it refers to the concept 'class', not the
-// reserved word. On the other hand, 'super' refers to the reserved word. Do
-// not quote 'null' and numeric literals.
-//
-// 3. Do not try to compose messages, as it can make translating them hard.
-//
-// 4. Try to keep the error messages short, but informative.
-//
-// 5. Use simple words and terminology, assume the reader of the message
-// doesn't have an advanced degree in math, and that English is not the
-// reader's native language. Do not assume any formal computer science
-// training. For example, do not use Latin abbreviations (prefer "that is" over
-// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
-// only if" and "iff", that level of precision is unnecessary.
-//
-// 6. Prefer contractions when they are in common use, for example, prefer
-// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
-// off-putting to people new to programming.
-//
-// 7. Use common terminology, preferably from the Dart Language
-// Specification. This increases the user's chance of finding a good
-// explanation on the web.
-//
-// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
-// product that crashes with a "tongue-in-cheek" message, especially if you did
-// not want to use this product to begin with.
-//
-// 9. Do not lie, that is, do not write error messages containing phrases like
-// "can't happen".  If the user ever saw this message, it would be a
-// lie. Prefer messages like: "Internal error: This function should not be
-// called when 'x' is null.".
-//
-// 10. Prefer to not use imperative tone. That is, the message should not sound
-// accusing or like it is ordering the user around. The computer should
-// describe the problem, not criticize for violating the specification.
-//
-// Other things to keep in mind:
-//
-// An INFO message should always be preceded by a non-INFO message, and the
-// INFO messages are additional details about the preceding non-INFO
-// message. For example, consider duplicated elements. First report a WARNING
-// or ERROR about the duplicated element, and then report an INFO about the
-// location of the existing element.
-//
-// Generally, we want to provide messages that consists of three sentences:
-// 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].
-
-/// Padding used before and between import chains in the message for
-/// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
-const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
-
-/// Padding used before and between import chains in the message for
-/// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
-const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
-
-/// Padding used before and between import chains in the message for
-/// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
-const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
-
-const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
-
-final Map<String, Map> MESSAGES = {
-  /// Do not use this. It is here for legacy and debugging. It violates item
-  /// 4 of the guide lines for error messages in the beginning of the file.
-  'GENERIC': {'id': 'SOWPSL', 'template': "#{text}",},
-
-  'NOT_ASSIGNABLE': {
-    'id': 'VYNMAP',
-    'template': "'#{fromType}' is not assignable to '#{toType}'.",
-  },
-
-  'FORIN_NOT_ASSIGNABLE': {
-    'id': 'XQSRXO',
-    'template': "The element type '#{currentType}' of '#{expressionType}' "
-        "is not assignable to '#{elementType}'.",
-  },
-
-  'VOID_EXPRESSION': {
-    'id': 'QHEVSC',
-    'template': "Expression does not yield a value.",
-  },
-
-  'VOID_VARIABLE': {
-    'id': 'RFEURK',
-    'template': "Variable cannot be of type void.",
-  },
-
-  'RETURN_VALUE_IN_VOID': {
-    'id': 'FUNYDS',
-    'template': "Cannot return value from void function.",
-  },
-
-  'RETURN_NOTHING': {
-    'id': 'HPPODJ',
-    'template': "Value of type '#{returnType}' expected.",
-  },
-
-  'MISSING_ARGUMENT': {
-    'id': 'LHMCIK',
-    'template': "Missing argument of type '#{argumentType}'.",
-  },
-
-  'ADDITIONAL_ARGUMENT': {'id': 'GMITMA', 'template': "Additional argument.",},
-
-  'NAMED_ARGUMENT_NOT_FOUND': {
-    'id': 'UCEARQ',
-    'template': "No named argument '#{argumentName}' found on method.",
-  },
-
-  'MEMBER_NOT_FOUND': {
-    'id': 'MMQODC',
-    'template': "No member named '#{memberName}' in class '#{className}'.",
-  },
-
-  'AWAIT_MEMBER_NOT_FOUND': {
-    'id': 'XIDLIP',
-    'template': "No member named 'await' in class '#{className}'.",
-    'howToFix': "Did you mean to add the 'async' marker "
-        "to '#{functionName}'?",
-    'examples': [
-      """
-class A {
-m() => await -3;
-}
-main() => new A().m();
-"""
-    ],
-  },
-
-  'AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE': {
-    'id': 'HBIYGN',
-    'template': "No member named 'await' in class '#{className}'.",
-    'howToFix': "Did you mean to add the 'async' marker "
-        "to the enclosing function?",
-    'examples': [
-      """
-class A {
-m() => () => await -3;
-}
-main() => new A().m();
-"""
-    ],
-  },
-
-  'METHOD_NOT_FOUND': {
-    'id': 'QYYHBU',
-    'template': "No method named '#{memberName}' in class '#{className}'.",
-  },
-
-  'OPERATOR_NOT_FOUND': {
-    'id': 'SXGOYS',
-    'template': "No operator '#{memberName}' in class '#{className}'.",
-  },
-
-  'SETTER_NOT_FOUND': {
-    'id': 'ADFRVF',
-    'template': "No setter named '#{memberName}' in class '#{className}'.",
-  },
-
-  'SETTER_NOT_FOUND_IN_SUPER': {
-    'id': 'OCVRNJ',
-    'template': "No setter named '#{name}' in superclass of '#{className}'.",
-  },
-
-  'GETTER_NOT_FOUND': {
-    'id': 'PBNXAC',
-    'template': "No getter named '#{memberName}' in class '#{className}'.",
-  },
-
-  'NOT_CALLABLE': {
-    'id': 'SEMKJO',
-    'template': "'#{elementName}' is not callable.",
-  },
-
-  'MEMBER_NOT_STATIC': {
-    'id': 'QIOISX',
-    'template': "'#{className}.#{memberName}' is not static.",
-  },
-
-  'NO_INSTANCE_AVAILABLE': {
-    'id': 'FQPYLR',
-    'template': "'#{name}' is only available in instance methods.",
-  },
-
-  'NO_THIS_AVAILABLE': {
-    'id': 'LXPXKG',
-    'template': "'this' is only available in instance methods.",
-  },
-
-  'PRIVATE_ACCESS': {
-    'id': 'DIMHCR',
-    'template': "'#{name}' is declared private within library "
-        "'#{libraryName}'.",
-  },
-
-  'THIS_IS_THE_DECLARATION': {
-    'id': 'YIJWTO',
-    'template': "This is the declaration of '#{name}'.",
-  },
-
-  'THIS_IS_THE_METHOD': {
-    'id': 'PYXWLF',
-    'template': "This is the method declaration.",
-  },
-
-  'CANNOT_RESOLVE': {'id': 'SPVJYO', 'template': "Cannot resolve '#{name}'.",},
-
-  'CANNOT_RESOLVE_AWAIT': {
-    'id': 'YQYLRS',
-    'template': "Cannot resolve '#{name}'.",
-    'howToFix': "Did you mean to add the 'async' marker "
-        "to '#{functionName}'?",
-    'examples': ["main() => await -3;", "foo() => await -3; main() => foo();"],
-  },
-
-  'CANNOT_RESOLVE_AWAIT_IN_CLOSURE': {
-    'id': 'SIXRAA',
-    'template': "Cannot resolve '#{name}'.",
-    'howToFix': "Did you mean to add the 'async' marker "
-        "to the enclosing function?",
-    'examples': ["main() { (() => await -3)(); }",],
-  },
-
-  'CANNOT_RESOLVE_IN_INITIALIZER': {
-    'id': 'VVEQFD',
-    'template':
-        "Cannot resolve '#{name}'. It would be implicitly looked up on this "
-        "instance, but instances are not available in initializers.",
-    'howToFix': "Try correcting the unresolved reference or move the "
-        "initialization to a constructor body.",
-    'examples': [
-      """
-class A {
-var test = unresolvedName;
-}
-main() => new A();
-"""
-    ],
-  },
-
-  'CANNOT_RESOLVE_CONSTRUCTOR': {
-    'id': 'QRPATN',
-    'template': "Cannot resolve constructor '#{constructorName}'.",
-  },
-
-  'CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT': {
-    'id': 'IFKCHF',
-    'template': "cannot resolve constructor '#{constructorName}' "
-        "for implicit super call.",
-    'howToFix': "Try explicitly invoking a constructor of the super class",
-    'examples': [
-      """
-class A {
-A.foo() {}
-}
-class B extends A {
-B();
-}
-main() => new B();
-"""
-    ],
-  },
-
-  'INVALID_UNNAMED_CONSTRUCTOR_NAME': {
-    'id': 'VPJLVI',
-    'template': "Unnamed constructor name must be '#{name}'.",
-  },
-
-  'INVALID_CONSTRUCTOR_NAME': {
-    'id': 'LMDCAS',
-    'template': "Constructor name must start with '#{name}'.",
-  },
-
-  'CANNOT_RESOLVE_TYPE': {
-    'id': 'PQIAPG',
-    'template': "Cannot resolve type '#{typeName}'.",
-  },
-
-  'DUPLICATE_DEFINITION': {
-    'id': 'LVTYNW',
-    'template': "Duplicate definition of '#{name}'.",
-    'howToFix': "Try to rename or remove this definition.",
-    'examples': [
-      """
-class C {
-void f() {}
-int get f => 1;
-}
-
-main() {
-new C();
-}
-
-"""
-    ],
-  },
-
-  'EXISTING_DEFINITION': {
-    'id': 'DAUYKK',
-    'template': "Existing definition of '#{name}'.",
-  },
-
-  'DUPLICATE_IMPORT': {
-    'id': 'KYJFJN',
-    'template': "Duplicate import of '#{name}'.",
-  },
-
-  'HIDDEN_IMPORT': {
-    'id': 'ACRDPR',
-    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-        "from library '#{hidingUri}'.",
-    'howToFix': "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
-    'examples': [
-      {
-        'main.dart': """
-import 'dart:async'; // This imports a class Future.
-import 'future.dart';
-
-void main() => new Future();""",
-        'future.dart': """
-library future;
-
-class Future {}"""
-      },
-      {
-        'main.dart': """
-import 'future.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-        'future.dart': """
-library future;
-
-class Future {}"""
-      },
-      {
-        'main.dart': """
-import 'export.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-        'future.dart': """
-library future;
-
-class Future {}""",
-        'export.dart': """
-library export;
-
-export 'future.dart';"""
-      },
-      {
-        'main.dart': """
-import 'future.dart' as prefix;
-import 'dart:async' as prefix; // This imports a class Future.
-
-void main() => new prefix.Future();""",
-        'future.dart': """
-library future;
-
-class Future {}"""
-      }
-    ],
-  },
-
-  'HIDDEN_IMPLICIT_IMPORT': {
-    'id': 'WDNFSI',
-    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-        "from library '#{hidingUri}'.",
-    'howToFix': "Try adding an explicit "
-        "'import \"#{hiddenUri}\" hide #{name}'.",
-    'examples': [
-      {
-        'main.dart': """
-// This hides the implicit import of class Type from dart:core.
-import 'type.dart';
-
-void main() => new Type();""",
-        'type.dart': """
-library type;
-
-class Type {}"""
-      },
-      {
-        'conflictsWithDart.dart': """
-library conflictsWithDart;
-
-class Duration {
-static var x = 100;
-}
-""",
-        'conflictsWithDartAsWell.dart': """
-library conflictsWithDartAsWell;
-
-class Duration {
-static var x = 100;
-}
-""",
-        'main.dart': r"""
-library testDartConflicts;
-
-import 'conflictsWithDart.dart';
-import 'conflictsWithDartAsWell.dart';
-
-main() {
-print("Hail Caesar ${Duration.x}");
-}
-"""
-      }
-    ],
-  },
-
-  'DUPLICATE_EXPORT': {
-    'id': 'XGNOCL',
-    'template': "Duplicate export of '#{name}'.",
-    'howToFix': "Try adding 'hide #{name}' to one of the exports.",
-    'examples': [
-      {
-        'main.dart': """
-export 'decl1.dart';
-export 'decl2.dart';
-
-main() {}""",
-        'decl1.dart': "class Class {}",
-        'decl2.dart': "class Class {}"
-      }
-    ],
-  },
-
-  'DUPLICATE_EXPORT_CONT': {
-    'id': 'BDROED',
-    'template': "This is another export of '#{name}'.",
-  },
-
-  'DUPLICATE_EXPORT_DECL': {
-    'id': 'GFFLMA',
-    'template':
-        "The exported '#{name}' from export #{uriString} is defined here.",
-  },
-
-  'EMPTY_HIDE': {
-    'id': 'ODFAOC',
-    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
-    'howToFix': "Try removing '#{name}' the 'hide' clause.",
-    'examples': [
-      {
-        'main.dart': """
-import 'dart:core' hide Foo;
-
-main() {}"""
-      },
-      {
-        'main.dart': """
-export 'dart:core' hide Foo;
-
-main() {}"""
-      },
-    ],
-  },
-
-  'EMPTY_SHOW': {
-    'id': 'EXONIK',
-    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
-    'howToFix': "Try removing '#{name}' from the 'show' clause.",
-    'examples': [
-      {
-        'main.dart': """
-import 'dart:core' show Foo;
-
-main() {}"""
-      },
-      {
-        'main.dart': """
-export 'dart:core' show Foo;
-
-main() {}"""
-      },
-    ],
-  },
-
-  'NOT_A_TYPE': {'id': 'CTTAXD', 'template': "'#{node}' is not a type.",},
-
-  'NOT_A_PREFIX': {'id': 'LKEUMI', 'template': "'#{node}' is not a prefix.",},
-
-  'PREFIX_AS_EXPRESSION': {
-    'id': 'CYIMBJ',
-    'template': "Library prefix '#{prefix}' is not a valid expression.",
-  },
-
-  'CANNOT_FIND_CONSTRUCTOR': {
-    'id': 'DROVNH',
-    'template': "Cannot find constructor '#{constructorName}' in class "
-        "'#{className}'.",
-  },
-
-  'CANNOT_FIND_UNNAMED_CONSTRUCTOR': {
-    'id': 'GDCTGB',
-    'template': "Cannot find unnamed constructor in class "
-        "'#{className}'.",
-  },
-
-  'CYCLIC_CLASS_HIERARCHY': {
-    'id': 'HKFYOA',
-    'template': "'#{className}' creates a cycle in the class hierarchy.",
-  },
-
-  'CYCLIC_REDIRECTING_FACTORY': {
-    'id': 'QGETJC',
-    'template': "Redirecting factory leads to a cyclic redirection.",
-  },
-
-  'INVALID_RECEIVER_IN_INITIALIZER': {
-    'id': 'SYUTHA',
-    'template': "Field initializer expected.",
-  },
-
-  'NO_SUPER_IN_STATIC': {
-    'id': 'HSCESG',
-    'template': "'super' is only available in instance methods.",
-  },
-
-  'DUPLICATE_INITIALIZER': {
-    'id': 'GKVFEP',
-    'template': "Field '#{fieldName}' is initialized more than once.",
-  },
-
-  'ALREADY_INITIALIZED': {
-    'id': 'NCRMVD',
-    'template': "'#{fieldName}' was already initialized here.",
-  },
-
-  'INIT_STATIC_FIELD': {
-    'id': 'DBSRHA',
-    'template': "Cannot initialize static field '#{fieldName}'.",
-  },
-
-  'NOT_A_FIELD': {
-    'id': 'FYEPLC',
-    'template': "'#{fieldName}' is not a field.",
-  },
-
-  'CONSTRUCTOR_CALL_EXPECTED': {
-    'id': 'GEJCDX',
-    'template': "only call to 'this' or 'super' constructor allowed.",
-  },
-
-  'INVALID_FOR_IN': {
-    'id': 'AUQJBG',
-    'template': "Invalid for-in variable declaration.",
-  },
-
-  'INVALID_INITIALIZER': {'id': 'JKUKSA', 'template': "Invalid initializer.",},
-
-  'FUNCTION_WITH_INITIALIZER': {
-    'id': 'BNRDDK',
-    'template': "Only constructors can have initializers.",
-  },
-
-  'REDIRECTING_CONSTRUCTOR_CYCLE': {
-    'id': 'CQTMEP',
-    'template': "Cyclic constructor redirection.",
-  },
-
-  'REDIRECTING_CONSTRUCTOR_HAS_BODY': {
-    'id': 'WXJQNE',
-    'template': "Redirecting constructor can't have a body.",
-  },
-
-  'CONST_CONSTRUCTOR_HAS_BODY': {
-    'id': 'GNEFQG',
-    'template': "Const constructor or factory can't have a body.",
-    'howToFix': "Remove the 'const' keyword or the body",
-    'examples': [
-      """
-class C {
-const C() {}
-}
-
-main() => new C();"""
-    ],
-  },
-
-  'REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER': {
-    'id': 'NUIDSF',
-    'template': "Redirecting constructor cannot have other initializers.",
-  },
-
-  'SUPER_INITIALIZER_IN_OBJECT': {
-    'id': 'DXYGND',
-    'template': "'Object' cannot have a super initializer.",
-  },
-
-  'DUPLICATE_SUPER_INITIALIZER': {
-    'id': 'FFKOWP',
-    'template': "Cannot have more than one super initializer.",
-  },
-
-  'SUPER_CALL_TO_FACTORY': {
-    'id': 'YTOWGV',
-    'template': "The target of the superinitializer must be a generative "
-        "constructor.",
-    'howToFix': "Try calling another constructor on the superclass.",
-    'examples': [
-      """
-class Super {
-factory Super() => null;
-}
-class Class extends Super {}
-main() => new Class();
-""",
-      """
-class Super {
-factory Super() => null;
-}
-class Class extends Super {
-Class();
-}
-main() => new Class();
-""",
-      """
-class Super {
-factory Super() => null;
-}
-class Class extends Super {
-Class() : super();
-}
-main() => new Class();
-""",
-      """
-class Super {
-factory Super.foo() => null;
-}
-class Class extends Super {
-Class() : super.foo();
-}
-main() => new Class();
-"""
-    ],
-  },
-
-  'THIS_CALL_TO_FACTORY': {
-    'id': 'JLATDB',
-    'template': "The target of the redirection clause must be a generative "
-        "constructor",
-    'howToFix': "Try redirecting to another constructor.",
-    'examples': [
-      """
-class Class {
-factory Class() => null;
-Class.foo() : this();
-}
-main() => new Class.foo();
-""",
-      """
-class Class {
-factory Class.foo() => null;
-Class() : this.foo();
-}
-main() => new Class();
-"""
-    ],
-  },
-
-  'INVALID_CONSTRUCTOR_ARGUMENTS': {
-    'id': 'WVPLKL',
-    'template': "Arguments do not match the expected parameters of constructor "
-        "'#{constructorName}'.",
-  },
-
-  'NO_MATCHING_CONSTRUCTOR': {
-    'id': 'OJQQLE',
-    'template':
-        "'super' call arguments and constructor parameters do not match.",
-  },
-
-  'NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT': {
-    'id': 'WHCVID',
-    'template': "Implicit 'super' call arguments and constructor parameters "
-        "do not match.",
-  },
-
-  'CONST_CALLS_NON_CONST': {
-    'id': 'CQFHXC',
-    'template': "'const' constructor cannot call a non-const constructor.",
-  },
-
-  'CONST_CALLS_NON_CONST_FOR_IMPLICIT': {
-    'id': 'SFCEXS',
-    'template': "'const' constructor cannot call a non-const constructor. "
-        "This constructor has an implicit call to a "
-        "super non-const constructor.",
-    'howToFix': "Try making the super constructor const.",
-    'examples': [
-      """
-class C {
-C(); // missing const
-}
-class D extends C {
-final d;
-const D(this.d);
-}
-main() => new D(0);"""
-    ],
-  },
-
-  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS': {
-    'id': 'XBHUDL',
-    'template': "Can't declare constructor 'const' on class #{className} "
-        "because the class contains non-final instance fields.",
-    'howToFix': "Try making all fields final.",
-    'examples': [
-      """
-class C {
-// 'a' must be declared final to allow for the const constructor.
-var a;
-const C(this.a);
-}
-
-main() => new C(0);"""
-    ],
-  },
-
-  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD': {
-    'id': 'YYAHVD',
-    'template': "This non-final field prevents using const constructors.",
-  },
-
-  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR': {
-    'id': 'FROWJB',
-    'template': "This const constructor is not allowed due to "
-        "non-final fields.",
-  },
-
-  'INITIALIZING_FORMAL_NOT_ALLOWED': {
-    'id': 'YIPXYP',
-    'template': "Initializing formal parameter only allowed in generative "
-        "constructor.",
-  },
-
-  'INVALID_PARAMETER': {
-    'id': 'OWWLIX',
-    'template': "Cannot resolve parameter.",
-  },
-
-  'NOT_INSTANCE_FIELD': {
-    'id': 'VSPKMU',
-    'template': "'#{fieldName}' is not an instance field.",
-  },
-
-  'THIS_PROPERTY': {'id': 'MWFIGH', 'template': "Expected an identifier.",},
-
-  'NO_CATCH_NOR_FINALLY': {
-    'id': 'OPJXPP',
-    'template': "Expected 'catch' or 'finally'.",
-  },
-
-  'EMPTY_CATCH_DECLARATION': {
-    'id': 'UNHCPY',
-    'template': "Expected an identifier in catch declaration.",
-  },
-
-  'EXTRA_CATCH_DECLARATION': {
-    'id': 'YGGRAK',
-    'template': "Extra parameter in catch declaration.",
-  },
-
-  'PARAMETER_WITH_TYPE_IN_CATCH': {
-    'id': 'EXQVDU',
-    'template': "Cannot use type annotations in catch.",
-  },
-
-  'PARAMETER_WITH_MODIFIER_IN_CATCH': {
-    'id': 'BQLKRF',
-    'template': "Cannot use modifiers in catch.",
-  },
-
-  'OPTIONAL_PARAMETER_IN_CATCH': {
-    'id': 'DAICPP',
-    'template': "Cannot use optional parameters in catch.",
-  },
-
-  'THROW_WITHOUT_EXPRESSION': {
-    'id': 'YHACYV',
-    'template': "Cannot use re-throw outside of catch block "
-        "(expression expected after 'throw').",
-  },
-
-  'UNBOUND_LABEL': {
-    'id': 'GLDXHY',
-    'template': "Cannot resolve label '#{labelName}'.",
-  },
-
-  'NO_BREAK_TARGET': {
-    'id': 'VBXXBE',
-    'template': "'break' statement not inside switch or loop.",
-  },
-
-  'NO_CONTINUE_TARGET': {
-    'id': 'JTTHHM',
-    'template': "'continue' statement not inside loop.",
-  },
-
-  'EXISTING_LABEL': {
-    'id': 'AHCSXF',
-    'template': "Original declaration of duplicate label '#{labelName}'.",
-  },
-
-  'DUPLICATE_LABEL': {
-    'id': 'HPULLI',
-    'template': "Duplicate declaration of label '#{labelName}'.",
-  },
-
-  'UNUSED_LABEL': {'id': 'KFREJO', 'template': "Unused label '#{labelName}'.",},
-
-  'INVALID_CONTINUE': {
-    'id': 'DSKTPX',
-    'template': "Target of continue is not a loop or switch case.",
-  },
-
-  'INVALID_BREAK': {
-    'id': 'MFCCWX',
-    'template': "Target of break is not a statement.",
-  },
-
-  'DUPLICATE_TYPE_VARIABLE_NAME': {
-    'id': 'BAYCCM',
-    'template': "Type variable '#{typeVariableName}' already declared.",
-  },
-
-  'TYPE_VARIABLE_WITHIN_STATIC_MEMBER': {
-    'id': 'XQLXRL',
-    'template': "Cannot refer to type variable '#{typeVariableName}' "
-        "within a static member.",
-  },
-
-  'TYPE_VARIABLE_IN_CONSTANT': {
-    'id': 'ANDEVG',
-    'template': "Constant expressions can't refer to type variables.",
-    'howToFix': "Try removing the type variable or replacing it with a "
-        "concrete type.",
-    'examples': [
-      """
-class C<T> {
-const C();
-
-m(T t) => const C<T>();
-}
-
-void main() => new C().m(null);
-"""
-    ],
-  },
-
-  'INVALID_TYPE_VARIABLE_BOUND': {
-    'id': 'WQAEDK',
-    'template': "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
-        "type variable '#{typeVariable}' of type '#{thisType}'.",
-    'howToFix': "Try to change or remove the type argument.",
-    'examples': [
-      """
-class C<T extends num> {}
-
-// 'String' is not a valid instantiation of T with bound num.'.
-main() => new C<String>();
-"""
-    ],
-  },
-
-  'INVALID_USE_OF_SUPER': {
-    'id': 'JKYYSN',
-    'template': "'super' not allowed here.",
-  },
-
-  'INVALID_CASE_DEFAULT': {
-    'id': 'ABSPBM',
-    'template': "'default' only allowed on last case of a switch.",
-  },
-
-  'SWITCH_CASE_TYPES_NOT_EQUAL': {
-    'id': 'UFQPBC',
-    'template': "'case' expressions do not all have type '#{type}'.",
-  },
-
-  'SWITCH_CASE_TYPES_NOT_EQUAL_CASE': {
-    'id': 'RDMVAC',
-    'template': "'case' expression of type '#{type}'.",
-  },
-
-  'SWITCH_CASE_FORBIDDEN': {
-    'id': 'UHSCSU',
-    'template': "'case' expression may not be of type '#{type}'.",
-  },
-
-  'SWITCH_CASE_VALUE_OVERRIDES_EQUALS': {
-    'id': 'NRTWXL',
-    'template': "'case' expression type '#{type}' overrides 'operator =='.",
-  },
-
-  'INVALID_ARGUMENT_AFTER_NAMED': {
-    'id': 'WAJURC',
-    'template': "Unnamed argument after named argument.",
-  },
-
-  'NOT_A_COMPILE_TIME_CONSTANT': {
-    'id': 'SBCHWL',
-    'template': "Not a compile-time constant.",
-  },
-
-  'DEFERRED_COMPILE_TIME_CONSTANT': {
-    'id': 'FHXTCK',
-    'template': "A deferred value cannot be used as a compile-time constant.",
-  },
-
-  'DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION': {
-    'id': 'TSBXLG',
-    'template': "A deferred class cannot be used to create a "
-        "compile-time constant.",
-  },
-
-  'CYCLIC_COMPILE_TIME_CONSTANTS': {
-    'id': 'JJWJYE',
-    'template': "Cycle in the compile-time constant computation.",
-  },
-
-  'CONSTRUCTOR_IS_NOT_CONST': {
-    'id': 'DOJCUX',
-    'template': "Constructor is not a 'const' constructor.",
-  },
-
-  'CONST_MAP_KEY_OVERRIDES_EQUALS': {
-    'id': 'VJNWEL',
-    'template': "Const-map key type '#{type}' overrides 'operator =='.",
-  },
-
-  'NO_SUCH_LIBRARY_MEMBER': {
-    'id': 'IOXVBA',
-    'template': "'#{libraryName}' has no member named '#{memberName}'.",
-  },
-
-  'CANNOT_INSTANTIATE_TYPEDEF': {
-    'id': 'KOYNMU',
-    'template': "Cannot instantiate typedef '#{typedefName}'.",
-  },
-
-  'REQUIRED_PARAMETER_WITH_DEFAULT': {
-    'id': 'CJWECI',
-    'template': "Non-optional parameters can't have a default value.",
-    'howToFix':
-        "Try removing the default value or making the parameter optional.",
-    'examples': [
-      """
-main() {
-foo(a: 1) => print(a);
-foo(2);
-}""",
-      """
-main() {
-foo(a = 1) => print(a);
-foo(2);
-}"""
-    ],
-  },
-
-  'NAMED_PARAMETER_WITH_EQUALS': {
-    'id': 'RPJDXD',
-    'template': "Named optional parameters can't use '=' to specify a default "
-        "value.",
-    'howToFix': "Try replacing '=' with ':'.",
-    'examples': [
-      """
-main() {
-foo({a = 1}) => print(a);
-foo(a: 2);
-}"""
-    ],
-  },
-
-  'POSITIONAL_PARAMETER_WITH_EQUALS': {
-    'id': 'JMSSDX',
-    'template': "Positional optional parameters can't use ':' to specify a "
-        "default value.",
-    'howToFix': "Try replacing ':' with '='.",
-    'examples': [
-      """
-main() {
-foo([a: 1]) => print(a);
-foo(2);
-}"""
-    ],
-  },
-
-  'TYPEDEF_FORMAL_WITH_DEFAULT': {
-    'id': 'NABHHS',
-    'template': "A parameter of a typedef can't specify a default value.",
-    'howToFix': "Try removing the default value.",
-    'examples': [
-      """
-typedef void F([int arg = 0]);
-
-main() {
-F f;
-}""",
-      """
-typedef void F({int arg: 0});
-
-main() {
-F f;
-}"""
-    ],
-  },
-
-  'FUNCTION_TYPE_FORMAL_WITH_DEFAULT': {
-    'id': 'APKYLU',
-    'template': "A function type parameter can't specify a default value.",
-    'howToFix': "Try removing the default value.",
-    'examples': [
-      """
-foo(f(int i, [a = 1])) {}
-
-main() {
-foo(1, 2);
-}""",
-      """
-foo(f(int i, {a: 1})) {}
-
-main() {
-foo(1, a: 2);
-}"""
-    ],
-  },
-
-  'REDIRECTING_FACTORY_WITH_DEFAULT': {
-    'id': 'AWSSEY',
-    'template':
-        "A parameter of a redirecting factory constructor can't specify a "
-        "default value.",
-    'howToFix': "Try removing the default value.",
-    'examples': [
-      """
-class A {
-A([a]);
-factory A.foo([a = 1]) = A;
-}
-
-main() {
-new A.foo(1);
-}""",
-      """
-class A {
-A({a});
-factory A.foo({a: 1}) = A;
-}
-
-main() {
-new A.foo(a: 1);
-}"""
-    ],
-  },
-
-  'FORMAL_DECLARED_CONST': {
-    'id': 'AVPRDK',
-    'template': "A formal parameter can't be declared const.",
-    'howToFix': "Try removing 'const'.",
-    'examples': [
-      """
-foo(const x) {}
-main() => foo(42);
-""",
-      """
-foo({const x}) {}
-main() => foo(42);
-""",
-      """
-foo([const x]) {}
-main() => foo(42);
-"""
-    ],
-  },
-
-  'FORMAL_DECLARED_STATIC': {
-    'id': 'PJKDMX',
-    'template': "A formal parameter can't be declared static.",
-    'howToFix': "Try removing 'static'.",
-    'examples': [
-      """
-foo(static x) {}
-main() => foo(42);
-""",
-      """
-foo({static x}) {}
-main() => foo(42);
-""",
-      """
-foo([static x]) {}
-main() => foo(42);
-"""
-    ],
-  },
-
-  'FINAL_FUNCTION_TYPE_PARAMETER': {
-    'id': 'JIOPIQ',
-    'template': "A function type parameter can't be declared final.",
-    'howToFix': "Try removing 'final'.",
-    'examples': [
-      """
-foo(final int x(int a)) {}
-main() => foo((y) => 42);
-""",
-      """
-foo({final int x(int a)}) {}
-main() => foo((y) => 42);
-""",
-      """
-foo([final int x(int a)]) {}
-main() => foo((y) => 42);
-"""
-    ],
-  },
-
-  'VAR_FUNCTION_TYPE_PARAMETER': {
-    'id': 'FOQOHK',
-    'template': "A function type parameter can't be declared with 'var'.",
-    'howToFix': "Try removing 'var'.",
-    'examples': [
-      """
-foo(var int x(int a)) {}
-main() => foo((y) => 42);
-""",
-      """
-foo({var int x(int a)}) {}
-main() => foo((y) => 42);
-""",
-      """
-foo([var int x(int a)]) {}
-main() => foo((y) => 42);
-"""
-    ],
-  },
-
-  'CANNOT_INSTANTIATE_TYPE_VARIABLE': {
-    'id': 'JAYHCH',
-    'template': "Cannot instantiate type variable '#{typeVariableName}'.",
-  },
-
-  'CYCLIC_TYPE_VARIABLE': {
-    'id': 'RQMPSO',
-    'template': "Type variable '#{typeVariableName}' is a supertype of itself.",
-  },
-
-  'CYCLIC_TYPEDEF': {
-    'id': 'VFERCQ',
-    'template': "A typedef can't refer to itself.",
-    'howToFix': "Try removing all references to '#{typedefName}' "
-        "in the definition of '#{typedefName}'.",
-    'examples': [
-      """
-typedef F F(); // The return type 'F' is a self-reference.
-main() { F f = null; }"""
-    ],
-  },
-
-  'CYCLIC_TYPEDEF_ONE': {
-    'id': 'ASWLWR',
-    'template': "A typedef can't refer to itself through another typedef.",
-    'howToFix': "Try removing all references to "
-        "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
-    'examples': [
-      """
-typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
-typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
-main() { F f = null; }""",
-      """
-typedef G F(); // The return type 'G' creates a self-reference.
-typedef H G(); // The return type 'H' creates a self-reference.
-typedef H(F f); // The argument type 'F' creates a self-reference.
-main() { F f = null; }"""
-    ],
-  },
-
-  'CLASS_NAME_EXPECTED': {'id': 'DPKNHY', 'template': "Class name expected.",},
-
-  'CANNOT_EXTEND': {
-    'id': 'GCIQXD',
-    'template': "'#{type}' cannot be extended.",
-  },
-
-  'CANNOT_IMPLEMENT': {
-    'id': 'IBOQKV',
-    'template': "'#{type}' cannot be implemented.",
-  },
-
-  // TODO(johnnwinther): Split messages into reasons for malformedness.
-  'CANNOT_EXTEND_MALFORMED': {
-    'id': 'YPFJBD',
-    'template': "Class '#{className}' can't extend the type '#{malformedType}' "
-        "because it is malformed.",
-    'howToFix': "Try correcting the malformed type annotation or removing the "
-        "'extends' clause.",
-    'examples': [
-      """
-class A extends Malformed {}
-main() => new A();"""
-    ],
-  },
-
-  'CANNOT_IMPLEMENT_MALFORMED': {
-    'id': 'XJUIAQ',
-    'template':
-        "Class '#{className}' can't implement the type '#{malformedType}' "
-        "because it is malformed.",
-    'howToFix': "Try correcting the malformed type annotation or removing the "
-        "type from the 'implements' clause.",
-    'examples': [
-      """
-class A implements Malformed {}
-main() => new A();"""
-    ],
-  },
-
-  'CANNOT_MIXIN_MALFORMED': {
-    'id': 'SSMNXN',
-    'template': "Class '#{className}' can't mixin the type '#{malformedType}' "
-        "because it is malformed.",
-    'howToFix': "Try correcting the malformed type annotation or removing the "
-        "type from the 'with' clause.",
-    'examples': [
-      """
-class A extends Object with Malformed {}
-main() => new A();"""
-    ],
-  },
-
-  'CANNOT_MIXIN': {
-    'id': 'KLSXDQ',
-    'template': "The type '#{type}' can't be mixed in.",
-    'howToFix': "Try removing '#{type}' from the 'with' clause.",
-    'examples': [
-      """
-class C extends Object with String {}
-
-main() => new C();
-""",
-      """
-typedef C = Object with String;
-
-main() => new C();
-"""
-    ],
-  },
-
-  'CANNOT_EXTEND_ENUM': {
-    'id': 'JEPRST',
-    'template':
-        "Class '#{className}' can't extend the type '#{enumType}' because "
-        "it is declared by an enum.",
-    'howToFix': "Try making '#{enumType}' a normal class or removing the "
-        "'extends' clause.",
-    'examples': [
-      """
-enum Enum { A }
-class B extends Enum {}
-main() => new B();"""
-    ],
-  },
-
-  'CANNOT_IMPLEMENT_ENUM': {
-    'id': 'JMJMSH',
-    'template': "Class '#{className}' can't implement the type '#{enumType}' "
-        "because it is declared by an enum.",
-    'howToFix': "Try making '#{enumType}' a normal class or removing the "
-        "type from the 'implements' clause.",
-    'examples': [
-      """
-enum Enum { A }
-class B implements Enum {}
-main() => new B();"""
-    ],
-  },
-
-  'CANNOT_MIXIN_ENUM': {
-    'id': 'YSYDIM',
-    'template':
-        "Class '#{className}' can't mixin the type '#{enumType}' because it "
-        "is declared by an enum.",
-    'howToFix': "Try making '#{enumType}' a normal class or removing the "
-        "type from the 'with' clause.",
-    'examples': [
-      """
-enum Enum { A }
-class B extends Object with Enum {}
-main() => new B();"""
-    ],
-  },
-
-  'CANNOT_INSTANTIATE_ENUM': {
-    'id': 'CQYIFU',
-    'template': "Enum type '#{enumName}' cannot be instantiated.",
-    'howToFix': "Try making '#{enumType}' a normal class or use an enum "
-        "constant.",
-    'examples': [
-      """
-enum Enum { A }
-main() => new Enum(0);""",
-      """
-enum Enum { A }
-main() => const Enum(0);"""
-    ],
-  },
-
-  'EMPTY_ENUM_DECLARATION': {
-    'id': 'JFPDOH',
-    'template': "Enum '#{enumName}' must contain at least one value.",
-    'howToFix': "Try adding an enum constant or making #{enumName} a "
-        "normal class.",
-    'examples': [
-      """
-enum Enum {}
-main() { Enum e; }"""
-    ],
-  },
-
-  'MISSING_ENUM_CASES': {
-    'id': 'HHEOIW',
-    'template': "Missing enum constants in switch statement: #{enumValues}.",
-    'howToFix': "Try adding the missing constants or a default case.",
-    'examples': [
-      """
-enum Enum { A, B }
-main() {
-switch (Enum.A) {
-case Enum.B: break;
-}
-}""",
-      """
-enum Enum { A, B, C }
-main() {
-switch (Enum.A) {
-case Enum.B: break;
-}
-}"""
-    ],
-  },
-
-  'DUPLICATE_EXTENDS_IMPLEMENTS': {
-    'id': 'BKRKEO',
-    'template': "'#{type}' can not be both extended and implemented.",
-  },
-
-  'DUPLICATE_IMPLEMENTS': {
-    'id': 'IWJFTU',
-    'template': "'#{type}' must not occur more than once "
-        "in the implements clause.",
-  },
-
-  'MULTI_INHERITANCE': {
-    'id': 'NWXGOI',
-    'template':
-        "Dart2js does not currently support inheritance of the same class "
-        "with different type arguments: Both #{firstType} and #{secondType} "
-        "are supertypes of #{thisType}.",
-  },
-
-  'ILLEGAL_SUPER_SEND': {
-    'id': 'LDRGIU',
-    'template': "'#{name}' cannot be called on super.",
-  },
-
-  'NO_SUCH_SUPER_MEMBER': {
-    'id': 'HIJJVG',
-    'template':
-        "Cannot resolve '#{memberName}' in a superclass of '#{className}'.",
-  },
-
-  'ADDITIONAL_TYPE_ARGUMENT': {
-    'id': 'HWYHWH',
-    'template': "Additional type argument.",
-  },
-
-  'MISSING_TYPE_ARGUMENT': {
-    'id': 'KYTQWA',
-    'template': "Missing type argument.",
-  },
-
-  // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
-  // MISSING_TYPE_ARGUMENT instead.
-  'TYPE_ARGUMENT_COUNT_MISMATCH': {
-    'id': 'ECXGRM',
-    'template': "Incorrect number of type arguments on '#{type}'.",
-  },
-
-  'GETTER_MISMATCH': {
-    'id': 'MNODFW',
-    'template': "Setter disagrees on: '#{modifiers}'.",
-  },
-
-  'SETTER_MISMATCH': {
-    'id': 'FMNHPL',
-    'template': "Getter disagrees on: '#{modifiers}'.",
-  },
-
-  'ILLEGAL_SETTER_FORMALS': {
-    'id': 'COTPVN',
-    'template': "A setter must have exactly one argument.",
-  },
-
-  'NO_STATIC_OVERRIDE': {
-    'id': 'EHINXB',
-    'template':
-        "Static member cannot override instance member '#{memberName}' of "
-        "'#{className}'.",
-  },
-
-  'NO_STATIC_OVERRIDE_CONT': {
-    'id': 'TEVJMA',
-    'template': "This is the instance member that cannot be overridden "
-        "by a static member.",
-  },
-
-  'INSTANCE_STATIC_SAME_NAME': {
-    'id': 'LTBFBO',
-    'template': "Instance member '#{memberName}' and static member of "
-        "superclass '#{className}' have the same name.",
-  },
-
-  'INSTANCE_STATIC_SAME_NAME_CONT': {
-    'id': 'CHSUCQ',
-    'template': "This is the static member with the same name.",
-  },
-
-  'INVALID_OVERRIDE_METHOD': {
-    'id': 'NINKPI',
-    'template': "The type '#{declaredType}' of method '#{name}' declared in "
-        "'#{class}' is not a subtype of the overridden method type "
-        "'#{inheritedType}' inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDDEN_METHOD': {
-    'id': 'BQHUPY',
-    'template': "This is the overridden method '#{name}' declared in class "
-        "'#{class}'.",
-  },
-
-  'INVALID_OVERRIDE_GETTER': {
-    'id': 'KLMPWO',
-    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden getter inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDDEN_GETTER': {
-    'id': 'ASSKCT',
-    'template': "This is the overridden getter '#{name}' declared in class "
-        "'#{class}'.",
-  },
-
-  'INVALID_OVERRIDE_GETTER_WITH_FIELD': {
-    'id': 'TCCGXU',
-    'template': "The type '#{declaredType}' of field '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden getter inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDE_FIELD_WITH_GETTER': {
-    'id': 'UMMEXO',
-    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden field inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDE_SETTER': {
-    'id': 'BWRGEC',
-    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden setter inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDDEN_SETTER': {
-    'id': 'XQUOLL',
-    'template': "This is the overridden setter '#{name}' declared in class "
-        "'#{class}'.",
-  },
-
-  'INVALID_OVERRIDE_SETTER_WITH_FIELD': {
-    'id': 'GKGOFA',
-    'template': "The type '#{declaredType}' of field '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden setter inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDE_FIELD_WITH_SETTER': {
-    'id': 'OOXKHQ',
-    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden field inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDE_FIELD': {
-    'id': 'LDPKOL',
-    'template': "The type '#{declaredType}' of field '#{name}' declared in "
-        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-        "overridden field inherited from '#{inheritedClass}'.",
-  },
-
-  'INVALID_OVERRIDDEN_FIELD': {
-    'id': 'UNQFWX',
-    'template': "This is the overridden field '#{name}' declared in class "
-        "'#{class}'.",
-  },
-
-  'CANNOT_OVERRIDE_FIELD_WITH_METHOD': {
-    'id': 'SYKCSK',
-    'template': "Method '#{name}' in '#{class}' can't override field from "
-        "'#{inheritedClass}'.",
-  },
-
-  'CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT': {
-    'id': 'HYHQSO',
-    'template': "This is the field that cannot be overridden by a method.",
-  },
-
-  'CANNOT_OVERRIDE_METHOD_WITH_FIELD': {
-    'id': 'UROMAS',
-    'template': "Field '#{name}' in '#{class}' can't override method from "
-        "'#{inheritedClass}'.",
-  },
-
-  'CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT': {
-    'id': 'NSORYS',
-    'template': "This is the method that cannot be overridden by a field.",
-  },
-
-  'CANNOT_OVERRIDE_GETTER_WITH_METHOD': {
-    'id': 'MMFIOH',
-    'template': "Method '#{name}' in '#{class}' can't override getter from "
-        "'#{inheritedClass}'.",
-  },
-
-  'CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT': {
-    'id': 'YGWPDH',
-    'template': "This is the getter that cannot be overridden by a method.",
-  },
-
-  'CANNOT_OVERRIDE_METHOD_WITH_GETTER': {
-    'id': 'BNKNXO',
-    'template': "Getter '#{name}' in '#{class}' can't override method from "
-        "'#{inheritedClass}'.",
-  },
-
-  'CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT': {
-    'id': 'KFBCYX',
-    'template': "This is the method that cannot be overridden by a getter.",
-  },
-
-  'MISSING_FORMALS': {
-    'id': 'BOERAF',
-    'template': "Formal parameters are missing.",
-  },
-
-  'EXTRA_FORMALS': {
-    'id': 'UTWRIU',
-    'template': "Formal parameters are not allowed here.",
-  },
-
-  'UNARY_OPERATOR_BAD_ARITY': {
-    'id': 'TNHLAL',
-    'template': "Operator '#{operatorName}' must have no parameters.",
-  },
-
-  'MINUS_OPERATOR_BAD_ARITY': {
-    'id': 'SXDRRU',
-    'template': "Operator '-' must have 0 or 1 parameters.",
-  },
-
-  'BINARY_OPERATOR_BAD_ARITY': {
-    'id': 'QKWAUM',
-    'template': "Operator '#{operatorName}' must have exactly 1 parameter.",
-  },
-
-  'TERNARY_OPERATOR_BAD_ARITY': {
-    'id': 'LSMQGF',
-    'template': "Operator '#{operatorName}' must have exactly 2 parameters.",
-  },
-
-  'OPERATOR_OPTIONAL_PARAMETERS': {
-    'id': 'HSGRBV',
-    'template': "Operator '#{operatorName}' cannot have optional parameters.",
-  },
-
-  'OPERATOR_NAMED_PARAMETERS': {
-    'id': 'EACWGS',
-    'template': "Operator '#{operatorName}' cannot have named parameters.",
-  },
-
-  'CONSTRUCTOR_WITH_RETURN_TYPE': {
-    'id': 'OPMBHF',
-    'template': "Cannot have return type for constructor.",
-  },
-
-  'CANNOT_RETURN_FROM_CONSTRUCTOR': {
-    'id': 'NFUGNH',
-    'template': "Constructors can't return values.",
-    'howToFix': "Remove the return statement or use a factory constructor.",
-    'examples': [
-      """
-class C {
-C() {
-  return 1;
-}
-}
-
-main() => new C();"""
-    ],
-  },
-
-  'ILLEGAL_FINAL_METHOD_MODIFIER': {
-    'id': 'YUKCVU',
-    'template': "Cannot have final modifier on method.",
-  },
-
-  'ILLEGAL_CONST_FIELD_MODIFIER': {
-    'id': 'JGFAGV',
-    'template': "Cannot have const modifier on non-static field.",
-    'howToFix': "Try adding a static modifier, or removing the const modifier.",
-    'examples': [
-      """
-class C {
-const int a = 1;
-}
-
-main() => new C();"""
-    ],
-  },
-
-  'ILLEGAL_CONSTRUCTOR_MODIFIERS': {
-    'id': 'WODRHN',
-    'template': "Illegal constructor modifiers: '#{modifiers}'.",
-  },
-
-  'ILLEGAL_MIXIN_APPLICATION_MODIFIERS': {
-    'id': 'OFLFHN',
-    'template': "Illegal mixin application modifiers: '#{modifiers}'.",
-  },
-
-  'ILLEGAL_MIXIN_SUPERCLASS': {
-    'id': 'TPVVYN',
-    'template': "Class used as mixin must have Object as superclass.",
-  },
-
-  'ILLEGAL_MIXIN_OBJECT': {
-    'id': 'CMVTLF',
-    'template': "Cannot use Object as mixin.",
-  },
-
-  'ILLEGAL_MIXIN_CONSTRUCTOR': {
-    'id': 'HXBUIB',
-    'template': "Class used as mixin cannot have non-factory constructor.",
-  },
-
-  'ILLEGAL_MIXIN_CYCLE': {
-    'id': 'ANXAMU',
-    'template': "Class used as mixin introduces mixin cycle: "
-        "'#{mixinName1}' <-> '#{mixinName2}'.",
-  },
-
-  'ILLEGAL_MIXIN_WITH_SUPER': {
-    'id': 'KIEUGK',
-    'template': "Cannot use class '#{className}' as a mixin because it uses "
-        "'super'.",
-  },
-
-  'ILLEGAL_MIXIN_SUPER_USE': {
-    'id': 'QKUPLH',
-    'template': "Use of 'super' in class used as mixin.",
-  },
-
-  'PARAMETER_NAME_EXPECTED': {
-    'id': 'JOUOBT',
-    'template': "parameter name expected.",
-  },
-
-  'CANNOT_RESOLVE_GETTER': {
-    'id': 'TDHKSW',
-    'template': "Cannot resolve getter.",
-  },
-
-  'CANNOT_RESOLVE_SETTER': {
-    'id': 'QQFANP',
-    'template': "Cannot resolve setter.",
-  },
-
-  'ASSIGNING_FINAL_FIELD_IN_SUPER': {
-    'id': 'LXUPCC',
-    'template': "Cannot assign a value to final field '#{name}' "
-        "in superclass '#{superclassName}'.",
-  },
-
-  'ASSIGNING_METHOD': {
-    'id': 'JUVMYC',
-    'template': "Cannot assign a value to a method.",
-  },
-
-  'ASSIGNING_METHOD_IN_SUPER': {
-    'id': 'AGMAXN',
-    'template': "Cannot assign a value to method '#{name}' "
-        "in superclass '#{superclassName}'.",
-  },
-
-  'ASSIGNING_TYPE': {
-    'id': 'VXTPWE',
-    'template': "Cannot assign a value to a type.",
-  },
-
-  'IF_NULL_ASSIGNING_TYPE': {
-    'id': 'XBRHGK',
-    'template':
-        "Cannot assign a value to a type. Note that types are never null, "
-        "so this ??= assignment has no effect.",
-    'howToFix': "Try removing the '??=' assignment.",
-    'examples': ["class A {} main() { print(A ??= 3);}",],
-  },
-
-  'VOID_NOT_ALLOWED': {
-    'id': 'DMMDXT',
-    'template':
-        "Type 'void' can't be used here because it isn't a return type.",
-    'howToFix':
-        "Try removing 'void' keyword or replace it with 'var', 'final', "
-        "or a type.",
-    'examples': ["void x; main() {}", "foo(void x) {} main() { foo(null); }",],
-  },
-
-  'NULL_NOT_ALLOWED': {
-    'id': 'STYNSK',
-    'template': "`null` can't be used here.",
-  },
-
-  'BEFORE_TOP_LEVEL': {
-    'id': 'GRCXQF',
-    'template': "Part header must come before top-level definitions.",
-  },
-
-  'IMPORT_PART_OF': {
-    'id': 'VANCWE',
-    'template': "The imported library must not have a 'part-of' directive.",
-    'howToFix': "Try removing the 'part-of' directive or replacing the "
-        "import of the library with a 'part' directive.",
-    'examples': [
-      {
-        'main.dart': """
-library library;
-
-import 'part.dart';
-
-main() {}
-""",
-        'part.dart': """
-part of library;
-"""
-      }
-    ],
-  },
-
-  'IMPORT_PART_OF_HERE': {
-    'id': 'TRSZOJ',
-    'template': 'The library is imported here.',
-  },
-
-  'MAIN_HAS_PART_OF': {
-    'id': 'MFMRRL',
-    'template': "The main application file must not have a 'part-of' "
-                "directive.",
-    'howToFix': "Try removing the 'part-of' directive or starting compilation "
-                "from another file.",
-    'examples': [
-      {
-        'main.dart': """
-part of library;
-
-main() {}
-"""
-      }
-    ],
-  },
-
-  'LIBRARY_NAME_MISMATCH': {
-    'id': 'AXGYPQ',
-    'template': "Expected part of library name '#{libraryName}'.",
-    'howToFix': "Try changing the directive to 'part of #{libraryName};'.",
-    'examples': [
-      {
-        'main.dart': """
-library lib.foo;
-
-part 'part.dart';
-
-main() {}
-""",
-        'part.dart': """
-part of lib.bar;
-"""
-      }
-    ],
-  },
-
-  'MISSING_LIBRARY_NAME': {
-    'id': 'NYQNCA',
-    'template': "Library has no name. Part directive expected library name "
-        "to be '#{libraryName}'.",
-    'howToFix': "Try adding 'library #{libraryName};' to the library.",
-    'examples': [
-      {
-        'main.dart': """
-part 'part.dart';
-
-main() {}
-""",
-        'part.dart': """
-part of lib.foo;
-"""
-      }
-    ],
-  },
-
-  'THIS_IS_THE_PART_OF_TAG': {
-    'id': 'RPSJRS',
-    'template': "This is the part of directive.",
-  },
-
-  'MISSING_PART_OF_TAG': {
-    'id': 'QNYCMV',
-    'template': "This file has no part-of tag, but it is being used as a part.",
-  },
-
-  'DUPLICATED_PART_OF': {
-    'id': 'UJDYHF',
-    'template': "Duplicated part-of directive.",
-  },
-
-  'DUPLICATED_LIBRARY_NAME': {
-    'id': 'OSEHXI',
-    'template': "Duplicated library name '#{libraryName}'.",
-  },
-
-  'DUPLICATED_RESOURCE': {
-    'id': 'UFWKBY',
-    'template': "The resource '#{resourceUri}' is loaded through both "
-        "'#{canonicalUri1}' and '#{canonicalUri2}'.",
-  },
-
-  'DUPLICATED_LIBRARY_RESOURCE': {
-    'id': 'KYGYTT',
-    'template':
-        "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
-        "both '#{canonicalUri1}' and '#{canonicalUri2}'.",
-  },
-
-  // This is used as an exception.
-  'INVALID_SOURCE_FILE_LOCATION': {
-    'id': 'WIGJFG',
-    'template': """
-Invalid offset (#{offset}) in source map.
-File: #{fileName}
-Length: #{length}""",
-  },
-
-  'TOP_LEVEL_VARIABLE_DECLARED_STATIC': {
-    'id': 'IVNDML',
-    'template': "Top-level variable cannot be declared static.",
-  },
-
-  'REFERENCE_IN_INITIALIZATION': {
-    'id': 'OVWTEU',
-    'template': "Variable '#{variableName}' is referenced during its "
-        "initialization.",
-    'howToFix': "If you are trying to reference a shadowed variable, rename "
-        "one of the variables.",
-    'examples': [
-      """
-foo(t) {
-var t = t;
-return t;
-}
-
-main() => foo(1);
-"""
-    ],
-  },
-
-  'CONST_WITHOUT_INITIALIZER': {
-    'id': 'UDWCNH',
-    'template': "A constant variable must be initialized.",
-    'howToFix': "Try adding an initializer or "
-        "removing the 'const' modifier.",
-    'examples': [
-      """
-void main() {
-const c; // This constant variable must be initialized.
-}"""
-    ],
-  },
-
-  'FINAL_WITHOUT_INITIALIZER': {
-    'id': 'YMESFI',
-    'template': "A final variable must be initialized.",
-    'howToFix': "Try adding an initializer or "
-        "removing the 'final' modifier.",
-    'examples': ["class C { static final field; } main() => C.field;"],
-  },
-
-  'CONST_LOOP_VARIABLE': {
-    'id': 'WUSKMG',
-    'template': "A loop variable cannot be constant.",
-    'howToFix': "Try remove the 'const' modifier or "
-        "replacing it with a 'final' modifier.",
-    'examples': [
-      """
-void main() {
-  for (const c in []) {}
-}"""
-    ],
-  },
-
-  'MEMBER_USES_CLASS_NAME': {
-    'id': 'TVFYRK',
-    'template': "Member variable can't have the same name as the class it is "
-        "declared in.",
-    'howToFix': "Try renaming the variable.",
-    'examples': [
-      """
-class A { var A; }
-main() {
-var a = new A();
-a.A = 1;
-}
-""",
-      """
-class A { static var A; }
-main() => A.A = 1;
-"""
-    ],
-  },
-
-  'WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT': {
-    'id': 'IXYNUF',
-    'template': "Wrong number of arguments to assert. Should be 1, but given "
-        "#{argumentCount}.",
-  },
-
-  'ASSERT_IS_GIVEN_NAMED_ARGUMENTS': {
-    'id': 'EJFDTO',
-    'template':
-        "'assert' takes no named arguments, but given #{argumentCount}.",
-  },
-
-  'FACTORY_REDIRECTION_IN_NON_FACTORY': {
-    'id': 'DTBWEX',
-    'template': "Factory redirection only allowed in factories.",
-  },
-
-  'MISSING_FACTORY_KEYWORD': {
-    'id': 'HOQYYA',
-    'template': "Did you forget a factory keyword here?",
-  },
-
-  'NO_SUCH_METHOD_IN_NATIVE': {
-    'id': 'MSDDBX',
-    'template':
-        "'NoSuchMethod' is not supported for classes that extend native "
-        "classes.",
-  },
-
-  'DEFERRED_LIBRARY_DART_2_DART': {
-    'id': 'RIRQAH',
-    'template': "Deferred loading is not supported by the dart backend yet. "
-        "The output will not be split.",
-  },
-
-  'DEFERRED_LIBRARY_WITHOUT_PREFIX': {
-    'id': 'CARRII',
-    'template': "This import is deferred but there is no prefix keyword.",
-    'howToFix': "Try adding a prefix to the import."
-  },
-
-  'DEFERRED_OLD_SYNTAX': {
-    'id': 'QCBRAE',
-    'template': "The DeferredLibrary annotation is obsolete.",
-    'howToFix':
-        "Use the \"import 'lib.dart' deferred as prefix\" syntax instead.",
-  },
-
-  'DEFERRED_LIBRARY_DUPLICATE_PREFIX': {
-    'id': 'BBMJTD',
-    'template': "The prefix of this deferred import is not unique.",
-    'howToFix': "Try changing the import prefix."
-  },
-
-  'DEFERRED_TYPE_ANNOTATION': {
-    'id': 'JOUEFD',
-    'template': "The type #{node} is deferred. "
-        "Deferred types are not valid as type annotations.",
-    'howToFix': "Try using a non-deferred abstract class as an interface.",
-  },
-
-  'ILLEGAL_STATIC': {
-    'id': 'HFBHVE',
-    'template': "Modifier static is only allowed on functions declared in "
-        "a class.",
-  },
-
-  'STATIC_FUNCTION_BLOAT': {
-    'id': 'SJHTKF',
-    'template': "Using '#{class}.#{name}' may lead to unnecessarily large "
-        "generated code.",
-    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
-        "https://goo.gl/Akrrog.",
-  },
-
-  'NON_CONST_BLOAT': {
-    'id': 'RDRSHO',
-    'template': "Using 'new #{name}' may lead to unnecessarily large generated "
-        "code.",
-    'howToFix': "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
-        "described at https://goo.gl/Akrrog.",
-  },
-
-  'STRING_EXPECTED': {
-    'id': 'OEJOOI',
-    'template': "Expected a 'String', but got an instance of '#{type}'.",
-  },
-
-  'PRIVATE_IDENTIFIER': {
-    'id': 'XAHVWI',
-    'template': "'#{value}' is not a valid Symbol name because it starts with "
-        "'_'.",
-  },
-
-  'PRIVATE_NAMED_PARAMETER': {
-    'id': 'VFGCLK',
-    'template': "Named optional parameter can't have a library private name.",
-    'howToFix': "Try removing the '_' or making the parameter positional or "
-        "required.",
-    'examples': ["""foo({int _p}) {} main() => foo();"""],
-  },
-
-  'UNSUPPORTED_LITERAL_SYMBOL': {
-    'id': 'OYCDII',
-    'template':
-        "Symbol literal '##{value}' is currently unsupported by dart2js.",
-  },
-
-  'INVALID_SYMBOL': {
-    'id': 'RUXMBL',
-    'template': '''
-'#{value}' is not a valid Symbol name because is not:
-* an empty String,
-* a user defined operator,
-* a qualified non-private identifier optionally followed by '=', or
-* a qualified non-private identifier followed by '.' and a user-defined '''
-        "operator.",
-  },
-
-  'AMBIGUOUS_REEXPORT': {
-    'id': 'YNTOND',
-    'template': "'#{name}' is (re)exported by multiple libraries.",
-  },
-
-  'AMBIGUOUS_LOCATION': {
-    'id': 'SKLTYA',
-    'template': "'#{name}' is defined here.",
-  },
-
-  'IMPORTED_HERE': {'id': 'IMUXAE', 'template': "'#{name}' is imported here.",},
-
-  'OVERRIDE_EQUALS_NOT_HASH_CODE': {
-    'id': 'MUHYXI',
-    'template': "The class '#{class}' overrides 'operator==', "
-        "but not 'get hashCode'.",
-  },
-
-  'INTERNAL_LIBRARY_FROM': {
-    'id': 'RXOCLX',
-    'template': "Internal library '#{resolvedUri}' is not accessible from "
-        "'#{importingUri}'.",
-  },
-
-  'INTERNAL_LIBRARY': {
-    'id': 'SYLJAV',
-    'template': "Internal library '#{resolvedUri}' is not accessible.",
-  },
-
-  'JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS': {
-    'id': 'LSHKJK',
-    'template':
-        "Js-interop class '#{cls}' cannot extend from the non js-interop "
-        "class '#{superclass}'.",
-    'howToFix': "Annotate the superclass with @JS.",
-    'examples': [
-      """
-            import 'package:js/js.dart';
-
-            class Foo { }
-
-            @JS()
-            class Bar extends Foo { }
-
-            main() {
-              new Bar();
-            }
-            """
-    ],
-  },
-
-  'JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER': {
-    'id': 'QLLLEE',
-    'template':
-        "Member '#{member}' in js-interop class '#{cls}' is not external.",
-    'howToFix': "Mark all interop methods external",
-    'examples': [
-      """
-            import 'package:js/js.dart';
-
-            @JS()
-            class Foo {
-              bar() {}
-            }
-
-            main() {
-              new Foo().bar();
-            }
-            """
-    ],
-  },
-
-  'JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS': {
-    'id': 'TDQHRY',
-    'template': "Js-interop method '#{method}' has named arguments but is not "
-        "a factory constructor of an @anonymous @JS class.",
-    'howToFix': "Remove all named arguments from js-interop method or "
-        "in the case of a factory constructor annotate the class "
-        "as @anonymous.",
-    'examples': [
-      """
-            import 'package:js/js.dart';
-
-            @JS()
-            class Foo {
-              external bar(foo, {baz});
-            }
-
-            main() {
-              new Foo().bar(4, baz: 5);
-            }
-            """
-    ],
-  },
-
-  'JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS': {
-    'id': 'EHEKUY',
-    'template':
-        "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
-        "object literal constructor is positional instead of named."
-        ".",
-    'howToFix': "Make all arguments in external factory object literal "
-        "constructors named.",
-    'examples': [
-      """
-            import 'package:js/js.dart';
-
-            @anonymous
-            @JS()
-            class Foo {
-              external factory Foo(foo, {baz});
-            }
-
-            main() {
-              new Foo(5, baz: 5);
-            }
-            """
-    ],
-  },
-
-  'LIBRARY_NOT_FOUND': {
-    'id': 'BARPSL',
-    'template': "Library not found '#{resolvedUri}'.",
-  },
-
-  'LIBRARY_NOT_SUPPORTED': {
-    'id': 'GDXUNS',
-    'template': "Library not supported '#{resolvedUri}'.",
-    'howToFix': "Try removing the dependency or enabling support using "
-        "the '--categories' option.",
-    'examples': [
-//            """
-//            import 'dart:io';
-//            main() {}
-//            """
-    ],
-    // TODO(johnniwinther): Enable example when message_kind_test.dart
-    // supports library loader callbacks.
-  },
-
-  'UNSUPPORTED_EQ_EQ_EQ': {
-    'id': 'GPOVNO',
-    'template': "'===' is not an operator. "
-        "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?",
-  },
-
-  'UNSUPPORTED_BANG_EQ_EQ': {
-    'id': 'HDYKMV',
-    'template': "'!==' is not an operator. "
-        "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?",
-  },
-
-  'UNSUPPORTED_PREFIX_PLUS': {
-    'id': 'LSQTHP',
-    'template': "'+' is not a prefix operator. ",
-    'howToFix': "Try removing '+'.",
-    'examples': ["main() => +2;  // No longer a valid way to write '2'"],
-  },
-
-  'UNSUPPORTED_THROW_WITHOUT_EXP': {
-    'id': 'QOAKGE',
-    'template': "No expression after 'throw'. "
-        "Did you mean 'rethrow'?",
-  },
-
-  'DEPRECATED_TYPEDEF_MIXIN_SYNTAX': {
-    'id': 'BBGGFE',
-    'template': "'typedef' not allowed here. ",
-    'howToFix': "Try replacing 'typedef' with 'class'.",
-    'examples': [
-      """
-class B { }
-class M1 {  }
-typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
-main() { new C(); }
-"""
-    ],
-  },
-
-  'MIRRORS_EXPECTED_STRING': {
-    'id': 'XSKTIB',
-    'template':
-        "Can't use '#{name}' here because it's an instance of '#{type}' "
-        "and a 'String' value is expected.",
-    'howToFix': "Did you forget to add quotes?",
-    'examples': [
-      """
-// 'Foo' is a type literal, not a string.
-@MirrorsUsed(symbols: const [Foo])
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_EXPECTED_STRING_OR_TYPE': {
-    'id': 'JQDJPL',
-    'template':
-        "Can't use '#{name}' here because it's an instance of '#{type}' "
-        "and a 'String' or 'Type' value is expected.",
-    'howToFix': "Did you forget to add quotes?",
-    'examples': [
-      """
-// 'main' is a method, not a class.
-@MirrorsUsed(targets: const [main])
-import 'dart:mirrors';
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_EXPECTED_STRING_OR_LIST': {
-    'id': 'UVYCOE',
-    'template':
-        "Can't use '#{name}' here because it's an instance of '#{type}' "
-        "and a 'String' or 'List' value is expected.",
-    'howToFix': "Did you forget to add quotes?",
-    'examples': [
-      """
-// 'Foo' is not a string.
-@MirrorsUsed(symbols: Foo)
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_EXPECTED_STRING_TYPE_OR_LIST': {
-    'id': 'WSYDFL',
-    'template':
-        "Can't use '#{name}' here because it's an instance of '#{type}' "
-        "but a 'String', 'Type', or 'List' value is expected.",
-    'howToFix': "Did you forget to add quotes?",
-    'examples': [
-      """
-// '1' is not a string.
-@MirrorsUsed(targets: 1)
-import 'dart:mirrors';
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY': {
-    'id': 'VDBBNE',
-    'template': "Can't find '#{name}' in the current library.",
-    // TODO(ahe): The closest identifiers in edit distance would be nice.
-    'howToFix': "Did you forget to add an import?",
-    'examples': [
-      """
-// 'window' is not in scope because dart:html isn't imported.
-@MirrorsUsed(targets: 'window')
-import 'dart:mirrors';
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_CANNOT_RESOLVE_IN_LIBRARY': {
-    'id': 'RUEKXE',
-    'template': "Can't find '#{name}' in the library '#{library}'.",
-    // TODO(ahe): The closest identifiers in edit distance would be nice.
-    'howToFix': "Is '#{name}' spelled right?",
-    'examples': [
-      """
-// 'List' is misspelled.
-@MirrorsUsed(targets: 'dart.core.Lsit')
-import 'dart:mirrors';
-
-main() {}
-"""
-    ],
-  },
-
-  'MIRRORS_CANNOT_FIND_IN_ELEMENT': {
-    'id': 'ACPDCS',
-    'template': "Can't find '#{name}' in '#{element}'.",
-    // TODO(ahe): The closest identifiers in edit distance would be nice.
-    'howToFix': "Is '#{name}' spelled right?",
-    'examples': [
-      """
-// 'addAll' is misspelled.
-@MirrorsUsed(targets: 'dart.core.List.addAl')
-import 'dart:mirrors';
-
-main() {}
-"""
-    ],
-  },
-
-  'INVALID_URI': {
-    'id': 'QQEQMK',
-    'template': "'#{uri}' is not a valid URI.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-// can't have a '[' in a URI
-import '../../Udyn[mic ils/expect.dart';
-
-main() {}
-"""
-    ],
-  },
-
-  'INVALID_PACKAGE_CONFIG': {
-    'id': 'XKFAJO',
-    'template': """Package config file '#{uri}' is invalid.
-#{exception}""",
-    'howToFix': DONT_KNOW_HOW_TO_FIX
-  },
-
-  'INVALID_PACKAGE_URI': {
-    'id': 'MFVNNJ',
-    'template': "'#{uri}' is not a valid package URI (#{exception}).",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-// can't have a 'top level' package URI
-import 'package:foo.dart';
-
-main() {}
-""",
-      """
-// can't have 2 slashes
-import 'package://foo/foo.dart';
-
-main() {}
-""",
-      """
-// package name must be valid
-import 'package:not\valid/foo.dart';
-
-main() {}
-"""
-    ],
-  },
-
-  'READ_SCRIPT_ERROR': {
-    'id': 'JDDYLH',
-    'template': "Can't read '#{uri}' (#{exception}).",
-    // Don't know how to fix since the underlying error is unknown.
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-// 'foo.dart' does not exist.
-import 'foo.dart';
-
-main() {}
-"""
-    ],
-  },
-
-  'READ_SELF_ERROR': {
-    'id': 'CRJUAV',
-    'template': "#{exception}",
-    // Don't know how to fix since the underlying error is unknown.
-    'howToFix': DONT_KNOW_HOW_TO_FIX
-  },
-
-  'EXTRANEOUS_MODIFIER': {
-    'id': 'DPLVJG',
-    'template': "Can't have modifier '#{modifier}' here.",
-    'howToFix': "Try removing '#{modifier}'.",
-    'examples': [
-      "var String foo; main(){}",
-      // "var get foo; main(){}",
-      "var set foo; main(){}",
-      "var final foo; main(){}",
-      "var var foo; main(){}",
-      "var const foo; main(){}",
-      "var abstract foo; main(){}",
-      "var static foo; main(){}",
-      "var external foo; main(){}",
-      "get var foo; main(){}",
-      "set var foo; main(){}",
-      "final var foo; main(){}",
-      "var var foo; main(){}",
-      "const var foo; main(){}",
-      "abstract var foo; main(){}",
-      "static var foo; main(){}",
-      "external var foo; main(){}"
-    ],
-  },
-
-  'EXTRANEOUS_MODIFIER_REPLACE': {
-    'id': 'SSXDLN',
-    'template': "Can't have modifier '#{modifier}' here.",
-    'howToFix': "Try replacing modifier '#{modifier}' with 'var', 'final', "
-        "or a type.",
-    'examples': [
-      // "get foo; main(){}",
-      "set foo; main(){}",
-      "abstract foo; main(){}",
-      "static foo; main(){}",
-      "external foo; main(){}"
-    ],
-  },
-
-  'ABSTRACT_CLASS_INSTANTIATION': {
-    'id': 'KOBCRO',
-    'template': "Can't instantiate abstract class.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': ["abstract class A {} main() { new A(); }"],
-  },
-
-  'BODY_EXPECTED': {
-    'id': 'YXCAHO',
-    'template': "Expected a function body or '=>'.",
-    // TODO(ahe): In some scenarios, we can suggest removing the 'static'
-    // keyword.
-    'howToFix': "Try adding {}.",
-    'examples': ["main();"],
-  },
-
-  'MIRROR_BLOAT': {
-    'id': 'BSEAIT',
-    'template':
-        "#{count} methods retained for use by dart:mirrors out of #{total}"
-        " total methods (#{percentage}%).",
-  },
-
-  'MIRROR_IMPORT': {'id': 'BDAETE', 'template': "Import of 'dart:mirrors'.",},
-
-  'MIRROR_IMPORT_NO_USAGE': {
-    'id': 'OJOHTR',
-    'template':
-        "This import is not annotated with @MirrorsUsed, which may lead to "
-        "unnecessarily large generated code.",
-    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
-        "https://goo.gl/Akrrog.",
-  },
-
-  'JS_PLACEHOLDER_CAPTURE': {
-    'id': 'EJXEGQ',
-    'template': "JS code must not use '#' placeholders inside functions.",
-    'howToFix': "Use an immediately called JavaScript function to capture the"
-        " the placeholder values as JavaScript function parameters.",
-  },
-
-  'WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT': {
-    'id': 'JHRISO',
-    'template':
-        "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.",
-  },
-
-  'EXPECTED_IDENTIFIER_NOT_RESERVED_WORD': {
-    'id': 'FEJXJF',
-    'template': "'#{keyword}' is a reserved word and can't be used here.",
-    'howToFix': "Try using a different name.",
-    'examples': ["do() {} main() {}"],
-  },
-
-  'NAMED_FUNCTION_EXPRESSION': {
-    'id': 'CTHFPI',
-    'template': "Function expression '#{name}' cannot be named.",
-    'howToFix': "Try removing the name.",
-    'examples': ["main() { var f = func() {}; }"],
-  },
-
-  'UNUSED_METHOD': {
-    'id': 'PKLRQL',
-    'template': "The method '#{name}' is never called.",
-    'howToFix': "Consider deleting it.",
-    'examples': ["deadCode() {} main() {}"],
-  },
-
-  'UNUSED_CLASS': {
-    'id': 'TBIECC',
-    'template': "The class '#{name}' is never used.",
-    'howToFix': "Consider deleting it.",
-    'examples': ["class DeadCode {} main() {}"],
-  },
-
-  'UNUSED_TYPEDEF': {
-    'id': 'JBIPCN',
-    'template': "The typedef '#{name}' is never used.",
-    'howToFix': "Consider deleting it.",
-    'examples': ["typedef DeadCode(); main() {}"],
-  },
-
-  'ABSTRACT_METHOD': {
-    'id': 'HOKOBG',
-    'template': "The method '#{name}' has no implementation in "
-        "class '#{class}'.",
-    'howToFix': "Try adding a body to '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-class Class {
-method();
-}
-main() => new Class().method();
-"""
-    ],
-  },
-
-  'ABSTRACT_GETTER': {
-    'id': 'VKTRNK',
-    'template': "The getter '#{name}' has no implementation in "
-        "class '#{class}'.",
-    'howToFix': "Try adding a body to '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-class Class {
-get getter;
-}
-main() => new Class();
-"""
-    ],
-  },
-
-  'ABSTRACT_SETTER': {
-    'id': 'XGDGKK',
-    'template': "The setter '#{name}' has no implementation in "
-        "class '#{class}'.",
-    'howToFix': "Try adding a body to '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-class Class {
-set setter(_);
-}
-main() => new Class();
-"""
-    ],
-  },
-
-  'INHERIT_GETTER_AND_METHOD': {
-    'id': 'UMEUEG',
-    'template': "The class '#{class}' can't inherit both getters and methods "
-        "by the named '#{name}'.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-class A {
-get member => null;
-}
-class B {
-member() {}
-}
-class Class implements A, B {
-}
-main() => new Class();
-"""
-    ],
-  },
-
-  'INHERITED_METHOD': {
-    'id': 'GMSVBM',
-    'template': "The inherited method '#{name}' is declared here in class "
-        "'#{class}'.",
-  },
-
-  'INHERITED_EXPLICIT_GETTER': {
-    'id': 'KKAVRS',
-    'template': "The inherited getter '#{name}' is declared here in class "
-        "'#{class}'.",
-  },
-
-  'INHERITED_IMPLICIT_GETTER': {
-    'id': 'JBAMEJ',
-    'template': "The inherited getter '#{name}' is implicitly declared by this "
-        "field in class '#{class}'.",
-  },
-
-  'UNIMPLEMENTED_METHOD_ONE': {
-    'id': 'CMCLWO',
-    'template': "'#{class}' doesn't implement '#{method}' "
-        "declared in '#{declarer}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-m();
-}
-class C implements I {}
-main() => new C();
-""",
-      """
-abstract class I {
-m();
-}
-class C extends I {}
-main() => new C();
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_METHOD': {
-    'id': 'IJSNQB',
-    'template': "'#{class}' doesn't implement '#{method}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-m();
-}
-
-abstract class J {
-m();
-}
-
-class C implements I, J {}
-
-main() {
-new C();
-}
-""",
-      """
-abstract class I {
-m();
-}
-
-abstract class J {
-m();
-}
-
-class C extends I implements J {}
-
-main() {
-new C();
-}
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_METHOD_CONT': {
-    'id': 'KFBKPO',
-    'template': "The method '#{name}' is declared here in class '#{class}'.",
-  },
-
-  'UNIMPLEMENTED_SETTER_ONE': {
-    'id': 'QGKTEA',
-    'template': "'#{class}' doesn't implement the setter '#{name}' "
-        "declared in '#{declarer}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-set m(_);
-}
-class C implements I {}
-class D implements I {
-set m(_) {}
-}
-main() {
-new D().m = 0;
-new C();
-}
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_SETTER': {
-    'id': 'VEEGJQ',
-    'template': "'#{class}' doesn't implement the setter '#{name}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-set m(_);
-}
-abstract class J {
-set m(_);
-}
-class C implements I, J {}
-main() => new C();
-""",
-      """
-abstract class I {
-set m(_);
-}
-abstract class J {
-set m(_);
-}
-class C extends I implements J {}
-main() => new C();
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_EXPLICIT_SETTER': {
-    'id': 'SABABA',
-    'template': "The setter '#{name}' is declared here in class '#{class}'.",
-  },
-
-  'UNIMPLEMENTED_IMPLICIT_SETTER': {
-    'id': 'SWESAQ',
-    'template': "The setter '#{name}' is implicitly declared by this field "
-        "in class '#{class}'.",
-  },
-
-  'UNIMPLEMENTED_GETTER_ONE': {
-    'id': 'ODEPFW',
-    'template': "'#{class}' doesn't implement the getter '#{name}' "
-        "declared in '#{declarer}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-get m;
-}
-class C implements I {}
-main() => new C();
-""",
-      """
-abstract class I {
-get m;
-}
-class C extends I {}
-main() => new C();
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_GETTER': {
-    'id': 'VHSECG',
-    'template': "'#{class}' doesn't implement the getter '#{name}'.",
-    'howToFix': "Try adding an implementation of '#{name}' or declaring "
-        "'#{class}' to be 'abstract'.",
-    'examples': [
-      """
-abstract class I {
-get m;
-}
-abstract class J {
-get m;
-}
-class C implements I, J {}
-main() => new C();
-""",
-      """
-abstract class I {
-get m;
-}
-abstract class J {
-get m;
-}
-class C extends I implements J {}
-main() => new C();
-"""
-    ],
-  },
-
-  'UNIMPLEMENTED_EXPLICIT_GETTER': {
-    'id': 'HFDJPP',
-    'template': "The getter '#{name}' is declared here in class '#{class}'.",
-  },
-
-  'UNIMPLEMENTED_IMPLICIT_GETTER': {
-    'id': 'BSCQNO',
-    'template': "The getter '#{name}' is implicitly declared by this field "
-        "in class '#{class}'.",
-  },
-
-  'INVALID_METADATA': {
-    'id': 'RKJGDE',
-    'template':
-        "A metadata annotation must be either a reference to a compile-time "
-        "constant variable or a call to a constant constructor.",
-    'howToFix':
-        "Try using a different constant value or referencing it through a "
-        "constant variable.",
-    'examples': [
-'@Object main() {}',
-'@print main() {}']
-  },
-
-  'INVALID_METADATA_GENERIC': {
-    'id': 'WEEDQD',
-    'template':
-        "A metadata annotation using a constant constructor cannot use type "
-        "arguments.",
-    'howToFix':
-        "Try removing the type arguments or referencing the constant "
-        "through a constant variable.",
-    'examples': [
-      '''
-class C<T> {
-  const C();
-}
-@C<int>() main() {}
-'''],
-  },
-
-  'EQUAL_MAP_ENTRY_KEY': {
-    'id': 'KIDLPM',
-    'template': "An entry with the same key already exists in the map.",
-    'howToFix': "Try removing the previous entry or changing the key in one "
-        "of the entries.",
-    'examples': [
-      """
-main() {
-var m = const {'foo': 1, 'foo': 2};
-}"""
-    ],
-  },
-
-  'BAD_INPUT_CHARACTER': {
-    'id': 'SHQWJY',
-    'template': "Character U+#{characterHex} isn't allowed here.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-main() {
-String x = ç;
-}
-"""
-    ],
-  },
-
-  'UNTERMINATED_STRING': {
-    'id': 'TRLTHK',
-    'template': "String must end with #{quote}.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      """
-main() {
-return '
-;
-}
-""",
-      """
-main() {
-return \"
-;
-}
-""",
-      """
-main() {
-return r'
-;
-}
-""",
-      """
-main() {
-return r\"
-;
-}
-""",
-      """
-main() => '''
-""",
-      """
-main() => \"\"\"
-""",
-      """
-main() => r'''
-""",
-      """
-main() => r\"\"\"
-"""
-    ],
-  },
-
-  'UNMATCHED_TOKEN': {
-    'id': 'AGJKMQ',
-    'template': "Can't find '#{end}' to match '#{begin}'.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': ["main(", "main(){", "main(){]}",],
-  },
-
-  'UNTERMINATED_TOKEN': {
-    'id': 'VIIXHQ',
-    'template':
-        // This is a fall-back message that shouldn't happen.
-        "Incomplete token.",
-  },
-
-  'EXPONENT_MISSING': {
-    'id': 'CXPLCR',
-    'template':
-        "Numbers in exponential notation should always contain an exponent"
-        " (an integer number with an optional sign).",
-    'howToFix': "Make sure there is an exponent, and remove any whitespace "
-        "before it.",
-    'examples': [
-      """
-main() {
-var i = 1e;
-}
-"""
-    ],
-  },
-
-  'HEX_DIGIT_EXPECTED': {
-    'id': 'GKCAGV',
-    'template': "A hex digit (0-9 or A-F) must follow '0x'.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
-    'examples': [
-      """
-main() {
-var i = 0x;
-}
-"""
-    ],
-  },
-
-  'MALFORMED_STRING_LITERAL': {
-    'id': 'DULNSD',
-    'template':
-        r"A '$' has special meaning inside a string, and must be followed by "
-        "an identifier or an expression in curly braces ({}).",
-    'howToFix': r"Try adding a backslash (\) to escape the '$'.",
-    'examples': [
-      r"""
-main() {
-return '$';
-}
-""",
-      r'''
-main() {
-return "$";
-}
-''',
-      r"""
-main() {
-return '''$''';
-}
-""",
-      r'''
-main() {
-return """$""";
-}
-'''
-    ],
-  },
-
-  'UNTERMINATED_COMMENT': {
-    'id': 'NECJNM',
-    'template': "Comment starting with '/*' must end with '*/'.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      r"""
-main() {
-}
-/*"""
-    ],
-  },
-
-  'MISSING_TOKEN_BEFORE_THIS': {
-    'id': 'AFKXGU',
-    'template': "Expected '#{token}' before this.",
-    // Consider the second example below: the parser expects a ')' before
-    // 'y', but a ',' would also have worked. We don't have enough
-    // information to give a good suggestion.
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': ["main() => true ? 1;", "main() => foo(x: 1 y: 2);",],
-  },
-
-  'MISSING_TOKEN_AFTER_THIS': {
-    'id': 'FMUFJL',
-    'template': "Expected '#{token}' after this.",
-    // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
-    // to give a good suggestion.
-    'howToFix': DONT_KNOW_HOW_TO_FIX,
-    'examples': [
-      "main(x) {x}",
-      """
-class S1 {}
-class S2 {}
-class S3 {}
-class A = S1 with S2, S3
-main() => new A();
-"""
-    ],
-  },
-
-  'CONSIDER_ANALYZE_ALL': {
-    'id': 'HHILSH',
-    'template': "Could not find '#{main}'.  Nothing will be analyzed.",
-    'howToFix': "Try using '--analyze-all' to analyze everything.",
-    'examples': [''],
-  },
-
-  'MISSING_MAIN': {
-    'id': 'HNAOPV',
-    'template': "Could not find '#{main}'.",
-    // No example, test uses '--analyze-only' which will produce the above
-    // message [CONSIDER_ANALYZE_ALL].  An example for a human operator
-    // would be an empty file.
-    'howToFix': "Try adding a method named '#{main}' to your program."
-  },
-
-  'MAIN_NOT_A_FUNCTION': {
-    'id': 'PIURPA',
-    'template': "'#{main}' is not a function.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
-    'examples': ['var main;'],
-  },
-
-  'MAIN_WITH_EXTRA_PARAMETER': {
-    'id': 'ONOGQB',
-    'template': "'#{main}' cannot have more than two parameters.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
-    'examples': ['main(a, b, c) {}'],
-  },
-
-  'COMPILER_CRASHED': {
-    'id': 'MHDWAV',
-    'template': "The compiler crashed when compiling this element.",
-  },
-
-  'PLEASE_REPORT_THE_CRASH': {
-    'id': 'UUTHXX',
-    'template': '''
-The compiler is broken.
-
-When compiling the above element, the compiler crashed. It is not
-possible to tell if this is caused by a problem in your program or
-not. Regardless, the compiler should not crash.
-
-The Dart team would greatly appreciate if you would take a moment to
-report this problem at http://dartbug.com/new.
-
-Please include the following information:
-
-* the name and version of your operating system,
-
-* the Dart SDK build number (#{buildId}), and
-
-* the entire message you see here (including the full stack trace
-below as well as the source location above).
-''',
-  },
-
-  'POTENTIAL_MUTATION': {
-    'id': 'YGNLLB',
-    'template': "Variable '#{variableName}' is not known to be of type "
-        "'#{shownType}' because it is potentially mutated in the scope for "
-        "promotion.",
-  },
-
-  'POTENTIAL_MUTATION_HERE': {
-    'id': 'ATMSVX',
-    'template': "Variable '#{variableName}' is potentially mutated here.",
-  },
-
-  'POTENTIAL_MUTATION_IN_CLOSURE': {
-    'id': 'XUAHTW',
-    'template': "Variable '#{variableName}' is not known to be of type "
-        "'#{shownType}' because it is potentially mutated within a closure.",
-  },
-
-  'POTENTIAL_MUTATION_IN_CLOSURE_HERE': {
-    'id': 'UHFXLG',
-    'template': "Variable '#{variableName}' is potentially mutated in a "
-        "closure here.",
-  },
-
-  'ACCESSED_IN_CLOSURE': {
-    'id': 'JJHKSF',
-    'template': "Variable '#{variableName}' is not known to be of type "
-        "'#{shownType}' because it is accessed by a closure in the scope for "
-        "promotion and potentially mutated in the scope of "
-        "'#{variableName}'.",
-  },
-
-  'ACCESSED_IN_CLOSURE_HERE': {
-    'id': 'KMJVEA',
-    'template': "Variable '#{variableName}' is accessed in a closure here.",
-  },
-
-  'NOT_MORE_SPECIFIC': {
-    'id': 'EJHQAG',
-    'template': "Variable '#{variableName}' is not shown to have type "
-        "'#{shownType}' because '#{shownType}' is not more specific than the "
-        "known type '#{knownType}' of '#{variableName}'.",
-  },
-
-  'NOT_MORE_SPECIFIC_SUBTYPE': {
-    'id': 'APICDL',
-    'template': "Variable '#{variableName}' is not shown to have type "
-        "'#{shownType}' because '#{shownType}' is not a subtype of the "
-        "known type '#{knownType}' of '#{variableName}'.",
-  },
-
-  'NOT_MORE_SPECIFIC_SUGGESTION': {
-    'id': 'FFNCJX',
-    'template': "Variable '#{variableName}' is not shown to have type "
-        "'#{shownType}' because '#{shownType}' is not more specific than the "
-        "known type '#{knownType}' of '#{variableName}'.",
-    'howToFix': "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'.",
-  },
-
-  'NO_COMMON_SUBTYPES': {
-    'id': 'XKJOEC',
-    'template': "Types '#{left}' and '#{right}' have no common subtypes.",
-  },
-
-  'HIDDEN_WARNINGS_HINTS': {
-    'id': 'JBAWEK',
-    'template':
-        "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}.",
-  },
-
-  'HIDDEN_WARNINGS': {
-    'id': 'JIYWDC',
-    'template': "#{warnings} warning(s) suppressed in #{uri}.",
-  },
-
-  'HIDDEN_HINTS': {
-    'id': 'RHNXQT',
-    'template': "#{hints} hint(s) suppressed in #{uri}.",
-  },
-
-  'PREAMBLE': {
-    'id': 'GXGWIF',
-    'template': "When run on the command-line, the compiled output might"
-        " require a preamble file located in:\n"
-        "  <sdk>/lib/_internal/js_runtime/lib/preambles.",
-  },
-
-  'INVALID_SYNC_MODIFIER': {
-    'id': 'FNYUYU',
-    'template': "Invalid modifier 'sync'.",
-    'howToFix': "Try replacing 'sync' with 'sync*'.",
-    'examples': ["main() sync {}"],
-  },
-
-  'INVALID_AWAIT_FOR': {
-    'id': 'IEYGCY',
-    'template': "'await' is only supported on for-in loops.",
-    'howToFix': "Try rewriting the loop as a for-in loop or removing the "
-        "'await' keyword.",
-    'examples': [
-      """
-main() async* {
-await for (int i = 0; i < 10; i++) {}
-}
-"""
-    ],
-  },
-
-  'INVALID_AWAIT_FOR_IN': {
-    'id': 'FIEYGC',
-    'template': "'await' is only supported in methods with an 'async' or "
-                "'async*' body modifier.",
-    'howToFix': "Try adding 'async' or 'async*' to the method body or "
-                "removing the 'await' keyword.",
-    'examples': [
-      """
-main(o) sync* {
-  await for (var e in o) {}
-}
-"""
-    ],
-  },
-
-  'INVALID_AWAIT': {
-    'id': 'IEYHYD',
-    'template': "'await' is only supported in methods with an 'async' or "
-                "'async*' body modifier.",
-    'howToFix': "Try adding 'async' or 'async*' to the method body.",
-    'examples': [
-      """
-main() sync* {
-  await null;
-}
-"""
-    ],
-  },
-
-  'INVALID_YIELD': {
-    'id': 'IPGGCY',
-    'template': "'yield' is only supported in methods with a 'sync*' or "
-                "'async*' body modifier.",
-    'howToFix': "Try adding 'sync*' or 'async*' to the method body.",
-    'examples': [
-      """
-main() async {
-  yield 0;
-}
-"""
-    ],
-  },
-
-  'ASYNC_MODIFIER_ON_ABSTRACT_METHOD': {
-    'id': 'VRISLY',
-    'template':
-        "The modifier '#{modifier}' is not allowed on an abstract method.",
-    'options': ['--enable-async'],
-    'howToFix': "Try removing the '#{modifier}' modifier or adding a "
-        "body to the method.",
-    'examples': [
-      """
-abstract class A {
-method() async;
-}
-class B extends A {
-method() {}
-}
-main() {
-A a = new B();
-a.method();
-}
-"""
-    ],
-  },
-
-  'ASYNC_MODIFIER_ON_CONSTRUCTOR': {
-    'id': 'DHCFON',
-    'template': "The modifier '#{modifier}' is not allowed on constructors.",
-    'options': ['--enable-async'],
-    'howToFix': "Try removing the '#{modifier}' modifier.",
-    'examples': [
-      """
-class A {
-A() async;
-}
-main() => new A();""",
-      """
-class A {
-A();
-factory A.a() async* {}
-}
-main() => new A.a();"""
-    ],
-  },
-
-  'ASYNC_MODIFIER_ON_SETTER': {
-    'id': 'NMJLJE',
-    'template': "The modifier '#{modifier}' is not allowed on setters.",
-    'options': ['--enable-async'],
-    'howToFix': "Try removing the '#{modifier}' modifier.",
-    'examples': [
-      """
-class A {
-set foo(v) async {}
-}
-main() => new A().foo = 0;"""
-    ],
-  },
-
-  'YIELDING_MODIFIER_ON_ARROW_BODY': {
-    'id': 'UOGLUX',
-    'template':
-        "The modifier '#{modifier}' is not allowed on methods implemented "
-        "using '=>'.",
-    'options': ['--enable-async'],
-    'howToFix': "Try removing the '#{modifier}' modifier or implementing "
-        "the method body using a block: '{ ... }'.",
-    'examples': ["main() sync* => null;", "main() async* => null;"],
-  },
-
-  // TODO(johnniwinther): Check for 'async' as identifier.
-  'ASYNC_KEYWORD_AS_IDENTIFIER': {
-    'id': 'VTWSMA',
-    'template':
-        "'#{keyword}' cannot be used as an identifier in a function body "
-        "marked with '#{modifier}'.",
-    'options': ['--enable-async'],
-    'howToFix': "Try removing the '#{modifier}' modifier or renaming the "
-        "identifier.",
-    'examples': [
-      """
-main() async {
-var await;
-}""",
-      """
-main() async* {
-var yield;
-}""",
-      """
-main() sync* {
-var yield;
-}"""
-    ],
-  },
-
-  'RETURN_IN_GENERATOR': {
-    'id': 'AWGUVF',
-    'template':
-        "'return' with a value is not allowed in a method body using the "
-        "'#{modifier}' modifier.",
-    'howToFix': "Try removing the value, replacing 'return' with 'yield' "
-        "or changing the method body modifier.",
-    'examples': [
-      """
-foo() async* { return 0; }
-main() => foo();
-""",
-      """
-foo() sync* { return 0; }
-main() => foo();
-"""
-    ],
-  },
-
-  'NATIVE_NOT_SUPPORTED': {
-    'id': 'QMMLUT',
-    'template': "'native' modifier is not supported.",
-    'howToFix': "Try removing the 'native' implementation or analyzing the "
-        "code with the --allow-native-extensions option.",
-    'examples': [
-      """
-main() native "Main";
-"""
-    ],
-  },
-
-  'DART_EXT_NOT_SUPPORTED': {
-    'id': 'JLPQFJ',
-    'template': "The 'dart-ext' scheme is not supported.",
-    'howToFix': "Try analyzing the code with the --allow-native-extensions "
-        "option.",
-    'examples': [
-      """
-import 'dart-ext:main';
-
-main() {}
-"""
-    ],
-  },
-
-  'LIBRARY_TAG_MUST_BE_FIRST': {
-    'id': 'JFUSRX',
-    'template':
-        "The library declaration should come before other declarations.",
-    'howToFix': "Try moving the declaration to the top of the file.",
-    'examples': [
-      """
-import 'dart:core';
-library foo;
-main() {}
-""",
-    ],
-  },
-
-  'ONLY_ONE_LIBRARY_TAG': {
-    'id': 'CCXFMY',
-    'template': "There can only be one library declaration.",
-    'howToFix': "Try removing all other library declarations.",
-    'examples': [
-      """
-library foo;
-library bar;
-main() {}
-""",
-      """
-library foo;
-import 'dart:core';
-library bar;
-main() {}
-""",
-    ],
-  },
-
-  'IMPORT_BEFORE_PARTS': {
-    'id': 'NSMOQI',
-    'template': "Import declarations should come before parts.",
-    'howToFix': "Try moving this import further up in the file.",
-    'examples': [
-      {
-        'main.dart': """
-library test.main;
-part 'part.dart';
-import 'dart:core';
-main() {}
-""",
-        'part.dart': """
-part of test.main;
-""",
-      }
-    ],
-  },
-
-  'EXPORT_BEFORE_PARTS': {
-    'id': 'KYJTTC',
-    'template': "Export declarations should come before parts.",
-    'howToFix': "Try moving this export further up in the file.",
-    'examples': [
-      {
-        'main.dart': """
-library test.main;
-part 'part.dart';
-export 'dart:core';
-main() {}
-""",
-        'part.dart': """
-part of test.main;
-""",
-      }
-    ],
-
-//////////////////////////////////////////////////////////////////////////////
-// Patch errors start.
-//////////////////////////////////////////////////////////////////////////////
-  },
-
-  'PATCH_RETURN_TYPE_MISMATCH': {
-    'id': 'DTOQDU',
-    'template': "Patch return type '#{patchReturnType}' does not match "
-        "'#{originReturnType}' on origin method '#{methodName}'.",
-  },
-
-  'PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH': {
-    'id': 'KJUUYC',
-    'template': "Required parameter count of patch method "
-        "(#{patchParameterCount}) does not match parameter count on origin "
-        "method '#{methodName}' (#{originParameterCount}).",
-  },
-
-  'PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH': {
-    'id': 'GUTGTE',
-    'template': "Optional parameter count of patch method "
-        "(#{patchParameterCount}) does not match parameter count on origin "
-        "method '#{methodName}' (#{originParameterCount}).",
-  },
-
-  'PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH': {
-    'id': 'MCHEIC',
-    'template': "Optional parameters of origin and patch method "
-        "'#{methodName}' must both be either named or positional.",
-  },
-
-  'PATCH_PARAMETER_MISMATCH': {
-    'id': 'XISHPB',
-    'template': "Patch method parameter '#{patchParameter}' does not match "
-        "'#{originParameter}' on origin method '#{methodName}'.",
-  },
-
-  'PATCH_PARAMETER_TYPE_MISMATCH': {
-    'id': 'UGRBYD',
-    'template': "Patch method parameter '#{parameterName}' type "
-        "'#{patchParameterType}' does not match '#{originParameterType}' on "
-        "origin method '#{methodName}'.",
-  },
-
-  'PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION': {
-    'id': 'WSNMKD',
-    'template': "External method without an implementation.",
-  },
-
-  'PATCH_POINT_TO_FUNCTION': {
-    'id': 'CAVBPN',
-    'template': "This is the function patch '#{functionName}'.",
-  },
-
-  'PATCH_POINT_TO_CLASS': {
-    'id': 'TWDLDX',
-    'template': "This is the class patch '#{className}'.",
-  },
-
-  'PATCH_POINT_TO_GETTER': {
-    'id': 'TRBBNY',
-    'template': "This is the getter patch '#{getterName}'.",
-  },
-
-  'PATCH_POINT_TO_SETTER': {
-    'id': 'DAXDLW',
-    'template': "This is the setter patch '#{setterName}'.",
-  },
-
-  'PATCH_POINT_TO_CONSTRUCTOR': {
-    'id': 'VYQISY',
-    'template': "This is the constructor patch '#{constructorName}'.",
-  },
-
-  'PATCH_POINT_TO_PARAMETER': {
-    'id': 'TFPAGO',
-    'template': "This is the patch parameter '#{parameterName}'.",
-  },
-
-  'PATCH_NON_EXISTING': {
-    'id': 'AWOACF',
-    'template': "Origin does not exist for patch '#{name}'.",
-  },
-
-  // TODO(ahe): Eventually, this error should be removed as it will be
-  // handled by the regular parser.
-  'PATCH_NONPATCHABLE': {
-    'id': 'WQEPJI',
-    'template': "Only classes and functions can be patched.",
-  },
-
-  'PATCH_NON_EXTERNAL': {
-    'id': 'MHLXNK',
-    'template': "Only external functions can be patched.",
-  },
-
-  'PATCH_NON_CLASS': {
-    'id': 'UIALAB',
-    'template': "Patching non-class with class patch '#{className}'.",
-  },
-
-  'PATCH_NON_GETTER': {
-    'id': 'VTNQCJ',
-    'template': "Cannot patch non-getter '#{name}' with getter patch.",
-  },
-
-  'PATCH_NO_GETTER': {
-    'id': 'XOPDHD',
-    'template': "No getter found for getter patch '#{getterName}'.",
-  },
-
-  'PATCH_NON_SETTER': {
-    'id': 'XBOMMN',
-    'template': "Cannot patch non-setter '#{name}' with setter patch.",
-  },
-
-  'PATCH_NO_SETTER': {
-    'id': 'YITARQ',
-    'template': "No setter found for setter patch '#{setterName}'.",
-  },
-
-  'PATCH_NON_CONSTRUCTOR': {
-    'id': 'TWAEQV',
-    'template': "Cannot patch non-constructor with constructor patch "
-        "'#{constructorName}'.",
-  },
-
-  'PATCH_NON_FUNCTION': {
-    'id': 'EDXBPI',
-    'template': "Cannot patch non-function with function patch "
-        "'#{functionName}'.",
-  },
-
-  'INJECTED_PUBLIC_MEMBER': {
-    'id': 'JGMXMI',
-    'template': "Non-patch members in patch libraries must be private.",
-  },
-
-  'EXTERNAL_WITH_BODY': {
-    'id': 'GAVMSQ',
-    'template':
-        "External function '#{functionName}' cannot have a function body.",
-    'options': ["--output-type=dart"],
-    'howToFix': "Try removing the 'external' modifier or the function body.",
-    'examples': [
-      """
-external foo() => 0;
-main() => foo();
-""",
-      """
-external foo() {}
-main() => foo();
-"""
-    ],
-
-//////////////////////////////////////////////////////////////////////////////
-// Patch errors end.
-//////////////////////////////////////////////////////////////////////////////
-  },
-
-  'EXPERIMENTAL_ASSERT_MESSAGE': {
-    'id': 'NENGIS',
-    'template': "Experimental language feature 'assertion with message'"
-        " is not supported.",
-    'howToFix':
-        "Use option '--assert-message' to use assertions with messages.",
-    'examples': [
-      r'''
-main() {
-int n = -7;
-assert(n > 0, 'must be positive: $n');
-}
-'''
-    ],
-  },
-
-  'IMPORT_EXPERIMENTAL_MIRRORS': {
-    'id': 'SCJYPH',
-    'template': '''
-
-****************************************************************
-* WARNING: dart:mirrors support in dart2js is experimental,
-*          and not recommended.
-*          This implementation of mirrors is incomplete,
-*          and often greatly increases the size of the generated
-*          JavaScript code.
-*
-* Your app imports dart:mirrors via:'''
-        '''
-$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
-*
-* You can disable this message by using the --enable-experimental-mirrors
-* command-line flag.
-*
-* To learn what to do next, please visit:
-*    http://dartlang.org/dart2js-reflection
-****************************************************************
-''',
-  },
-
-  'DISALLOWED_LIBRARY_IMPORT': {
-    'id': 'OCSFJU',
-    'template': '''
-Your app imports the unsupported library '#{uri}' via:
-'''
-        '''
-$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
-
-Use the --categories option to support import of '#{uri}'.
-''',
-  },
-
-  'MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND': {
-    'id': 'JBTRRM',
-    'template': """
-dart:mirrors library is not supported when using this backend.
-
-Your app imports dart:mirrors via:"""
-        """
-$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}""",
-  },
-
-  'CALL_NOT_SUPPORTED_ON_NATIVE_CLASS': {
-    'id': 'HAULDW',
-    'template': "Non-supported 'call' member on a native class, or a "
-        "subclass of a native class.",
-  },
-
-  'DIRECTLY_THROWING_NSM': {
-    'id': 'XLTPCS',
-    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
-        "exception. The generated code will be smaller if it is "
-        "rewritten.",
-    'howToFix': "Rewrite to "
-        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
-  },
-
-  'COMPLEX_THROWING_NSM': {
-    'id': 'PLCXVX',
-    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
-        "exception. The generated code will be smaller and the compiler "
-        "will be able to perform more optimizations if it is rewritten.",
-    'howToFix': "Rewrite to "
-        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
-  },
-
-  'COMPLEX_RETURNING_NSM': {
-    'id': 'HUTCTQ',
-    'template': "Overriding 'noSuchMethod' causes the compiler to generate "
-        "more code and prevents the compiler from doing some optimizations.",
-    'howToFix': "Consider removing this 'noSuchMethod' implementation."
-  },
-
-  'UNRECOGNIZED_VERSION_OF_LOOKUP_MAP': {
-    'id': 'OVAFEW',
-    'template': "Unsupported version of package:lookup_map.",
-    'howToFix': DONT_KNOW_HOW_TO_FIX
-  },
-};
diff --git a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
new file mode 100644
index 0000000..c8617cc
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
@@ -0,0 +1,37 @@
+// 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.
+/*
+DON'T EDIT. GENERATED. DON'T EDIT.
+This file has been generated by 'publish.dart' in the dart_messages package.
+
+Messages are maintained in `lib/shared_messages.dart` of that same package.
+After any change to that file, run `bin/publish.dart` to generate a new version
+of the json, dart2js and analyzer representations.
+*/
+import '../messages.dart' show MessageTemplate;
+
+enum SharedMessageKind {
+  exampleMessage
+}
+
+const Map<SharedMessageKind, MessageTemplate> TEMPLATES = const <SharedMessageKind, MessageTemplate>{ 
+  SharedMessageKind.exampleMessage: const MessageTemplate(
+    SharedMessageKind.exampleMessage,
+    "#use #named #arguments",
+    howToFix: "an explanation on how to fix things",
+    examples: const [
+      r'''
+      Some multiline example;
+      That generates the bug.''',
+      const {
+      'fileA.dart': r'''
+        or a map from file to content.
+        again multiline''',
+      'fileB.dart': r'''
+        with possibly multiple files.
+        muliline too''',
+      },
+    ]
+  ),  // Generated. Don't edit.
+};
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index b529e1c..f394bdf 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -2,16 +2,81 @@
 // 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.
 
+
+/**
+ * The messages in this file should meet the following guide lines:
+ *
+ * 1. The message should be a complete sentence starting with an uppercase
+ * letter, and ending with a period.
+ *
+ * 2. Reserved words and embedded identifiers should be in single quotes, so
+ * prefer double quotes for the complete message. For example, "The
+ * class '#{className}' can't use 'super'." Notice that the word 'class' in the
+ * preceding message is not quoted as it refers to the concept 'class', not the
+ * reserved word. On the other hand, 'super' refers to the reserved word. Do
+ * not quote 'null' and numeric literals.
+ *
+ * 3. Do not try to compose messages, as it can make translating them hard.
+ *
+ * 4. Try to keep the error messages short, but informative.
+ *
+ * 5. Use simple words and terminology, assume the reader of the message
+ * doesn't have an advanced degree in math, and that English is not the
+ * reader's native language. Do not assume any formal computer science
+ * training. For example, do not use Latin abbreviations (prefer "that is" over
+ * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+ * only if" and "iff", that level of precision is unnecessary.
+ *
+ * 6. Prefer contractions when they are in common use, for example, prefer
+ * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+ * off-putting to people new to programming.
+ *
+ * 7. Use common terminology, preferably from the Dart Language
+ * Specification. This increases the user's chance of finding a good
+ * explanation on the web.
+ *
+ * 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+ * product that crashes with a "tongue-in-cheek" message, especially if you did
+ * not want to use this product to begin with.
+ *
+ * 9. Do not lie, that is, do not write error messages containing phrases like
+ * "can't happen".  If the user ever saw this message, it would be a
+ * lie. Prefer messages like: "Internal error: This function should not be
+ * called when 'x' is null.".
+ *
+ * 10. Prefer to not use imperative tone. That is, the message should not sound
+ * accusing or like it is ordering the user around. The computer should
+ * describe the problem, not criticize for violating the specification.
+ *
+ * Other things to keep in mind:
+ *
+ * An INFO message should always be preceded by a non-INFO message, and the
+ * INFO messages are additional details about the preceding non-INFO
+ * message. For example, consider duplicated elements. First report a WARNING
+ * or ERROR about the duplicated element, and then report an INFO about the
+ * location of the existing element.
+ *
+ * Generally, we want to provide messages that consists of three sentences:
+ * 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].
+ */
+
 library dart2js.messages;
 
-import 'package:dart_messages/shared_messages.dart' as shared_messages;
+import '../tokens/token.dart' show
+    ErrorToken,
+    Token;
 
-import '../tokens/token.dart' show ErrorToken, Token;
+import 'invariant.dart' show
+    invariant;
+import 'spannable.dart' show
+    CURRENT_ELEMENT_SPANNABLE;
 
-import 'invariant.dart' show invariant;
-import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
+import 'generated/shared_messages.dart' as shared_messages;
 
-import 'dart2js_messages.dart' as dart2js_messages;
+export 'generated/shared_messages.dart' show SharedMessageKind;
+
+const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
 
 /// Keys for the [MessageTemplate]s.
 enum MessageKind {
@@ -406,472 +471,13 @@
   YIELDING_MODIFIER_ON_ARROW_BODY,
 }
 
-const _KIND_TO_STRING_MAP = const <MessageKind, String>{
-  MessageKind.ABSTRACT_CLASS_INSTANTIATION: "ABSTRACT_CLASS_INSTANTIATION",
-  MessageKind.ABSTRACT_GETTER: "ABSTRACT_GETTER",
-  MessageKind.ABSTRACT_METHOD: "ABSTRACT_METHOD",
-  MessageKind.ABSTRACT_SETTER: "ABSTRACT_SETTER",
-  MessageKind.ACCESSED_IN_CLOSURE: "ACCESSED_IN_CLOSURE",
-  MessageKind.ACCESSED_IN_CLOSURE_HERE: "ACCESSED_IN_CLOSURE_HERE",
-  MessageKind.ADDITIONAL_ARGUMENT: "ADDITIONAL_ARGUMENT",
-  MessageKind.ADDITIONAL_TYPE_ARGUMENT: "ADDITIONAL_TYPE_ARGUMENT",
-  MessageKind.ALREADY_INITIALIZED: "ALREADY_INITIALIZED",
-  MessageKind.AMBIGUOUS_LOCATION: "AMBIGUOUS_LOCATION",
-  MessageKind.AMBIGUOUS_REEXPORT: "AMBIGUOUS_REEXPORT",
-  MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
-      "ASSERT_IS_GIVEN_NAMED_ARGUMENTS",
-  MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER: "ASSIGNING_FINAL_FIELD_IN_SUPER",
-  MessageKind.ASSIGNING_METHOD: "ASSIGNING_METHOD",
-  MessageKind.ASSIGNING_METHOD_IN_SUPER: "ASSIGNING_METHOD_IN_SUPER",
-  MessageKind.ASSIGNING_TYPE: "ASSIGNING_TYPE",
-  MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER: "ASYNC_KEYWORD_AS_IDENTIFIER",
-  MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
-      "ASYNC_MODIFIER_ON_ABSTRACT_METHOD",
-  MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR: "ASYNC_MODIFIER_ON_CONSTRUCTOR",
-  MessageKind.ASYNC_MODIFIER_ON_SETTER: "ASYNC_MODIFIER_ON_SETTER",
-  MessageKind.AWAIT_MEMBER_NOT_FOUND: "AWAIT_MEMBER_NOT_FOUND",
-  MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
-      "AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE",
-  MessageKind.BAD_INPUT_CHARACTER: "BAD_INPUT_CHARACTER",
-  MessageKind.BEFORE_TOP_LEVEL: "BEFORE_TOP_LEVEL",
-  MessageKind.BINARY_OPERATOR_BAD_ARITY: "BINARY_OPERATOR_BAD_ARITY",
-  MessageKind.BODY_EXPECTED: "BODY_EXPECTED",
-  MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
-      "CALL_NOT_SUPPORTED_ON_NATIVE_CLASS",
-  MessageKind.CANNOT_EXTEND: "CANNOT_EXTEND",
-  MessageKind.CANNOT_EXTEND_ENUM: "CANNOT_EXTEND_ENUM",
-  MessageKind.CANNOT_EXTEND_MALFORMED: "CANNOT_EXTEND_MALFORMED",
-  MessageKind.CANNOT_FIND_CONSTRUCTOR: "CANNOT_FIND_CONSTRUCTOR",
-  MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
-      "CANNOT_FIND_UNNAMED_CONSTRUCTOR",
-  MessageKind.CANNOT_IMPLEMENT: "CANNOT_IMPLEMENT",
-  MessageKind.CANNOT_IMPLEMENT_ENUM: "CANNOT_IMPLEMENT_ENUM",
-  MessageKind.CANNOT_IMPLEMENT_MALFORMED: "CANNOT_IMPLEMENT_MALFORMED",
-  MessageKind.CANNOT_INSTANTIATE_ENUM: "CANNOT_INSTANTIATE_ENUM",
-  MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
-      "CANNOT_INSTANTIATE_TYPE_VARIABLE",
-  MessageKind.CANNOT_INSTANTIATE_TYPEDEF: "CANNOT_INSTANTIATE_TYPEDEF",
-  MessageKind.CANNOT_MIXIN: "CANNOT_MIXIN",
-  MessageKind.CANNOT_MIXIN_ENUM: "CANNOT_MIXIN_ENUM",
-  MessageKind.CANNOT_MIXIN_MALFORMED: "CANNOT_MIXIN_MALFORMED",
-  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
-      "CANNOT_OVERRIDE_FIELD_WITH_METHOD",
-  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
-      "CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT",
-  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
-      "CANNOT_OVERRIDE_GETTER_WITH_METHOD",
-  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
-      "CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT",
-  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
-      "CANNOT_OVERRIDE_METHOD_WITH_FIELD",
-  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
-      "CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT",
-  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
-      "CANNOT_OVERRIDE_METHOD_WITH_GETTER",
-  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
-      "CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT",
-  MessageKind.CANNOT_RESOLVE: "CANNOT_RESOLVE",
-  MessageKind.CANNOT_RESOLVE_AWAIT: "CANNOT_RESOLVE_AWAIT",
-  MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
-      "CANNOT_RESOLVE_AWAIT_IN_CLOSURE",
-  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR: "CANNOT_RESOLVE_CONSTRUCTOR",
-  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
-      "CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT",
-  MessageKind.CANNOT_RESOLVE_GETTER: "CANNOT_RESOLVE_GETTER",
-  MessageKind.CANNOT_RESOLVE_IN_INITIALIZER: "CANNOT_RESOLVE_IN_INITIALIZER",
-  MessageKind.CANNOT_RESOLVE_SETTER: "CANNOT_RESOLVE_SETTER",
-  MessageKind.CANNOT_RESOLVE_TYPE: "CANNOT_RESOLVE_TYPE",
-  MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR: "CANNOT_RETURN_FROM_CONSTRUCTOR",
-  MessageKind.CLASS_NAME_EXPECTED: "CLASS_NAME_EXPECTED",
-  MessageKind.COMPILER_CRASHED: "COMPILER_CRASHED",
-  MessageKind.COMPLEX_RETURNING_NSM: "COMPLEX_RETURNING_NSM",
-  MessageKind.COMPLEX_THROWING_NSM: "COMPLEX_THROWING_NSM",
-  MessageKind.CONSIDER_ANALYZE_ALL: "CONSIDER_ANALYZE_ALL",
-  MessageKind.CONST_CALLS_NON_CONST: "CONST_CALLS_NON_CONST",
-  MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
-      "CONST_CALLS_NON_CONST_FOR_IMPLICIT",
-  MessageKind.CONST_CONSTRUCTOR_HAS_BODY: "CONST_CONSTRUCTOR_HAS_BODY",
-  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
-      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS",
-  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
-      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR",
-  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
-      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD",
-  MessageKind.CONST_LOOP_VARIABLE: "CONST_LOOP_VARIABLE",
-  MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS: "CONST_MAP_KEY_OVERRIDES_EQUALS",
-  MessageKind.CONST_WITHOUT_INITIALIZER: "CONST_WITHOUT_INITIALIZER",
-  MessageKind.CONSTRUCTOR_CALL_EXPECTED: "CONSTRUCTOR_CALL_EXPECTED",
-  MessageKind.CONSTRUCTOR_IS_NOT_CONST: "CONSTRUCTOR_IS_NOT_CONST",
-  MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE: "CONSTRUCTOR_WITH_RETURN_TYPE",
-  MessageKind.CYCLIC_CLASS_HIERARCHY: "CYCLIC_CLASS_HIERARCHY",
-  MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS: "CYCLIC_COMPILE_TIME_CONSTANTS",
-  MessageKind.CYCLIC_REDIRECTING_FACTORY: "CYCLIC_REDIRECTING_FACTORY",
-  MessageKind.CYCLIC_TYPE_VARIABLE: "CYCLIC_TYPE_VARIABLE",
-  MessageKind.CYCLIC_TYPEDEF: "CYCLIC_TYPEDEF",
-  MessageKind.CYCLIC_TYPEDEF_ONE: "CYCLIC_TYPEDEF_ONE",
-  MessageKind.DART_EXT_NOT_SUPPORTED: "DART_EXT_NOT_SUPPORTED",
-  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT: "DEFERRED_COMPILE_TIME_CONSTANT",
-  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
-      "DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION",
-  MessageKind.DEFERRED_LIBRARY_DART_2_DART: "DEFERRED_LIBRARY_DART_2_DART",
-  MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
-      "DEFERRED_LIBRARY_DUPLICATE_PREFIX",
-  MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
-      "DEFERRED_LIBRARY_WITHOUT_PREFIX",
-  MessageKind.DEFERRED_OLD_SYNTAX: "DEFERRED_OLD_SYNTAX",
-  MessageKind.DEFERRED_TYPE_ANNOTATION: "DEFERRED_TYPE_ANNOTATION",
-  MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
-      "DEPRECATED_TYPEDEF_MIXIN_SYNTAX",
-  MessageKind.DIRECTLY_THROWING_NSM: "DIRECTLY_THROWING_NSM",
-  MessageKind.DISALLOWED_LIBRARY_IMPORT: "DISALLOWED_LIBRARY_IMPORT",
-  MessageKind.DUPLICATE_DEFINITION: "DUPLICATE_DEFINITION",
-  MessageKind.DUPLICATE_EXPORT: "DUPLICATE_EXPORT",
-  MessageKind.DUPLICATE_EXPORT_CONT: "DUPLICATE_EXPORT_CONT",
-  MessageKind.DUPLICATE_EXPORT_DECL: "DUPLICATE_EXPORT_DECL",
-  MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS: "DUPLICATE_EXTENDS_IMPLEMENTS",
-  MessageKind.DUPLICATE_IMPLEMENTS: "DUPLICATE_IMPLEMENTS",
-  MessageKind.DUPLICATE_IMPORT: "DUPLICATE_IMPORT",
-  MessageKind.DUPLICATE_INITIALIZER: "DUPLICATE_INITIALIZER",
-  MessageKind.DUPLICATE_LABEL: "DUPLICATE_LABEL",
-  MessageKind.DUPLICATE_SUPER_INITIALIZER: "DUPLICATE_SUPER_INITIALIZER",
-  MessageKind.DUPLICATE_TYPE_VARIABLE_NAME: "DUPLICATE_TYPE_VARIABLE_NAME",
-  MessageKind.DUPLICATED_LIBRARY_NAME: "DUPLICATED_LIBRARY_NAME",
-  MessageKind.DUPLICATED_LIBRARY_RESOURCE: "DUPLICATED_LIBRARY_RESOURCE",
-  MessageKind.DUPLICATED_PART_OF: "DUPLICATED_PART_OF",
-  MessageKind.DUPLICATED_RESOURCE: "DUPLICATED_RESOURCE",
-  MessageKind.EMPTY_CATCH_DECLARATION: "EMPTY_CATCH_DECLARATION",
-  MessageKind.EMPTY_ENUM_DECLARATION: "EMPTY_ENUM_DECLARATION",
-  MessageKind.EMPTY_HIDE: "EMPTY_HIDE",
-  MessageKind.EQUAL_MAP_ENTRY_KEY: "EQUAL_MAP_ENTRY_KEY",
-  MessageKind.EMPTY_SHOW: "EMPTY_SHOW",
-  MessageKind.EXISTING_DEFINITION: "EXISTING_DEFINITION",
-  MessageKind.EXISTING_LABEL: "EXISTING_LABEL",
-  MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
-      "EXPECTED_IDENTIFIER_NOT_RESERVED_WORD",
-  MessageKind.EXPERIMENTAL_ASSERT_MESSAGE: "EXPERIMENTAL_ASSERT_MESSAGE",
-  MessageKind.EXPONENT_MISSING: "EXPONENT_MISSING",
-  MessageKind.EXPORT_BEFORE_PARTS: "EXPORT_BEFORE_PARTS",
-  MessageKind.EXTERNAL_WITH_BODY: "EXTERNAL_WITH_BODY",
-  MessageKind.EXTRA_CATCH_DECLARATION: "EXTRA_CATCH_DECLARATION",
-  MessageKind.EXTRA_FORMALS: "EXTRA_FORMALS",
-  MessageKind.EXTRANEOUS_MODIFIER: "EXTRANEOUS_MODIFIER",
-  MessageKind.EXTRANEOUS_MODIFIER_REPLACE: "EXTRANEOUS_MODIFIER_REPLACE",
-  MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
-      "FACTORY_REDIRECTION_IN_NON_FACTORY",
-  MessageKind.FINAL_FUNCTION_TYPE_PARAMETER: "FINAL_FUNCTION_TYPE_PARAMETER",
-  MessageKind.FINAL_WITHOUT_INITIALIZER: "FINAL_WITHOUT_INITIALIZER",
-  MessageKind.FORIN_NOT_ASSIGNABLE: "FORIN_NOT_ASSIGNABLE",
-  MessageKind.FORMAL_DECLARED_CONST: "FORMAL_DECLARED_CONST",
-  MessageKind.FORMAL_DECLARED_STATIC: "FORMAL_DECLARED_STATIC",
-  MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
-      "FUNCTION_TYPE_FORMAL_WITH_DEFAULT",
-  MessageKind.FUNCTION_WITH_INITIALIZER: "FUNCTION_WITH_INITIALIZER",
-  MessageKind.GENERIC: "GENERIC",
-  MessageKind.GETTER_MISMATCH: "GETTER_MISMATCH",
-  MessageKind.GETTER_NOT_FOUND: "GETTER_NOT_FOUND",
-  MessageKind.HEX_DIGIT_EXPECTED: "HEX_DIGIT_EXPECTED",
-  MessageKind.HIDDEN_HINTS: "HIDDEN_HINTS",
-  MessageKind.HIDDEN_IMPLICIT_IMPORT: "HIDDEN_IMPLICIT_IMPORT",
-  MessageKind.HIDDEN_IMPORT: "HIDDEN_IMPORT",
-  MessageKind.HIDDEN_WARNINGS: "HIDDEN_WARNINGS",
-  MessageKind.HIDDEN_WARNINGS_HINTS: "HIDDEN_WARNINGS_HINTS",
-  MessageKind.IF_NULL_ASSIGNING_TYPE: "IF_NULL_ASSIGNING_TYPE",
-  MessageKind.ILLEGAL_CONST_FIELD_MODIFIER: "ILLEGAL_CONST_FIELD_MODIFIER",
-  MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS: "ILLEGAL_CONSTRUCTOR_MODIFIERS",
-  MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER: "ILLEGAL_FINAL_METHOD_MODIFIER",
-  MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
-      "ILLEGAL_MIXIN_APPLICATION_MODIFIERS",
-  MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR: "ILLEGAL_MIXIN_CONSTRUCTOR",
-  MessageKind.ILLEGAL_MIXIN_CYCLE: "ILLEGAL_MIXIN_CYCLE",
-  MessageKind.ILLEGAL_MIXIN_OBJECT: "ILLEGAL_MIXIN_OBJECT",
-  MessageKind.ILLEGAL_MIXIN_SUPER_USE: "ILLEGAL_MIXIN_SUPER_USE",
-  MessageKind.ILLEGAL_MIXIN_SUPERCLASS: "ILLEGAL_MIXIN_SUPERCLASS",
-  MessageKind.ILLEGAL_MIXIN_WITH_SUPER: "ILLEGAL_MIXIN_WITH_SUPER",
-  MessageKind.ILLEGAL_SETTER_FORMALS: "ILLEGAL_SETTER_FORMALS",
-  MessageKind.ILLEGAL_STATIC: "ILLEGAL_STATIC",
-  MessageKind.ILLEGAL_SUPER_SEND: "ILLEGAL_SUPER_SEND",
-  MessageKind.IMPORT_BEFORE_PARTS: "IMPORT_BEFORE_PARTS",
-  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS: "IMPORT_EXPERIMENTAL_MIRRORS",
-  MessageKind.IMPORT_PART_OF: "IMPORT_PART_OF",
-  MessageKind.IMPORT_PART_OF_HERE: "IMPORT_PART_OF_HERE",
-  MessageKind.IMPORTED_HERE: "IMPORTED_HERE",
-  MessageKind.INHERIT_GETTER_AND_METHOD: "INHERIT_GETTER_AND_METHOD",
-  MessageKind.INHERITED_EXPLICIT_GETTER: "INHERITED_EXPLICIT_GETTER",
-  MessageKind.INHERITED_IMPLICIT_GETTER: "INHERITED_IMPLICIT_GETTER",
-  MessageKind.INHERITED_METHOD: "INHERITED_METHOD",
-  MessageKind.INJECTED_PUBLIC_MEMBER: "INJECTED_PUBLIC_MEMBER",
-  MessageKind.INIT_STATIC_FIELD: "INIT_STATIC_FIELD",
-  MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
-      "INITIALIZING_FORMAL_NOT_ALLOWED",
-  MessageKind.INSTANCE_STATIC_SAME_NAME: "INSTANCE_STATIC_SAME_NAME",
-  MessageKind.INSTANCE_STATIC_SAME_NAME_CONT: "INSTANCE_STATIC_SAME_NAME_CONT",
-  MessageKind.INTERNAL_LIBRARY: "INTERNAL_LIBRARY",
-  MessageKind.INTERNAL_LIBRARY_FROM: "INTERNAL_LIBRARY_FROM",
-  MessageKind.INVALID_ARGUMENT_AFTER_NAMED: "INVALID_ARGUMENT_AFTER_NAMED",
-  MessageKind.INVALID_AWAIT: "INVALID_AWAIT",
-  MessageKind.INVALID_AWAIT_FOR: "INVALID_AWAIT_FOR",
-  MessageKind.INVALID_AWAIT_FOR_IN: "INVALID_AWAIT_FOR_IN",
-  MessageKind.INVALID_BREAK: "INVALID_BREAK",
-  MessageKind.INVALID_CASE_DEFAULT: "INVALID_CASE_DEFAULT",
-  MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS: "INVALID_CONSTRUCTOR_ARGUMENTS",
-  MessageKind.INVALID_CONSTRUCTOR_NAME: "INVALID_CONSTRUCTOR_NAME",
-  MessageKind.INVALID_CONTINUE: "INVALID_CONTINUE",
-  MessageKind.INVALID_FOR_IN: "INVALID_FOR_IN",
-  MessageKind.INVALID_INITIALIZER: "INVALID_INITIALIZER",
-  MessageKind.INVALID_METADATA: "INVALID_METADATA",
-  MessageKind.INVALID_METADATA_GENERIC: "INVALID_METADATA_GENERIC",
-  MessageKind.INVALID_OVERRIDDEN_FIELD: "INVALID_OVERRIDDEN_FIELD",
-  MessageKind.INVALID_OVERRIDDEN_GETTER: "INVALID_OVERRIDDEN_GETTER",
-  MessageKind.INVALID_OVERRIDDEN_METHOD: "INVALID_OVERRIDDEN_METHOD",
-  MessageKind.INVALID_OVERRIDDEN_SETTER: "INVALID_OVERRIDDEN_SETTER",
-  MessageKind.INVALID_OVERRIDE_FIELD: "INVALID_OVERRIDE_FIELD",
-  MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
-      "INVALID_OVERRIDE_FIELD_WITH_GETTER",
-  MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
-      "INVALID_OVERRIDE_FIELD_WITH_SETTER",
-  MessageKind.INVALID_OVERRIDE_GETTER: "INVALID_OVERRIDE_GETTER",
-  MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
-      "INVALID_OVERRIDE_GETTER_WITH_FIELD",
-  MessageKind.INVALID_OVERRIDE_METHOD: "INVALID_OVERRIDE_METHOD",
-  MessageKind.INVALID_OVERRIDE_SETTER: "INVALID_OVERRIDE_SETTER",
-  MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
-      "INVALID_OVERRIDE_SETTER_WITH_FIELD",
-  MessageKind.INVALID_PACKAGE_CONFIG: "INVALID_PACKAGE_CONFIG",
-  MessageKind.INVALID_PACKAGE_URI: "INVALID_PACKAGE_URI",
-  MessageKind.INVALID_PARAMETER: "INVALID_PARAMETER",
-  MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
-      "INVALID_RECEIVER_IN_INITIALIZER",
-  MessageKind.INVALID_SOURCE_FILE_LOCATION: "INVALID_SOURCE_FILE_LOCATION",
-  MessageKind.INVALID_SYMBOL: "INVALID_SYMBOL",
-  MessageKind.INVALID_SYNC_MODIFIER: "INVALID_SYNC_MODIFIER",
-  MessageKind.INVALID_TYPE_VARIABLE_BOUND: "INVALID_TYPE_VARIABLE_BOUND",
-  MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
-      "INVALID_UNNAMED_CONSTRUCTOR_NAME",
-  MessageKind.INVALID_URI: "INVALID_URI",
-  MessageKind.INVALID_USE_OF_SUPER: "INVALID_USE_OF_SUPER",
-  MessageKind.INVALID_YIELD: "INVALID_YIELD",
-  MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
-      "JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS",
-  MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
-      "JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER",
-  MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
-      "JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS",
-  MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
-      "JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS",
-  MessageKind.JS_PLACEHOLDER_CAPTURE: "JS_PLACEHOLDER_CAPTURE",
-  MessageKind.LIBRARY_NAME_MISMATCH: "LIBRARY_NAME_MISMATCH",
-  MessageKind.LIBRARY_NOT_FOUND: "LIBRARY_NOT_FOUND",
-  MessageKind.LIBRARY_NOT_SUPPORTED: "LIBRARY_NOT_SUPPORTED",
-  MessageKind.LIBRARY_TAG_MUST_BE_FIRST: "LIBRARY_TAG_MUST_BE_FIRST",
-  MessageKind.MAIN_HAS_PART_OF: "MAIN_HAS_PART_OF",
-  MessageKind.MAIN_NOT_A_FUNCTION: "MAIN_NOT_A_FUNCTION",
-  MessageKind.MAIN_WITH_EXTRA_PARAMETER: "MAIN_WITH_EXTRA_PARAMETER",
-  MessageKind.MALFORMED_STRING_LITERAL: "MALFORMED_STRING_LITERAL",
-  MessageKind.MEMBER_NOT_FOUND: "MEMBER_NOT_FOUND",
-  MessageKind.MEMBER_NOT_STATIC: "MEMBER_NOT_STATIC",
-  MessageKind.MEMBER_USES_CLASS_NAME: "MEMBER_USES_CLASS_NAME",
-  MessageKind.METHOD_NOT_FOUND: "METHOD_NOT_FOUND",
-  MessageKind.MINUS_OPERATOR_BAD_ARITY: "MINUS_OPERATOR_BAD_ARITY",
-  MessageKind.MIRROR_BLOAT: "MIRROR_BLOAT",
-  MessageKind.MIRROR_IMPORT: "MIRROR_IMPORT",
-  MessageKind.MIRROR_IMPORT_NO_USAGE: "MIRROR_IMPORT_NO_USAGE",
-  MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT: "MIRRORS_CANNOT_FIND_IN_ELEMENT",
-  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
-      "MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY",
-  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
-      "MIRRORS_CANNOT_RESOLVE_IN_LIBRARY",
-  MessageKind.MIRRORS_EXPECTED_STRING: "MIRRORS_EXPECTED_STRING",
-  MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
-      "MIRRORS_EXPECTED_STRING_OR_LIST",
-  MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
-      "MIRRORS_EXPECTED_STRING_OR_TYPE",
-  MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
-      "MIRRORS_EXPECTED_STRING_TYPE_OR_LIST",
-  MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
-      "MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND",
-  MessageKind.MISSING_ARGUMENT: "MISSING_ARGUMENT",
-  MessageKind.MISSING_ENUM_CASES: "MISSING_ENUM_CASES",
-  MessageKind.MISSING_FACTORY_KEYWORD: "MISSING_FACTORY_KEYWORD",
-  MessageKind.MISSING_FORMALS: "MISSING_FORMALS",
-  MessageKind.MISSING_LIBRARY_NAME: "MISSING_LIBRARY_NAME",
-  MessageKind.MISSING_MAIN: "MISSING_MAIN",
-  MessageKind.MISSING_PART_OF_TAG: "MISSING_PART_OF_TAG",
-  MessageKind.MISSING_TOKEN_AFTER_THIS: "MISSING_TOKEN_AFTER_THIS",
-  MessageKind.MISSING_TOKEN_BEFORE_THIS: "MISSING_TOKEN_BEFORE_THIS",
-  MessageKind.MISSING_TYPE_ARGUMENT: "MISSING_TYPE_ARGUMENT",
-  MessageKind.MULTI_INHERITANCE: "MULTI_INHERITANCE",
-  MessageKind.NAMED_ARGUMENT_NOT_FOUND: "NAMED_ARGUMENT_NOT_FOUND",
-  MessageKind.NAMED_FUNCTION_EXPRESSION: "NAMED_FUNCTION_EXPRESSION",
-  MessageKind.NAMED_PARAMETER_WITH_EQUALS: "NAMED_PARAMETER_WITH_EQUALS",
-  MessageKind.NATIVE_NOT_SUPPORTED: "NATIVE_NOT_SUPPORTED",
-  MessageKind.NO_BREAK_TARGET: "NO_BREAK_TARGET",
-  MessageKind.NO_CATCH_NOR_FINALLY: "NO_CATCH_NOR_FINALLY",
-  MessageKind.NO_COMMON_SUBTYPES: "NO_COMMON_SUBTYPES",
-  MessageKind.NO_CONTINUE_TARGET: "NO_CONTINUE_TARGET",
-  MessageKind.NO_INSTANCE_AVAILABLE: "NO_INSTANCE_AVAILABLE",
-  MessageKind.NO_MATCHING_CONSTRUCTOR: "NO_MATCHING_CONSTRUCTOR",
-  MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
-      "NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT",
-  MessageKind.NO_STATIC_OVERRIDE: "NO_STATIC_OVERRIDE",
-  MessageKind.NO_STATIC_OVERRIDE_CONT: "NO_STATIC_OVERRIDE_CONT",
-  MessageKind.NO_SUCH_LIBRARY_MEMBER: "NO_SUCH_LIBRARY_MEMBER",
-  MessageKind.NO_SUCH_METHOD_IN_NATIVE: "NO_SUCH_METHOD_IN_NATIVE",
-  MessageKind.NO_SUCH_SUPER_MEMBER: "NO_SUCH_SUPER_MEMBER",
-  MessageKind.NO_SUPER_IN_STATIC: "NO_SUPER_IN_STATIC",
-  MessageKind.NO_THIS_AVAILABLE: "NO_THIS_AVAILABLE",
-  MessageKind.NON_CONST_BLOAT: "NON_CONST_BLOAT",
-  MessageKind.NOT_A_COMPILE_TIME_CONSTANT: "NOT_A_COMPILE_TIME_CONSTANT",
-  MessageKind.NOT_A_FIELD: "NOT_A_FIELD",
-  MessageKind.NOT_A_PREFIX: "NOT_A_PREFIX",
-  MessageKind.NOT_A_TYPE: "NOT_A_TYPE",
-  MessageKind.NOT_ASSIGNABLE: "NOT_ASSIGNABLE",
-  MessageKind.NOT_CALLABLE: "NOT_CALLABLE",
-  MessageKind.NOT_INSTANCE_FIELD: "NOT_INSTANCE_FIELD",
-  MessageKind.NOT_MORE_SPECIFIC: "NOT_MORE_SPECIFIC",
-  MessageKind.NOT_MORE_SPECIFIC_SUBTYPE: "NOT_MORE_SPECIFIC_SUBTYPE",
-  MessageKind.NOT_MORE_SPECIFIC_SUGGESTION: "NOT_MORE_SPECIFIC_SUGGESTION",
-  MessageKind.NULL_NOT_ALLOWED: "NULL_NOT_ALLOWED",
-  MessageKind.ONLY_ONE_LIBRARY_TAG: "ONLY_ONE_LIBRARY_TAG",
-  MessageKind.OPERATOR_NAMED_PARAMETERS: "OPERATOR_NAMED_PARAMETERS",
-  MessageKind.OPERATOR_NOT_FOUND: "OPERATOR_NOT_FOUND",
-  MessageKind.OPERATOR_OPTIONAL_PARAMETERS: "OPERATOR_OPTIONAL_PARAMETERS",
-  MessageKind.OPTIONAL_PARAMETER_IN_CATCH: "OPTIONAL_PARAMETER_IN_CATCH",
-  MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE: "OVERRIDE_EQUALS_NOT_HASH_CODE",
-  MessageKind.PARAMETER_NAME_EXPECTED: "PARAMETER_NAME_EXPECTED",
-  MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
-      "PARAMETER_WITH_MODIFIER_IN_CATCH",
-  MessageKind.PARAMETER_WITH_TYPE_IN_CATCH: "PARAMETER_WITH_TYPE_IN_CATCH",
-  MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
-      "PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION",
-  MessageKind.PATCH_NO_GETTER: "PATCH_NO_GETTER",
-  MessageKind.PATCH_NO_SETTER: "PATCH_NO_SETTER",
-  MessageKind.PATCH_NON_CLASS: "PATCH_NON_CLASS",
-  MessageKind.PATCH_NON_CONSTRUCTOR: "PATCH_NON_CONSTRUCTOR",
-  MessageKind.PATCH_NON_EXISTING: "PATCH_NON_EXISTING",
-  MessageKind.PATCH_NON_EXTERNAL: "PATCH_NON_EXTERNAL",
-  MessageKind.PATCH_NON_FUNCTION: "PATCH_NON_FUNCTION",
-  MessageKind.PATCH_NON_GETTER: "PATCH_NON_GETTER",
-  MessageKind.PATCH_NON_SETTER: "PATCH_NON_SETTER",
-  MessageKind.PATCH_NONPATCHABLE: "PATCH_NONPATCHABLE",
-  MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
-      "PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH",
-  MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
-      "PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH",
-  MessageKind.PATCH_PARAMETER_MISMATCH: "PATCH_PARAMETER_MISMATCH",
-  MessageKind.PATCH_PARAMETER_TYPE_MISMATCH: "PATCH_PARAMETER_TYPE_MISMATCH",
-  MessageKind.PATCH_POINT_TO_CLASS: "PATCH_POINT_TO_CLASS",
-  MessageKind.PATCH_POINT_TO_CONSTRUCTOR: "PATCH_POINT_TO_CONSTRUCTOR",
-  MessageKind.PATCH_POINT_TO_FUNCTION: "PATCH_POINT_TO_FUNCTION",
-  MessageKind.PATCH_POINT_TO_GETTER: "PATCH_POINT_TO_GETTER",
-  MessageKind.PATCH_POINT_TO_PARAMETER: "PATCH_POINT_TO_PARAMETER",
-  MessageKind.PATCH_POINT_TO_SETTER: "PATCH_POINT_TO_SETTER",
-  MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
-      "PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH",
-  MessageKind.PATCH_RETURN_TYPE_MISMATCH: "PATCH_RETURN_TYPE_MISMATCH",
-  MessageKind.PLEASE_REPORT_THE_CRASH: "PLEASE_REPORT_THE_CRASH",
-  MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
-      "POSITIONAL_PARAMETER_WITH_EQUALS",
-  MessageKind.POTENTIAL_MUTATION: "POTENTIAL_MUTATION",
-  MessageKind.POTENTIAL_MUTATION_HERE: "POTENTIAL_MUTATION_HERE",
-  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE: "POTENTIAL_MUTATION_IN_CLOSURE",
-  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
-      "POTENTIAL_MUTATION_IN_CLOSURE_HERE",
-  MessageKind.PREAMBLE: "PREAMBLE",
-  MessageKind.PREFIX_AS_EXPRESSION: "PREFIX_AS_EXPRESSION",
-  MessageKind.PRIVATE_ACCESS: "PRIVATE_ACCESS",
-  MessageKind.PRIVATE_IDENTIFIER: "PRIVATE_IDENTIFIER",
-  MessageKind.PRIVATE_NAMED_PARAMETER: "PRIVATE_NAMED_PARAMETER",
-  MessageKind.READ_SCRIPT_ERROR: "READ_SCRIPT_ERROR",
-  MessageKind.READ_SELF_ERROR: "READ_SELF_ERROR",
-  MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE: "REDIRECTING_CONSTRUCTOR_CYCLE",
-  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
-      "REDIRECTING_CONSTRUCTOR_HAS_BODY",
-  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
-      "REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER",
-  MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
-      "REDIRECTING_FACTORY_WITH_DEFAULT",
-  MessageKind.REFERENCE_IN_INITIALIZATION: "REFERENCE_IN_INITIALIZATION",
-  MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
-      "REQUIRED_PARAMETER_WITH_DEFAULT",
-  MessageKind.RETURN_IN_GENERATOR: "RETURN_IN_GENERATOR",
-  MessageKind.RETURN_NOTHING: "RETURN_NOTHING",
-  MessageKind.RETURN_VALUE_IN_VOID: "RETURN_VALUE_IN_VOID",
-  MessageKind.SETTER_MISMATCH: "SETTER_MISMATCH",
-  MessageKind.SETTER_NOT_FOUND: "SETTER_NOT_FOUND",
-  MessageKind.SETTER_NOT_FOUND_IN_SUPER: "SETTER_NOT_FOUND_IN_SUPER",
-  MessageKind.STATIC_FUNCTION_BLOAT: "STATIC_FUNCTION_BLOAT",
-  MessageKind.STRING_EXPECTED: "STRING_EXPECTED",
-  MessageKind.SUPER_CALL_TO_FACTORY: "SUPER_CALL_TO_FACTORY",
-  MessageKind.SUPER_INITIALIZER_IN_OBJECT: "SUPER_INITIALIZER_IN_OBJECT",
-  MessageKind.SWITCH_CASE_FORBIDDEN: "SWITCH_CASE_FORBIDDEN",
-  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL: "SWITCH_CASE_TYPES_NOT_EQUAL",
-  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
-      "SWITCH_CASE_TYPES_NOT_EQUAL_CASE",
-  MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
-      "SWITCH_CASE_VALUE_OVERRIDES_EQUALS",
-  MessageKind.TERNARY_OPERATOR_BAD_ARITY: "TERNARY_OPERATOR_BAD_ARITY",
-  MessageKind.THIS_CALL_TO_FACTORY: "THIS_CALL_TO_FACTORY",
-  MessageKind.THIS_IS_THE_DECLARATION: "THIS_IS_THE_DECLARATION",
-  MessageKind.THIS_IS_THE_METHOD: "THIS_IS_THE_METHOD",
-  MessageKind.THIS_IS_THE_PART_OF_TAG: "THIS_IS_THE_PART_OF_TAG",
-  MessageKind.THIS_PROPERTY: "THIS_PROPERTY",
-  MessageKind.THROW_WITHOUT_EXPRESSION: "THROW_WITHOUT_EXPRESSION",
-  MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
-      "TOP_LEVEL_VARIABLE_DECLARED_STATIC",
-  MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH: "TYPE_ARGUMENT_COUNT_MISMATCH",
-  MessageKind.TYPE_VARIABLE_IN_CONSTANT: "TYPE_VARIABLE_IN_CONSTANT",
-  MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
-      "TYPE_VARIABLE_WITHIN_STATIC_MEMBER",
-  MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT: "TYPEDEF_FORMAL_WITH_DEFAULT",
-  MessageKind.UNARY_OPERATOR_BAD_ARITY: "UNARY_OPERATOR_BAD_ARITY",
-  MessageKind.UNBOUND_LABEL: "UNBOUND_LABEL",
-  MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER: "UNIMPLEMENTED_EXPLICIT_GETTER",
-  MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER: "UNIMPLEMENTED_EXPLICIT_SETTER",
-  MessageKind.UNIMPLEMENTED_GETTER: "UNIMPLEMENTED_GETTER",
-  MessageKind.UNIMPLEMENTED_GETTER_ONE: "UNIMPLEMENTED_GETTER_ONE",
-  MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER: "UNIMPLEMENTED_IMPLICIT_GETTER",
-  MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER: "UNIMPLEMENTED_IMPLICIT_SETTER",
-  MessageKind.UNIMPLEMENTED_METHOD: "UNIMPLEMENTED_METHOD",
-  MessageKind.UNIMPLEMENTED_METHOD_CONT: "UNIMPLEMENTED_METHOD_CONT",
-  MessageKind.UNIMPLEMENTED_METHOD_ONE: "UNIMPLEMENTED_METHOD_ONE",
-  MessageKind.UNIMPLEMENTED_SETTER: "UNIMPLEMENTED_SETTER",
-  MessageKind.UNIMPLEMENTED_SETTER_ONE: "UNIMPLEMENTED_SETTER_ONE",
-  MessageKind.UNMATCHED_TOKEN: "UNMATCHED_TOKEN",
-  MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
-      "UNRECOGNIZED_VERSION_OF_LOOKUP_MAP",
-  MessageKind.UNSUPPORTED_BANG_EQ_EQ: "UNSUPPORTED_BANG_EQ_EQ",
-  MessageKind.UNSUPPORTED_EQ_EQ_EQ: "UNSUPPORTED_EQ_EQ_EQ",
-  MessageKind.UNSUPPORTED_LITERAL_SYMBOL: "UNSUPPORTED_LITERAL_SYMBOL",
-  MessageKind.UNSUPPORTED_PREFIX_PLUS: "UNSUPPORTED_PREFIX_PLUS",
-  MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP: "UNSUPPORTED_THROW_WITHOUT_EXP",
-  MessageKind.UNTERMINATED_COMMENT: "UNTERMINATED_COMMENT",
-  MessageKind.UNTERMINATED_STRING: "UNTERMINATED_STRING",
-  MessageKind.UNTERMINATED_TOKEN: "UNTERMINATED_TOKEN",
-  MessageKind.UNUSED_CLASS: "UNUSED_CLASS",
-  MessageKind.UNUSED_LABEL: "UNUSED_LABEL",
-  MessageKind.UNUSED_METHOD: "UNUSED_METHOD",
-  MessageKind.UNUSED_TYPEDEF: "UNUSED_TYPEDEF",
-  MessageKind.VAR_FUNCTION_TYPE_PARAMETER: "VAR_FUNCTION_TYPE_PARAMETER",
-  MessageKind.VOID_EXPRESSION: "VOID_EXPRESSION",
-  MessageKind.VOID_NOT_ALLOWED: "VOID_NOT_ALLOWED",
-  MessageKind.VOID_VARIABLE: "VOID_VARIABLE",
-  MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
-      "WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT",
-  MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
-      "WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT",
-  MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
-      "YIELDING_MODIFIER_ON_ARROW_BODY",
-};
-
 /// A message template for an error, warning, hint or info message generated
 /// by the compiler. Each template is associated with a [MessageKind] that
 /// uniquely identifies the message template.
 // TODO(johnnniwinther): For Infos, consider adding a reference to the
 // error/warning/hint that they belong to.
 class MessageTemplate {
-  final MessageKind kind;
-
-  final String id;
+  final dynamic/*MessageKind | SharedMessageKind*/ kind;
 
   /// Should describe what is wrong and why.
   final String template;
@@ -892,8 +498,3176 @@
   /// Additional options needed for the examples to work.
   final List<String> options;
 
-  const MessageTemplate(this.kind, this.id, this.template, this.howToFix,
-      this.examples, this.options);
+  const MessageTemplate(
+      this.kind,
+      this.template,
+      {this.howToFix,
+       this.examples,
+       this.options: const <String>[]});
+
+  /// All templates used by the compiler.
+  ///
+  /// The map is complete mapping from [MessageKind] to their corresponding
+  /// [MessageTemplate].
+  // The key type is a union of MessageKind and SharedMessageKind.
+  static final Map<dynamic, MessageTemplate> TEMPLATES =
+      <dynamic, MessageTemplate>{}
+    ..addAll(shared_messages.TEMPLATES)
+    ..addAll(const<MessageKind, MessageTemplate>{
+      /// Do not use this. It is here for legacy and debugging. It violates item
+      /// 4 of the guide lines for error messages in the beginning of the file.
+      MessageKind.GENERIC:
+        const MessageTemplate(MessageKind.GENERIC, '#{text}'),
+
+      MessageKind.NOT_ASSIGNABLE:
+        const MessageTemplate(MessageKind.NOT_ASSIGNABLE,
+          "'#{fromType}' is not assignable to '#{toType}'."),
+
+      MessageKind.FORIN_NOT_ASSIGNABLE:
+        const MessageTemplate(MessageKind.FORIN_NOT_ASSIGNABLE,
+          "The element type '#{currentType}' of '#{expressionType}' "
+          "is not assignable to '#{elementType}'."),
+
+      MessageKind.VOID_EXPRESSION:
+        const MessageTemplate(MessageKind.VOID_EXPRESSION,
+          "Expression does not yield a value."),
+
+      MessageKind.VOID_VARIABLE:
+        const MessageTemplate(MessageKind.VOID_VARIABLE,
+          "Variable cannot be of type void."),
+
+      MessageKind.RETURN_VALUE_IN_VOID:
+        const MessageTemplate(MessageKind.RETURN_VALUE_IN_VOID,
+          "Cannot return value from void function."),
+
+      MessageKind.RETURN_NOTHING:
+        const MessageTemplate(MessageKind.RETURN_NOTHING,
+          "Value of type '#{returnType}' expected."),
+
+      MessageKind.MISSING_ARGUMENT:
+        const MessageTemplate(MessageKind.MISSING_ARGUMENT,
+          "Missing argument of type '#{argumentType}'."),
+
+      MessageKind.ADDITIONAL_ARGUMENT:
+        const MessageTemplate(MessageKind.ADDITIONAL_ARGUMENT,
+          "Additional argument."),
+
+      MessageKind.NAMED_ARGUMENT_NOT_FOUND:
+        const MessageTemplate(MessageKind.NAMED_ARGUMENT_NOT_FOUND,
+          "No named argument '#{argumentName}' found on method."),
+
+      MessageKind.MEMBER_NOT_FOUND:
+        const MessageTemplate(MessageKind.MEMBER_NOT_FOUND,
+          "No member named '#{memberName}' in class '#{className}'."),
+
+      MessageKind.AWAIT_MEMBER_NOT_FOUND:
+        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND,
+          "No member named 'await' in class '#{className}'.",
+          howToFix: "Did you mean to add the 'async' marker "
+                    "to '#{functionName}'?",
+          examples: const ["""
+class A {
+  m() => await -3;
+}
+main() => new A().m();
+"""]),
+
+      MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
+        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE,
+          "No member named 'await' in class '#{className}'.",
+          howToFix: "Did you mean to add the 'async' marker "
+                    "to the enclosing function?",
+          examples: const ["""
+class A {
+  m() => () => await -3;
+}
+main() => new A().m();
+"""]),
+
+      MessageKind.METHOD_NOT_FOUND:
+        const MessageTemplate(MessageKind.METHOD_NOT_FOUND,
+          "No method named '#{memberName}' in class '#{className}'."),
+
+      MessageKind.OPERATOR_NOT_FOUND:
+        const MessageTemplate(MessageKind.OPERATOR_NOT_FOUND,
+          "No operator '#{memberName}' in class '#{className}'."),
+
+      MessageKind.SETTER_NOT_FOUND:
+        const MessageTemplate(MessageKind.SETTER_NOT_FOUND,
+          "No setter named '#{memberName}' in class '#{className}'."),
+
+      MessageKind.SETTER_NOT_FOUND_IN_SUPER:
+        const MessageTemplate(MessageKind.SETTER_NOT_FOUND_IN_SUPER,
+          "No setter named '#{name}' in superclass of '#{className}'."),
+
+      MessageKind.GETTER_NOT_FOUND:
+        const MessageTemplate(MessageKind.GETTER_NOT_FOUND,
+          "No getter named '#{memberName}' in class '#{className}'."),
+
+      MessageKind.NOT_CALLABLE:
+        const MessageTemplate(MessageKind.NOT_CALLABLE,
+          "'#{elementName}' is not callable."),
+
+      MessageKind.MEMBER_NOT_STATIC:
+        const MessageTemplate(MessageKind.MEMBER_NOT_STATIC,
+          "'#{className}.#{memberName}' is not static."),
+
+      MessageKind.NO_INSTANCE_AVAILABLE:
+        const MessageTemplate(MessageKind.NO_INSTANCE_AVAILABLE,
+          "'#{name}' is only available in instance methods."),
+
+      MessageKind.NO_THIS_AVAILABLE:
+        const MessageTemplate(MessageKind.NO_THIS_AVAILABLE,
+          "'this' is only available in instance methods."),
+
+      MessageKind.PRIVATE_ACCESS:
+        const MessageTemplate(MessageKind.PRIVATE_ACCESS,
+          "'#{name}' is declared private within library "
+          "'#{libraryName}'."),
+
+      MessageKind.THIS_IS_THE_DECLARATION:
+        const MessageTemplate(MessageKind.THIS_IS_THE_DECLARATION,
+          "This is the declaration of '#{name}'."),
+
+      MessageKind.THIS_IS_THE_METHOD:
+        const MessageTemplate(MessageKind.THIS_IS_THE_METHOD,
+          "This is the method declaration."),
+
+      MessageKind.CANNOT_RESOLVE:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE,
+          "Cannot resolve '#{name}'."),
+
+      MessageKind.CANNOT_RESOLVE_AWAIT:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT,
+          "Cannot resolve '#{name}'.",
+          howToFix: "Did you mean to add the 'async' marker "
+                    "to '#{functionName}'?",
+          examples: const [
+              "main() => await -3;",
+              "foo() => await -3; main() => foo();"
+          ]),
+
+      MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE,
+          "Cannot resolve '#{name}'.",
+          howToFix: "Did you mean to add the 'async' marker "
+                    "to the enclosing function?",
+          examples: const [
+              "main() { (() => await -3)(); }",
+          ]),
+
+      MessageKind.CANNOT_RESOLVE_IN_INITIALIZER:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_IN_INITIALIZER,
+          "Cannot resolve '#{name}'. It would be implicitly looked up on this "
+          "instance, but instances are not available in initializers.",
+          howToFix: "Try correcting the unresolved reference or move the "
+              "initialization to a constructor body.",
+          examples: const ["""
+class A {
+  var test = unresolvedName;
+}
+main() => new A();
+"""]),
+
+      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_CONSTRUCTOR,
+          "Cannot resolve constructor '#{constructorName}'."),
+
+      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
+        const MessageTemplate(
+          MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT,
+          "cannot resolve constructor '#{constructorName}' "
+          "for implicit super call.",
+          howToFix: "Try explicitly invoking a constructor of the super class",
+          examples: const ["""
+class A {
+  A.foo() {}
+}
+class B extends A {
+  B();
+}
+main() => new B();
+"""]),
+
+      MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
+        const MessageTemplate(MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
+          "Unnamed constructor name must be '#{name}'."),
+
+      MessageKind.INVALID_CONSTRUCTOR_NAME:
+        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_NAME,
+          "Constructor name must start with '#{name}'."),
+
+      MessageKind.CANNOT_RESOLVE_TYPE:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_TYPE,
+          "Cannot resolve type '#{typeName}'."),
+
+      MessageKind.DUPLICATE_DEFINITION:
+        const MessageTemplate(MessageKind.DUPLICATE_DEFINITION,
+          "Duplicate definition of '#{name}'.",
+          howToFix: "Try to rename or remove this definition.",
+          examples: const ["""
+class C {
+  void f() {}
+  int get f => 1;
+}
+
+main() {
+  new C();
+}
+
+"""]),
+
+      MessageKind.EXISTING_DEFINITION:
+        const MessageTemplate(MessageKind.EXISTING_DEFINITION,
+          "Existing definition of '#{name}'."),
+
+      MessageKind.DUPLICATE_IMPORT:
+        const MessageTemplate(MessageKind.DUPLICATE_IMPORT,
+          "Duplicate import of '#{name}'."),
+
+      MessageKind.HIDDEN_IMPORT:
+        const MessageTemplate(MessageKind.HIDDEN_IMPORT,
+          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+          "from library '#{hidingUri}'.",
+          howToFix:
+            "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
+          examples: const [
+              const {
+'main.dart':
+"""
+import 'dart:async'; // This imports a class Future.
+import 'future.dart';
+
+void main() => new Future();""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}"""},
+
+          const {
+'main.dart':
+"""
+import 'future.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}"""},
+
+          const {
+'main.dart':
+"""
+import 'export.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}""",
+
+'export.dart':
+"""
+library export;
+
+export 'future.dart';"""},
+
+         const {
+'main.dart':
+"""
+import 'future.dart' as prefix;
+import 'dart:async' as prefix; // This imports a class Future.
+
+void main() => new prefix.Future();""",
+
+'future.dart':
+"""
+library future;
+
+class Future {}"""}]),
+
+
+      MessageKind.HIDDEN_IMPLICIT_IMPORT:
+        const MessageTemplate(MessageKind.HIDDEN_IMPLICIT_IMPORT,
+          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+          "from library '#{hidingUri}'.",
+          howToFix: "Try adding an explicit "
+                    "'import \"#{hiddenUri}\" hide #{name}'.",
+          examples: const [
+              const {
+'main.dart':
+"""
+// This hides the implicit import of class Type from dart:core.
+import 'type.dart';
+
+void main() => new Type();""",
+
+'type.dart':
+"""
+library type;
+
+class Type {}"""},
+          const {
+'conflictsWithDart.dart':
+"""
+library conflictsWithDart;
+
+class Duration {
+  static var x = 100;
+}
+""",
+
+'conflictsWithDartAsWell.dart':
+"""
+library conflictsWithDartAsWell;
+
+class Duration {
+  static var x = 100;
+}
+""",
+
+'main.dart':
+r"""
+library testDartConflicts;
+
+import 'conflictsWithDart.dart';
+import 'conflictsWithDartAsWell.dart';
+
+main() {
+  print("Hail Caesar ${Duration.x}");
+}
+"""}]),
+
+      MessageKind.DUPLICATE_EXPORT:
+        const MessageTemplate(MessageKind.DUPLICATE_EXPORT,
+          "Duplicate export of '#{name}'.",
+          howToFix: "Try adding 'hide #{name}' to one of the exports.",
+          examples: const [const {
+'main.dart': """
+export 'decl1.dart';
+export 'decl2.dart';
+
+main() {}""",
+'decl1.dart': "class Class {}",
+'decl2.dart': "class Class {}"}]),
+
+      MessageKind.DUPLICATE_EXPORT_CONT:
+        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_CONT,
+          "This is another export of '#{name}'."),
+
+      MessageKind.DUPLICATE_EXPORT_DECL:
+        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_DECL,
+          "The exported '#{name}' from export #{uriString} is defined here."),
+
+      MessageKind.EMPTY_HIDE:
+        const MessageTemplate(MessageKind.EMPTY_HIDE,
+            "Library '#{uri}' doesn't export a '#{name}' declaration.",
+      howToFix: "Try removing '#{name}' the 'hide' clause.",
+      examples: const [
+        const {
+            'main.dart': """
+import 'dart:core' hide Foo;
+
+main() {}"""},
+        const {
+'main.dart': """
+export 'dart:core' hide Foo;
+
+main() {}"""},
+]),
+
+      MessageKind.EMPTY_SHOW:
+        const MessageTemplate(MessageKind.EMPTY_SHOW,
+            "Library '#{uri}' doesn't export a '#{name}' declaration.",
+      howToFix: "Try removing '#{name}' from the 'show' clause.",
+      examples: const [
+        const {
+            'main.dart': """
+import 'dart:core' show Foo;
+
+main() {}"""},
+        const {
+'main.dart': """
+export 'dart:core' show Foo;
+
+main() {}"""},
+]),
+
+      MessageKind.NOT_A_TYPE:
+        const MessageTemplate(MessageKind.NOT_A_TYPE,
+          "'#{node}' is not a type."),
+
+      MessageKind.NOT_A_PREFIX:
+        const MessageTemplate(MessageKind.NOT_A_PREFIX,
+          "'#{node}' is not a prefix."),
+
+      MessageKind.PREFIX_AS_EXPRESSION:
+        const MessageTemplate(MessageKind.PREFIX_AS_EXPRESSION,
+          "Library prefix '#{prefix}' is not a valid expression."),
+
+      MessageKind.CANNOT_FIND_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.CANNOT_FIND_CONSTRUCTOR,
+          "Cannot find constructor '#{constructorName}' in class "
+          "'#{className}'."),
+
+      MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
+          "Cannot find unnamed constructor in class "
+          "'#{className}'."),
+
+      MessageKind.CYCLIC_CLASS_HIERARCHY:
+        const MessageTemplate(MessageKind.CYCLIC_CLASS_HIERARCHY,
+          "'#{className}' creates a cycle in the class hierarchy."),
+
+      MessageKind.CYCLIC_REDIRECTING_FACTORY:
+        const MessageTemplate(MessageKind.CYCLIC_REDIRECTING_FACTORY,
+          'Redirecting factory leads to a cyclic redirection.'),
+
+      MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
+        const MessageTemplate(MessageKind.INVALID_RECEIVER_IN_INITIALIZER,
+          "Field initializer expected."),
+
+      MessageKind.NO_SUPER_IN_STATIC:
+        const MessageTemplate(MessageKind.NO_SUPER_IN_STATIC,
+          "'super' is only available in instance methods."),
+
+      MessageKind.DUPLICATE_INITIALIZER:
+        const MessageTemplate(MessageKind.DUPLICATE_INITIALIZER,
+          "Field '#{fieldName}' is initialized more than once."),
+
+      MessageKind.ALREADY_INITIALIZED:
+        const MessageTemplate(MessageKind.ALREADY_INITIALIZED,
+          "'#{fieldName}' was already initialized here."),
+
+      MessageKind.INIT_STATIC_FIELD:
+        const MessageTemplate(MessageKind.INIT_STATIC_FIELD,
+          "Cannot initialize static field '#{fieldName}'."),
+
+      MessageKind.NOT_A_FIELD:
+        const MessageTemplate(MessageKind.NOT_A_FIELD,
+          "'#{fieldName}' is not a field."),
+
+      MessageKind.CONSTRUCTOR_CALL_EXPECTED:
+        const MessageTemplate(MessageKind.CONSTRUCTOR_CALL_EXPECTED,
+          "only call to 'this' or 'super' constructor allowed."),
+
+      MessageKind.INVALID_FOR_IN:
+        const MessageTemplate(MessageKind.INVALID_FOR_IN,
+          "Invalid for-in variable declaration."),
+
+      MessageKind.INVALID_INITIALIZER:
+        const MessageTemplate(MessageKind.INVALID_INITIALIZER,
+          "Invalid initializer."),
+
+      MessageKind.FUNCTION_WITH_INITIALIZER:
+        const MessageTemplate(MessageKind.FUNCTION_WITH_INITIALIZER,
+          "Only constructors can have initializers."),
+
+      MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE:
+        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE,
+          "Cyclic constructor redirection."),
+
+      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
+        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY,
+          "Redirecting constructor can't have a body."),
+
+      MessageKind.CONST_CONSTRUCTOR_HAS_BODY:
+        const MessageTemplate(MessageKind.CONST_CONSTRUCTOR_HAS_BODY,
+          "Const constructor or factory can't have a body.",
+          howToFix: "Remove the 'const' keyword or the body",
+          examples: const ["""
+class C {
+  const C() {}
+}
+
+main() => new C();"""]),
+
+      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
+        const MessageTemplate(
+          MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER,
+          "Redirecting constructor cannot have other initializers."),
+
+      MessageKind.SUPER_INITIALIZER_IN_OBJECT:
+        const MessageTemplate(MessageKind.SUPER_INITIALIZER_IN_OBJECT,
+          "'Object' cannot have a super initializer."),
+
+      MessageKind.DUPLICATE_SUPER_INITIALIZER:
+        const MessageTemplate(MessageKind.DUPLICATE_SUPER_INITIALIZER,
+          "Cannot have more than one super initializer."),
+
+      MessageKind.SUPER_CALL_TO_FACTORY:
+        const MessageTemplate(MessageKind.SUPER_CALL_TO_FACTORY,
+          "The target of the superinitializer must be a generative "
+          "constructor.",
+          howToFix: "Try calling another constructor on the superclass.",
+          examples: const ["""
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {}
+main() => new Class();
+""", """
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {
+  Class();
+}
+main() => new Class();
+""", """
+class Super {
+  factory Super() => null;
+}
+class Class extends Super {
+  Class() : super();
+}
+main() => new Class();
+""", """
+class Super {
+  factory Super.foo() => null;
+}
+class Class extends Super {
+  Class() : super.foo();
+}
+main() => new Class();
+"""]),
+
+      MessageKind.THIS_CALL_TO_FACTORY:
+        const MessageTemplate(MessageKind.THIS_CALL_TO_FACTORY,
+          "The target of the redirection clause must be a generative "
+          "constructor",
+        howToFix: "Try redirecting to another constructor.",
+        examples: const ["""
+class Class {
+  factory Class() => null;
+  Class.foo() : this();
+}
+main() => new Class.foo();
+""", """
+class Class {
+  factory Class.foo() => null;
+  Class() : this.foo();
+}
+main() => new Class();
+"""]),
+
+      MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS:
+        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
+          "Arguments do not match the expected parameters of constructor "
+          "'#{constructorName}'."),
+
+      MessageKind.NO_MATCHING_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR,
+          "'super' call arguments and constructor parameters do not match."),
+
+      MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
+        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT,
+              "Implicit 'super' call arguments and constructor parameters "
+              "do not match."),
+
+      MessageKind.CONST_CALLS_NON_CONST:
+        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST,
+          "'const' constructor cannot call a non-const constructor."),
+
+      MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
+        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT,
+              "'const' constructor cannot call a non-const constructor. "
+              "This constructor has an implicit call to a "
+              "super non-const constructor.",
+              howToFix: "Try making the super constructor const.",
+              examples: const ["""
+class C {
+  C(); // missing const
+}
+class D extends C {
+  final d;
+  const D(this.d);
+}
+main() => new D(0);"""]),
+
+      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
+        const MessageTemplate(
+          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
+          "Can't declare constructor 'const' on class #{className} "
+          "because the class contains non-final instance fields.",
+          howToFix: "Try making all fields final.",
+          examples: const ["""
+class C {
+  // 'a' must be declared final to allow for the const constructor.
+  var a;
+  const C(this.a);
+}
+
+main() => new C(0);"""]),
+
+      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
+        const MessageTemplate(
+          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
+          "This non-final field prevents using const constructors."),
+
+      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
+        const MessageTemplate(
+          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
+          "This const constructor is not allowed due to "
+          "non-final fields."),
+
+
+      MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
+        const MessageTemplate(MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED,
+          "Initializing formal parameter only allowed in generative "
+          "constructor."),
+
+      MessageKind.INVALID_PARAMETER:
+        const MessageTemplate(MessageKind.INVALID_PARAMETER,
+          "Cannot resolve parameter."),
+
+      MessageKind.NOT_INSTANCE_FIELD:
+        const MessageTemplate(MessageKind.NOT_INSTANCE_FIELD,
+          "'#{fieldName}' is not an instance field."),
+
+      MessageKind.THIS_PROPERTY:
+        const MessageTemplate(MessageKind.THIS_PROPERTY,
+          "Expected an identifier."),
+
+      MessageKind.NO_CATCH_NOR_FINALLY:
+        const MessageTemplate(MessageKind.NO_CATCH_NOR_FINALLY,
+          "Expected 'catch' or 'finally'."),
+
+      MessageKind.EMPTY_CATCH_DECLARATION:
+        const MessageTemplate(MessageKind.EMPTY_CATCH_DECLARATION,
+          "Expected an identifier in catch declaration."),
+
+      MessageKind.EXTRA_CATCH_DECLARATION:
+        const MessageTemplate(MessageKind.EXTRA_CATCH_DECLARATION,
+          "Extra parameter in catch declaration."),
+
+      MessageKind.PARAMETER_WITH_TYPE_IN_CATCH:
+        const MessageTemplate(MessageKind.PARAMETER_WITH_TYPE_IN_CATCH,
+          "Cannot use type annotations in catch."),
+
+      MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
+        const MessageTemplate(MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH,
+          "Cannot use modifiers in catch."),
+
+      MessageKind.OPTIONAL_PARAMETER_IN_CATCH:
+        const MessageTemplate(MessageKind.OPTIONAL_PARAMETER_IN_CATCH,
+          "Cannot use optional parameters in catch."),
+
+      MessageKind.THROW_WITHOUT_EXPRESSION:
+        const MessageTemplate(MessageKind.THROW_WITHOUT_EXPRESSION,
+          "Cannot use re-throw outside of catch block "
+          "(expression expected after 'throw')."),
+
+      MessageKind.UNBOUND_LABEL:
+        const MessageTemplate(MessageKind.UNBOUND_LABEL,
+          "Cannot resolve label '#{labelName}'."),
+
+      MessageKind.NO_BREAK_TARGET:
+        const MessageTemplate(MessageKind.NO_BREAK_TARGET,
+          "'break' statement not inside switch or loop."),
+
+      MessageKind.NO_CONTINUE_TARGET:
+        const MessageTemplate(MessageKind.NO_CONTINUE_TARGET,
+          "'continue' statement not inside loop."),
+
+      MessageKind.EXISTING_LABEL:
+        const MessageTemplate(MessageKind.EXISTING_LABEL,
+          "Original declaration of duplicate label '#{labelName}'."),
+
+      MessageKind.DUPLICATE_LABEL:
+        const MessageTemplate(MessageKind.DUPLICATE_LABEL,
+          "Duplicate declaration of label '#{labelName}'."),
+
+      MessageKind.UNUSED_LABEL:
+        const MessageTemplate(MessageKind.UNUSED_LABEL,
+          "Unused label '#{labelName}'."),
+
+      MessageKind.INVALID_CONTINUE:
+        const MessageTemplate(MessageKind.INVALID_CONTINUE,
+          "Target of continue is not a loop or switch case."),
+
+      MessageKind.INVALID_BREAK:
+        const MessageTemplate(MessageKind.INVALID_BREAK,
+          "Target of break is not a statement."),
+
+      MessageKind.DUPLICATE_TYPE_VARIABLE_NAME:
+        const MessageTemplate(MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
+          "Type variable '#{typeVariableName}' already declared."),
+
+      MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
+        const MessageTemplate(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
+              "Cannot refer to type variable '#{typeVariableName}' "
+              "within a static member."),
+
+      MessageKind.TYPE_VARIABLE_IN_CONSTANT:
+        const MessageTemplate(MessageKind.TYPE_VARIABLE_IN_CONSTANT,
+          "Constant expressions can't refer to type variables.",
+          howToFix: "Try removing the type variable or replacing it with a "
+                    "concrete type.",
+          examples: const ["""
+class C<T> {
+  const C();
+
+  m(T t) => const C<T>();
+}
+
+void main() => new C().m(null);
+"""
+]),
+
+      MessageKind.INVALID_TYPE_VARIABLE_BOUND:
+        const MessageTemplate(MessageKind.INVALID_TYPE_VARIABLE_BOUND,
+          "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
+          "type variable '#{typeVariable}' of type '#{thisType}'.",
+          howToFix: "Try to change or remove the type argument.",
+          examples: const ["""
+class C<T extends num> {}
+
+// 'String' is not a valid instantiation of T with bound num.'.
+main() => new C<String>();
+"""]),
+
+      MessageKind.INVALID_USE_OF_SUPER:
+        const MessageTemplate(MessageKind.INVALID_USE_OF_SUPER,
+          "'super' not allowed here."),
+
+      MessageKind.INVALID_CASE_DEFAULT:
+        const MessageTemplate(MessageKind.INVALID_CASE_DEFAULT,
+          "'default' only allowed on last case of a switch."),
+
+      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL:
+        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
+          "'case' expressions do not all have type '#{type}'."),
+
+      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
+        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
+          "'case' expression of type '#{type}'."),
+
+      MessageKind.SWITCH_CASE_FORBIDDEN:
+        const MessageTemplate(MessageKind.SWITCH_CASE_FORBIDDEN,
+          "'case' expression may not be of type '#{type}'."),
+
+      MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
+        const MessageTemplate(MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
+              "'case' expression type '#{type}' overrides 'operator =='."),
+
+      MessageKind.INVALID_ARGUMENT_AFTER_NAMED:
+        const MessageTemplate(MessageKind.INVALID_ARGUMENT_AFTER_NAMED,
+          "Unnamed argument after named argument."),
+
+      MessageKind.INVALID_AWAIT_FOR_IN:
+        const MessageTemplate(MessageKind.INVALID_AWAIT_FOR_IN,
+          "'await' is only supported in methods with an 'async' or "
+              "'async*' body modifier.",
+          howToFix: "Try adding 'async' or 'async*' to the method body or "
+              "removing the 'await' keyword.",
+          examples: const [
+            """
+main(o) sync* {
+  await for (var e in o) {}
+}"""]),
+
+      MessageKind.INVALID_AWAIT:
+        const MessageTemplate(MessageKind.INVALID_AWAIT,
+          "'await' is only supported in methods with an 'async' or "
+              "'async*' body modifier.",
+          howToFix: "Try adding 'async' or 'async*' to the method body.",
+          examples: const [
+          """
+main(o) sync* {
+  await null;
+}"""]),
+
+      MessageKind.INVALID_YIELD:
+        const MessageTemplate(MessageKind.INVALID_YIELD,
+          "'yield' is only supported in methods with a 'sync*' or "
+              "'async*' body modifier.",
+          howToFix: "Try adding 'sync*' or 'async*' to the method body.",
+          examples: const [
+            """
+main(o) async {
+  yield 0;
+}"""]),
+
+      MessageKind.NOT_A_COMPILE_TIME_CONSTANT:
+        const MessageTemplate(MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
+          "Not a compile-time constant."),
+
+      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT:
+        const MessageTemplate(MessageKind.DEFERRED_COMPILE_TIME_CONSTANT,
+          "A deferred value cannot be used as a compile-time constant."),
+
+      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
+        const MessageTemplate(
+          MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION,
+          "A deferred class cannot be used to create a "
+          "compile-time constant."),
+
+      MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS:
+        const MessageTemplate(MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS,
+          "Cycle in the compile-time constant computation."),
+
+      MessageKind.CONSTRUCTOR_IS_NOT_CONST:
+        const MessageTemplate(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
+          "Constructor is not a 'const' constructor."),
+
+      MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS:
+        const MessageTemplate(MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
+              "Const-map key type '#{type}' overrides 'operator =='."),
+
+      MessageKind.NO_SUCH_LIBRARY_MEMBER:
+        const MessageTemplate(MessageKind.NO_SUCH_LIBRARY_MEMBER,
+          "'#{libraryName}' has no member named '#{memberName}'."),
+
+      MessageKind.CANNOT_INSTANTIATE_TYPEDEF:
+        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
+          "Cannot instantiate typedef '#{typedefName}'."),
+
+      MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
+        const MessageTemplate(MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT,
+          "Non-optional parameters can't have a default value.",
+          howToFix:
+            "Try removing the default value or making the parameter optional.",
+          examples: const ["""
+main() {
+  foo(a: 1) => print(a);
+  foo(2);
+}""", """
+main() {
+  foo(a = 1) => print(a);
+  foo(2);
+}"""]),
+
+      MessageKind.NAMED_PARAMETER_WITH_EQUALS:
+        const MessageTemplate(MessageKind.NAMED_PARAMETER_WITH_EQUALS,
+          "Named optional parameters can't use '=' to specify a default "
+          "value.",
+          howToFix: "Try replacing '=' with ':'.",
+          examples: const ["""
+main() {
+  foo({a = 1}) => print(a);
+  foo(a: 2);
+}"""]),
+
+      MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
+        const MessageTemplate(MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS,
+          "Positional optional parameters can't use ':' to specify a "
+          "default value.",
+          howToFix: "Try replacing ':' with '='.",
+          examples: const ["""
+main() {
+  foo([a: 1]) => print(a);
+  foo(2);
+}"""]),
+
+      MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT:
+        const MessageTemplate(MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT,
+          "A parameter of a typedef can't specify a default value.",
+          howToFix:
+            "Try removing the default value.",
+          examples: const ["""
+typedef void F([int arg = 0]);
+
+main() {
+  F f;
+}""", """
+typedef void F({int arg: 0});
+
+main() {
+  F f;
+}"""]),
+
+      MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
+        const MessageTemplate(MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT,
+          "A function type parameter can't specify a default value.",
+          howToFix:
+            "Try removing the default value.",
+          examples: const ["""
+foo(f(int i, [a = 1])) {}
+
+main() {
+  foo(1, 2);
+}""", """
+foo(f(int i, {a: 1})) {}
+
+main() {
+  foo(1, a: 2);
+}"""]),
+
+      MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
+        const MessageTemplate(MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT,
+          "A parameter of a redirecting factory constructor can't specify a "
+          "default value.",
+          howToFix:
+            "Try removing the default value.",
+          examples: const ["""
+class A {
+  A([a]);
+  factory A.foo([a = 1]) = A;
+}
+
+main() {
+  new A.foo(1);
+}""", """
+class A {
+  A({a});
+  factory A.foo({a: 1}) = A;
+}
+
+main() {
+  new A.foo(a: 1);
+}"""]),
+
+      MessageKind.FORMAL_DECLARED_CONST:
+        const MessageTemplate(MessageKind.FORMAL_DECLARED_CONST,
+          "A formal parameter can't be declared const.",
+          howToFix: "Try removing 'const'.",
+          examples: const ["""
+foo(const x) {}
+main() => foo(42);
+""", """
+foo({const x}) {}
+main() => foo(42);
+""", """
+foo([const x]) {}
+main() => foo(42);
+"""]),
+
+      MessageKind.FORMAL_DECLARED_STATIC:
+        const MessageTemplate(MessageKind.FORMAL_DECLARED_STATIC,
+          "A formal parameter can't be declared static.",
+          howToFix: "Try removing 'static'.",
+          examples: const ["""
+foo(static x) {}
+main() => foo(42);
+""", """
+foo({static x}) {}
+main() => foo(42);
+""", """
+foo([static x]) {}
+main() => foo(42);
+"""]),
+
+      MessageKind.FINAL_FUNCTION_TYPE_PARAMETER:
+        const MessageTemplate(MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
+          "A function type parameter can't be declared final.",
+          howToFix: "Try removing 'final'.",
+          examples: const ["""
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""]),
+
+      MessageKind.VAR_FUNCTION_TYPE_PARAMETER:
+        const MessageTemplate(MessageKind.VAR_FUNCTION_TYPE_PARAMETER,
+          "A function type parameter can't be declared with 'var'.",
+          howToFix: "Try removing 'var'.",
+          examples: const ["""
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""", """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""", """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""]),
+
+      MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
+        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
+          "Cannot instantiate type variable '#{typeVariableName}'."),
+
+      MessageKind.CYCLIC_TYPE_VARIABLE:
+        const MessageTemplate(MessageKind.CYCLIC_TYPE_VARIABLE,
+          "Type variable '#{typeVariableName}' is a supertype of itself."),
+
+      MessageKind.CYCLIC_TYPEDEF:
+        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF,
+          "A typedef can't refer to itself.",
+          howToFix: "Try removing all references to '#{typedefName}' "
+                    "in the definition of '#{typedefName}'.",
+          examples: const ["""
+typedef F F(); // The return type 'F' is a self-reference.
+main() { F f = null; }"""]),
+
+      MessageKind.CYCLIC_TYPEDEF_ONE:
+        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF_ONE,
+          "A typedef can't refer to itself through another typedef.",
+          howToFix:
+            "Try removing all references to "
+            "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
+          examples: const ["""
+typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
+typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
+main() { F f = null; }""",
+"""
+typedef G F(); // The return type 'G' creates a self-reference.
+typedef H G(); // The return type 'H' creates a self-reference.
+typedef H(F f); // The argument type 'F' creates a self-reference.
+main() { F f = null; }"""]),
+
+      MessageKind.CLASS_NAME_EXPECTED:
+        const MessageTemplate(MessageKind.CLASS_NAME_EXPECTED,
+          "Class name expected."),
+
+      MessageKind.CANNOT_EXTEND:
+        const MessageTemplate(MessageKind.CANNOT_EXTEND,
+          "'#{type}' cannot be extended."),
+
+      MessageKind.CANNOT_IMPLEMENT:
+        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT,
+          "'#{type}' cannot be implemented."),
+
+      // TODO(johnnwinther): Split messages into reasons for malformedness.
+      MessageKind.CANNOT_EXTEND_MALFORMED:
+        const MessageTemplate(MessageKind.CANNOT_EXTEND_MALFORMED,
+          "Class '#{className}' can't extend the type '#{malformedType}' "
+          "because it is malformed.",
+          howToFix:
+            "Try correcting the malformed type annotation or removing the "
+            "'extends' clause.",
+          examples: const ["""
+class A extends Malformed {}
+main() => new A();"""]),
+
+      MessageKind.CANNOT_IMPLEMENT_MALFORMED:
+        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_MALFORMED,
+          "Class '#{className}' can't implement the type '#{malformedType}' "
+          "because it is malformed.",
+          howToFix:
+            "Try correcting the malformed type annotation or removing the "
+            "type from the 'implements' clause.",
+          examples: const ["""
+class A implements Malformed {}
+main() => new A();"""]),
+
+      MessageKind.CANNOT_MIXIN_MALFORMED:
+        const MessageTemplate(MessageKind.CANNOT_MIXIN_MALFORMED,
+          "Class '#{className}' can't mixin the type '#{malformedType}' "
+          "because it is malformed.",
+          howToFix:
+            "Try correcting the malformed type annotation or removing the "
+            "type from the 'with' clause.",
+          examples: const ["""
+class A extends Object with Malformed {}
+main() => new A();"""]),
+
+      MessageKind.CANNOT_MIXIN:
+        const MessageTemplate(MessageKind.CANNOT_MIXIN,
+          "The type '#{type}' can't be mixed in.",
+          howToFix: "Try removing '#{type}' from the 'with' clause.",
+          examples: const ["""
+class C extends Object with String {}
+
+main() => new C();
+""", """
+typedef C = Object with String;
+
+main() => new C();
+"""]),
+
+      MessageKind.CANNOT_EXTEND_ENUM:
+        const MessageTemplate(MessageKind.CANNOT_EXTEND_ENUM,
+          "Class '#{className}' can't extend the type '#{enumType}' because "
+          "it is declared by an enum.",
+          howToFix: "Try making '#{enumType}' a normal class or removing the "
+            "'extends' clause.",
+          examples: const ["""
+enum Enum { A }
+class B extends Enum {}
+main() => new B();"""]),
+
+      MessageKind.CANNOT_IMPLEMENT_ENUM:
+        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_ENUM,
+          "Class '#{className}' can't implement the type '#{enumType}' "
+          "because it is declared by an enum.",
+          howToFix: "Try making '#{enumType}' a normal class or removing the "
+            "type from the 'implements' clause.",
+          examples: const ["""
+enum Enum { A }
+class B implements Enum {}
+main() => new B();"""]),
+
+      MessageKind.CANNOT_MIXIN_ENUM:
+        const MessageTemplate(MessageKind.CANNOT_MIXIN_ENUM,
+          "Class '#{className}' can't mixin the type '#{enumType}' because it "
+          "is declared by an enum.",
+          howToFix: "Try making '#{enumType}' a normal class or removing the "
+            "type from the 'with' clause.",
+          examples: const ["""
+enum Enum { A }
+class B extends Object with Enum {}
+main() => new B();"""]),
+
+      MessageKind.CANNOT_INSTANTIATE_ENUM:
+        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_ENUM,
+          "Enum type '#{enumName}' cannot be instantiated.",
+          howToFix: "Try making '#{enumType}' a normal class or use an enum "
+                    "constant.",
+          examples: const ["""
+enum Enum { A }
+main() => new Enum(0);""", """
+enum Enum { A }
+main() => const Enum(0);"""]),
+
+      MessageKind.EMPTY_ENUM_DECLARATION:
+        const MessageTemplate(MessageKind.EMPTY_ENUM_DECLARATION,
+          "Enum '#{enumName}' must contain at least one value.",
+          howToFix: "Try adding an enum constant or making #{enumName} a "
+                    "normal class.",
+          examples: const ["""
+enum Enum {}
+main() { Enum e; }"""]),
+
+      MessageKind.MISSING_ENUM_CASES:
+        const MessageTemplate(MessageKind.MISSING_ENUM_CASES,
+          "Missing enum constants in switch statement: #{enumValues}.",
+          howToFix: "Try adding the missing constants or a default case.",
+          examples: const ["""
+enum Enum { A, B }
+main() {
+  switch (Enum.A) {
+  case Enum.B: break;
+  }
+}""", """
+enum Enum { A, B, C }
+main() {
+  switch (Enum.A) {
+  case Enum.B: break;
+  }
+}"""]),
+
+      MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS:
+        const MessageTemplate(MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
+          "'#{type}' can not be both extended and implemented."),
+
+      MessageKind.DUPLICATE_IMPLEMENTS:
+        const MessageTemplate(MessageKind.DUPLICATE_IMPLEMENTS,
+          "'#{type}' must not occur more than once "
+          "in the implements clause."),
+
+      MessageKind.MULTI_INHERITANCE:
+        const MessageTemplate(MessageKind.MULTI_INHERITANCE,
+          "Dart2js does not currently support inheritance of the same class "
+          "with different type arguments: Both #{firstType} and #{secondType} "
+          "are supertypes of #{thisType}."),
+
+      MessageKind.ILLEGAL_SUPER_SEND:
+        const MessageTemplate(MessageKind.ILLEGAL_SUPER_SEND,
+          "'#{name}' cannot be called on super."),
+
+      MessageKind.NO_SUCH_SUPER_MEMBER:
+        const MessageTemplate(MessageKind.NO_SUCH_SUPER_MEMBER,
+          "Cannot resolve '#{memberName}' in a superclass of '#{className}'."),
+
+      MessageKind.ADDITIONAL_TYPE_ARGUMENT:
+        const MessageTemplate(MessageKind.ADDITIONAL_TYPE_ARGUMENT,
+          "Additional type argument."),
+
+      MessageKind.MISSING_TYPE_ARGUMENT:
+        const MessageTemplate(MessageKind.MISSING_TYPE_ARGUMENT,
+          "Missing type argument."),
+
+      // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
+      // MISSING_TYPE_ARGUMENT instead.
+      MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH:
+        const MessageTemplate(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
+          "Incorrect number of type arguments on '#{type}'."),
+
+      MessageKind.GETTER_MISMATCH:
+        const MessageTemplate(MessageKind.GETTER_MISMATCH,
+          "Setter disagrees on: '#{modifiers}'."),
+
+      MessageKind.SETTER_MISMATCH:
+        const MessageTemplate(MessageKind.SETTER_MISMATCH,
+          "Getter disagrees on: '#{modifiers}'."),
+
+      MessageKind.ILLEGAL_SETTER_FORMALS:
+        const MessageTemplate(MessageKind.ILLEGAL_SETTER_FORMALS,
+          "A setter must have exactly one argument."),
+
+      MessageKind.NO_STATIC_OVERRIDE:
+        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE,
+          "Static member cannot override instance member '#{memberName}' of "
+          "'#{className}'."),
+
+      MessageKind.NO_STATIC_OVERRIDE_CONT:
+        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE_CONT,
+          "This is the instance member that cannot be overridden "
+          "by a static member."),
+
+      MessageKind.INSTANCE_STATIC_SAME_NAME:
+        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME,
+          "Instance member '#{memberName}' and static member of "
+          "superclass '#{className}' have the same name."),
+
+      MessageKind.INSTANCE_STATIC_SAME_NAME_CONT:
+        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME_CONT,
+          "This is the static member with the same name."),
+
+      MessageKind.INVALID_OVERRIDE_METHOD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_METHOD,
+          "The type '#{declaredType}' of method '#{name}' declared in "
+          "'#{class}' is not a subtype of the overridden method type "
+          "'#{inheritedType}' inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDDEN_METHOD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_METHOD,
+          "This is the overridden method '#{name}' declared in class "
+          "'#{class}'."),
+
+      MessageKind.INVALID_OVERRIDE_GETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER,
+          "The type '#{declaredType}' of getter '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden getter inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDDEN_GETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_GETTER,
+          "This is the overridden getter '#{name}' declared in class "
+          "'#{class}'."),
+
+      MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
+          "The type '#{declaredType}' of field '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden getter inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
+          "The type '#{declaredType}' of getter '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden field inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDE_SETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER,
+          "The type '#{declaredType}' of setter '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden setter inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDDEN_SETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_SETTER,
+          "This is the overridden setter '#{name}' declared in class "
+          "'#{class}'."),
+
+      MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
+          "The type '#{declaredType}' of field '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden setter inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
+          "The type '#{declaredType}' of setter '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden field inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDE_FIELD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD,
+          "The type '#{declaredType}' of field '#{name}' declared in "
+          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+          "overridden field inherited from '#{inheritedClass}'."),
+
+      MessageKind.INVALID_OVERRIDDEN_FIELD:
+        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_FIELD,
+          "This is the overridden field '#{name}' declared in class "
+          "'#{class}'."),
+
+      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
+        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
+          "Method '#{name}' in '#{class}' can't override field from "
+          "'#{inheritedClass}'."),
+
+      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
+        const MessageTemplate(
+          MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT,
+          "This is the field that cannot be overridden by a method."),
+
+      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
+        const MessageTemplate(
+          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
+          "Field '#{name}' in '#{class}' can't override method from "
+          "'#{inheritedClass}'."),
+
+      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
+        const MessageTemplate(
+          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT,
+          "This is the method that cannot be overridden by a field."),
+
+      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
+        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
+              "Method '#{name}' in '#{class}' can't override getter from "
+              "'#{inheritedClass}'."),
+
+      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
+        const MessageTemplate(
+          MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT,
+          "This is the getter that cannot be overridden by a method."),
+
+      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
+        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
+          "Getter '#{name}' in '#{class}' can't override method from "
+          "'#{inheritedClass}'."),
+
+      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
+        const MessageTemplate(
+          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT,
+          "This is the method that cannot be overridden by a getter."),
+
+      MessageKind.MISSING_FORMALS:
+        const MessageTemplate(MessageKind.MISSING_FORMALS,
+          "Formal parameters are missing."),
+
+      MessageKind.EXTRA_FORMALS:
+        const MessageTemplate(MessageKind.EXTRA_FORMALS,
+          "Formal parameters are not allowed here."),
+
+      MessageKind.UNARY_OPERATOR_BAD_ARITY:
+        const MessageTemplate(MessageKind.UNARY_OPERATOR_BAD_ARITY,
+          "Operator '#{operatorName}' must have no parameters."),
+
+      MessageKind.MINUS_OPERATOR_BAD_ARITY:
+        const MessageTemplate(MessageKind.MINUS_OPERATOR_BAD_ARITY,
+          "Operator '-' must have 0 or 1 parameters."),
+
+      MessageKind.BINARY_OPERATOR_BAD_ARITY:
+        const MessageTemplate(MessageKind.BINARY_OPERATOR_BAD_ARITY,
+          "Operator '#{operatorName}' must have exactly 1 parameter."),
+
+      MessageKind.TERNARY_OPERATOR_BAD_ARITY:
+        const MessageTemplate(MessageKind.TERNARY_OPERATOR_BAD_ARITY,
+          "Operator '#{operatorName}' must have exactly 2 parameters."),
+
+      MessageKind.OPERATOR_OPTIONAL_PARAMETERS:
+        const MessageTemplate(MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
+          "Operator '#{operatorName}' cannot have optional parameters."),
+
+      MessageKind.OPERATOR_NAMED_PARAMETERS:
+        const MessageTemplate(MessageKind.OPERATOR_NAMED_PARAMETERS,
+          "Operator '#{operatorName}' cannot have named parameters."),
+
+      MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE:
+        const MessageTemplate(MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
+          "Cannot have return type for constructor."),
+
+      MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR,
+          "Constructors can't return values.",
+          howToFix: "Remove the return statement or use a factory constructor.",
+          examples: const ["""
+class C {
+  C() {
+    return 1;
+  }
+}
+
+main() => new C();"""]),
+
+      MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER:
+        const MessageTemplate(MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER,
+          "Cannot have final modifier on method."),
+
+      MessageKind.ILLEGAL_CONST_FIELD_MODIFIER:
+        const MessageTemplate(MessageKind.ILLEGAL_CONST_FIELD_MODIFIER,
+          "Cannot have const modifier on non-static field.",
+          howToFix:
+            "Try adding a static modifier, or removing the const modifier.",
+          examples: const ["""
+class C {
+  const int a = 1;
+}
+
+main() => new C();"""]),
+
+      MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS:
+        const MessageTemplate(MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
+          "Illegal constructor modifiers: '#{modifiers}'."),
+
+      MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
+              "Illegal mixin application modifiers: '#{modifiers}'."),
+
+      MessageKind.ILLEGAL_MIXIN_SUPERCLASS:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPERCLASS,
+          "Class used as mixin must have Object as superclass."),
+
+      MessageKind.ILLEGAL_MIXIN_OBJECT:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_OBJECT,
+          "Cannot use Object as mixin."),
+
+      MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR,
+          "Class used as mixin cannot have non-factory constructor."),
+
+      MessageKind.ILLEGAL_MIXIN_CYCLE:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CYCLE,
+          "Class used as mixin introduces mixin cycle: "
+          "'#{mixinName1}' <-> '#{mixinName2}'."),
+
+      MessageKind.ILLEGAL_MIXIN_WITH_SUPER:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
+          "Cannot use class '#{className}' as a mixin because it uses "
+          "'super'."),
+
+      MessageKind.ILLEGAL_MIXIN_SUPER_USE:
+        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPER_USE,
+          "Use of 'super' in class used as mixin."),
+
+      MessageKind.PARAMETER_NAME_EXPECTED:
+        const MessageTemplate(MessageKind.PARAMETER_NAME_EXPECTED,
+          "parameter name expected."),
+
+      MessageKind.CANNOT_RESOLVE_GETTER:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_GETTER,
+          "Cannot resolve getter."),
+
+      MessageKind.CANNOT_RESOLVE_SETTER:
+        const MessageTemplate(MessageKind.CANNOT_RESOLVE_SETTER,
+          "Cannot resolve setter."),
+
+      MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER:
+        const MessageTemplate(MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
+          "Cannot assign a value to final field '#{name}' "
+          "in superclass '#{superclassName}'."),
+
+      MessageKind.ASSIGNING_METHOD:
+        const MessageTemplate(MessageKind.ASSIGNING_METHOD,
+          "Cannot assign a value to a method."),
+
+      MessageKind.ASSIGNING_METHOD_IN_SUPER:
+        const MessageTemplate(MessageKind.ASSIGNING_METHOD_IN_SUPER,
+          "Cannot assign a value to method '#{name}' "
+          "in superclass '#{superclassName}'."),
+
+      MessageKind.ASSIGNING_TYPE:
+        const MessageTemplate(MessageKind.ASSIGNING_TYPE,
+          "Cannot assign a value to a type."),
+
+      MessageKind.IF_NULL_ASSIGNING_TYPE:
+        const MessageTemplate(MessageKind.IF_NULL_ASSIGNING_TYPE,
+          "Cannot assign a value to a type. Note that types are never null, "
+          "so this ??= assignment has no effect.",
+          howToFix: "Try removing the '??=' assignment.",
+          examples: const [
+              "class A {} main() { print(A ??= 3);}",
+          ]),
+
+      MessageKind.VOID_NOT_ALLOWED:
+        const MessageTemplate(MessageKind.VOID_NOT_ALLOWED,
+          "Type 'void' can't be used here because it isn't a return type.",
+          howToFix:
+            "Try removing 'void' keyword or replace it with 'var', 'final', "
+            "or a type.",
+          examples: const [
+              "void x; main() {}",
+              "foo(void x) {} main() { foo(null); }",
+          ]),
+
+      MessageKind.NULL_NOT_ALLOWED:
+        const MessageTemplate(MessageKind.NULL_NOT_ALLOWED,
+          "`null` can't be used here."),
+
+      MessageKind.BEFORE_TOP_LEVEL:
+        const MessageTemplate(MessageKind.BEFORE_TOP_LEVEL,
+          "Part header must come before top-level definitions."),
+
+      MessageKind.IMPORT_PART_OF:
+        const MessageTemplate(MessageKind.IMPORT_PART_OF,
+          "The imported library must not have a 'part-of' directive.",
+          howToFix: "Try removing the 'part-of' directive or replacing the "
+                    "import of the library with a 'part' directive.",
+          examples: const [const {
+'main.dart': """
+library library;
+
+import 'part.dart';
+
+main() {}
+""",
+
+'part.dart': """
+part of library;
+"""}]),
+
+      MessageKind.IMPORT_PART_OF_HERE:
+        const MessageTemplate(MessageKind.IMPORT_PART_OF_HERE,
+          "The library is imported here."),
+
+      MessageKind.MAIN_HAS_PART_OF:
+        const MessageTemplate(MessageKind.MAIN_HAS_PART_OF,
+          "The main application file must not have a 'part-of' directive.",
+          howToFix:  "Try removing the 'part-of' directive or starting "
+              "compilation from another file.",
+          examples: const [const {
+'main.dart': """
+part of library;
+
+main() {}
+"""}]),
+
+      MessageKind.LIBRARY_NAME_MISMATCH:
+        const MessageTemplate(MessageKind.LIBRARY_NAME_MISMATCH,
+          "Expected part of library name '#{libraryName}'.",
+          howToFix: "Try changing the directive to 'part of #{libraryName};'.",
+          examples: const [const {
+'main.dart': """
+library lib.foo;
+
+part 'part.dart';
+
+main() {}
+""",
+
+'part.dart': """
+part of lib.bar;
+"""}]),
+
+      MessageKind.MISSING_LIBRARY_NAME:
+        const MessageTemplate(MessageKind.MISSING_LIBRARY_NAME,
+          "Library has no name. Part directive expected library name "
+          "to be '#{libraryName}'.",
+          howToFix: "Try adding 'library #{libraryName};' to the library.",
+          examples: const [const {
+'main.dart': """
+part 'part.dart';
+
+main() {}
+""",
+
+'part.dart': """
+part of lib.foo;
+"""}]),
+
+      MessageKind.THIS_IS_THE_PART_OF_TAG:
+        const MessageTemplate(MessageKind.THIS_IS_THE_PART_OF_TAG,
+          "This is the part of directive."),
+
+      MessageKind.MISSING_PART_OF_TAG:
+        const MessageTemplate(MessageKind.MISSING_PART_OF_TAG,
+          "This file has no part-of tag, but it is being used as a part."),
+
+      MessageKind.DUPLICATED_PART_OF:
+        const MessageTemplate(MessageKind.DUPLICATED_PART_OF,
+          "Duplicated part-of directive."),
+
+      MessageKind.DUPLICATED_LIBRARY_NAME:
+        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_NAME,
+          "Duplicated library name '#{libraryName}'."),
+
+      MessageKind.DUPLICATED_RESOURCE:
+        const MessageTemplate(MessageKind.DUPLICATED_RESOURCE,
+          "The resource '#{resourceUri}' is loaded through both "
+          "'#{canonicalUri1}' and '#{canonicalUri2}'."),
+
+      MessageKind.DUPLICATED_LIBRARY_RESOURCE:
+        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_RESOURCE,
+          "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
+          "both '#{canonicalUri1}' and '#{canonicalUri2}'."),
+
+      // This is used as an exception.
+      MessageKind.INVALID_SOURCE_FILE_LOCATION:
+        const MessageTemplate(MessageKind.INVALID_SOURCE_FILE_LOCATION, '''
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}'''),
+
+      MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
+        const MessageTemplate(MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC,
+              "Top-level variable cannot be declared static."),
+
+      MessageKind.REFERENCE_IN_INITIALIZATION:
+        const MessageTemplate(MessageKind.REFERENCE_IN_INITIALIZATION,
+           "Variable '#{variableName}' is referenced during its "
+           "initialization.",
+           howToFix:
+             "If you are trying to reference a shadowed variable, rename "
+             "one of the variables.",
+           examples: const ["""
+foo(t) {
+  var t = t;
+  return t;
+}
+
+main() => foo(1);
+"""]),
+
+      MessageKind.CONST_WITHOUT_INITIALIZER:
+        const MessageTemplate(MessageKind.CONST_WITHOUT_INITIALIZER,
+          "A constant variable must be initialized.",
+          howToFix: "Try adding an initializer or "
+                    "removing the 'const' modifier.",
+          examples: const ["""
+void main() {
+  const c; // This constant variable must be initialized.
+}"""]),
+
+      MessageKind.FINAL_WITHOUT_INITIALIZER:
+        const MessageTemplate(MessageKind.FINAL_WITHOUT_INITIALIZER,
+          "A final variable must be initialized.",
+          howToFix: "Try adding an initializer or "
+                    "removing the 'final' modifier.",
+          examples: const [
+              "class C { static final field; } main() => C.field;"]),
+
+      MessageKind.CONST_LOOP_VARIABLE:
+        const MessageTemplate(MessageKind.CONST_LOOP_VARIABLE,
+          "A loop variable cannot be constant.",
+          howToFix: "Try remove the 'const' modifier or "
+                    "replacing it with a 'final' modifier.",
+          examples: const ["""
+void main() {
+  for (const c in []) {}
+}"""]),
+
+      MessageKind.MEMBER_USES_CLASS_NAME:
+        const MessageTemplate(MessageKind.MEMBER_USES_CLASS_NAME,
+          "Member variable can't have the same name as the class it is "
+          "declared in.",
+          howToFix: "Try renaming the variable.",
+          examples: const ["""
+class A { var A; }
+main() {
+  var a = new A();
+  a.A = 1;
+}
+""", """
+class A { static var A; }
+main() => A.A = 1;
+"""]),
+
+      MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
+        const MessageTemplate(
+          MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
+          "Wrong number of arguments to assert. Should be 1, but given "
+          "#{argumentCount}."),
+
+      MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
+        const MessageTemplate(MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
+          "'assert' takes no named arguments, but given #{argumentCount}."),
+
+      MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
+        const MessageTemplate(MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY,
+          "Factory redirection only allowed in factories."),
+
+      MessageKind.MISSING_FACTORY_KEYWORD:
+        const MessageTemplate(MessageKind.MISSING_FACTORY_KEYWORD,
+          "Did you forget a factory keyword here?"),
+
+      MessageKind.NO_SUCH_METHOD_IN_NATIVE:
+        const MessageTemplate(MessageKind.NO_SUCH_METHOD_IN_NATIVE,
+          "'NoSuchMethod' is not supported for classes that extend native "
+          "classes."),
+
+      MessageKind.DEFERRED_LIBRARY_DART_2_DART:
+        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DART_2_DART,
+          "Deferred loading is not supported by the dart backend yet. "
+          "The output will not be split."),
+
+      MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
+        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX,
+          "This import is deferred but there is no prefix keyword.",
+          howToFix: "Try adding a prefix to the import."),
+
+      MessageKind.DEFERRED_OLD_SYNTAX:
+        const MessageTemplate(MessageKind.DEFERRED_OLD_SYNTAX,
+          "The DeferredLibrary annotation is obsolete.",
+          howToFix:
+            "Use the \"import 'lib.dart' deferred as prefix\" syntax instead."),
+
+      MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
+        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX,
+          "The prefix of this deferred import is not unique.",
+          howToFix: "Try changing the import prefix."),
+
+      MessageKind.DEFERRED_TYPE_ANNOTATION:
+        const MessageTemplate(MessageKind.DEFERRED_TYPE_ANNOTATION,
+          "The type #{node} is deferred. "
+          "Deferred types are not valid as type annotations.",
+          howToFix:
+            "Try using a non-deferred abstract class as an interface."),
+
+      MessageKind.ILLEGAL_STATIC:
+        const MessageTemplate(MessageKind.ILLEGAL_STATIC,
+          "Modifier static is only allowed on functions declared in "
+          "a class."),
+
+      MessageKind.STATIC_FUNCTION_BLOAT:
+        const MessageTemplate(MessageKind.STATIC_FUNCTION_BLOAT,
+          "Using '#{class}.#{name}' may lead to unnecessarily large "
+          "generated code.",
+          howToFix:
+              "Try adding '@MirrorsUsed(...)' as described at "
+              "https://goo.gl/Akrrog."),
+
+      MessageKind.NON_CONST_BLOAT:
+        const MessageTemplate(MessageKind.NON_CONST_BLOAT,
+          "Using 'new #{name}' may lead to unnecessarily large generated "
+          "code.",
+          howToFix:
+              "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
+              "described at https://goo.gl/Akrrog."),
+
+      MessageKind.STRING_EXPECTED:
+        const MessageTemplate(MessageKind.STRING_EXPECTED,
+          "Expected a 'String', but got an instance of '#{type}'."),
+
+      MessageKind.PRIVATE_IDENTIFIER:
+        const MessageTemplate(MessageKind.PRIVATE_IDENTIFIER,
+          "'#{value}' is not a valid Symbol name because it starts with "
+          "'_'."),
+
+      MessageKind.PRIVATE_NAMED_PARAMETER:
+        const MessageTemplate(MessageKind.PRIVATE_NAMED_PARAMETER,
+          "Named optional parameter can't have a library private name.",
+          howToFix:
+            "Try removing the '_' or making the parameter positional or "
+            "required.",
+          examples: const ["""foo({int _p}) {} main() => foo();"""]),
+
+      MessageKind.UNSUPPORTED_LITERAL_SYMBOL:
+        const MessageTemplate(MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
+          "Symbol literal '##{value}' is currently unsupported by dart2js."),
+
+      MessageKind.INVALID_SYMBOL:
+        const MessageTemplate(MessageKind.INVALID_SYMBOL, '''
+'#{value}' is not a valid Symbol name because is not:
+ * an empty String,
+ * a user defined operator,
+ * a qualified non-private identifier optionally followed by '=', or
+ * a qualified non-private identifier followed by '.' and a user-defined '''
+"operator."),
+
+      MessageKind.AMBIGUOUS_REEXPORT:
+        const MessageTemplate(MessageKind.AMBIGUOUS_REEXPORT,
+          "'#{name}' is (re)exported by multiple libraries."),
+
+      MessageKind.AMBIGUOUS_LOCATION:
+        const MessageTemplate(MessageKind.AMBIGUOUS_LOCATION,
+          "'#{name}' is defined here."),
+
+      MessageKind.IMPORTED_HERE:
+        const MessageTemplate(MessageKind.IMPORTED_HERE,
+          "'#{name}' is imported here."),
+
+      MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE:
+        const MessageTemplate(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
+          "The class '#{class}' overrides 'operator==', "
+          "but not 'get hashCode'."),
+
+      MessageKind.INTERNAL_LIBRARY_FROM:
+        const MessageTemplate(MessageKind.INTERNAL_LIBRARY_FROM,
+          "Internal library '#{resolvedUri}' is not accessible from "
+          "'#{importingUri}'."),
+
+      MessageKind.INTERNAL_LIBRARY:
+        const MessageTemplate(MessageKind.INTERNAL_LIBRARY,
+          "Internal library '#{resolvedUri}' is not accessible."),
+
+      MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
+        const MessageTemplate(
+          MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
+          "Js-interop class '#{cls}' cannot extend from the non js-interop "
+          "class '#{superclass}'.",
+          howToFix: "Annotate the superclass with @JS.",
+          examples: const [
+              """
+              import 'package:js/js.dart';
+
+              class Foo { }
+
+              @JS()
+              class Bar extends Foo { }
+
+              main() {
+                new Bar();
+              }
+              """]),
+
+      MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
+        const MessageTemplate(
+          MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
+          "Member '#{member}' in js-interop class '#{cls}' is not external.",
+          howToFix: "Mark all interop methods external",
+          examples: const [
+              """
+              import 'package:js/js.dart';
+
+              @JS()
+              class Foo {
+                bar() {}
+              }
+
+              main() {
+                new Foo().bar();
+              }
+              """]),
+
+      MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
+        const MessageTemplate(
+          MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
+          "Js-interop method '#{method}' has named arguments but is not "
+          "a factory constructor of an @anonymous @JS class.",
+          howToFix: "Remove all named arguments from js-interop method or "
+                    "in the case of a factory constructor annotate the class "
+                    "as @anonymous.",
+          examples: const [
+              """
+              import 'package:js/js.dart';
+
+              @JS()
+              class Foo {
+                external bar(foo, {baz});
+              }
+
+              main() {
+                new Foo().bar(4, baz: 5);
+              }
+              """]),
+
+      MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
+        const MessageTemplate(
+          MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
+          "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
+          "object literal constructor is positional instead of named."
+          ".",
+          howToFix: "Make all arguments in external factory object literal "
+                    "constructors named.",
+          examples: const [
+              """
+              import 'package:js/js.dart';
+
+              @anonymous
+              @JS()
+              class Foo {
+                external factory Foo(foo, {baz});
+              }
+
+              main() {
+                new Foo(5, baz: 5);
+              }
+              """]),
+
+      MessageKind.LIBRARY_NOT_FOUND:
+        const MessageTemplate(MessageKind.LIBRARY_NOT_FOUND,
+          "Library not found '#{resolvedUri}'."),
+
+      MessageKind.LIBRARY_NOT_SUPPORTED:
+        const MessageTemplate(MessageKind.LIBRARY_NOT_SUPPORTED,
+          "Library not supported '#{resolvedUri}'.",
+          howToFix: "Try removing the dependency or enabling support using "
+                    "the '--categories' option.",
+          examples: const [/*
+              """
+              import 'dart:io';
+              main() {}
+              """
+          */]),
+          // TODO(johnniwinther): Enable example when message_kind_test.dart
+          // supports library loader callbacks.
+
+      MessageKind.UNSUPPORTED_EQ_EQ_EQ:
+        const MessageTemplate(MessageKind.UNSUPPORTED_EQ_EQ_EQ,
+          "'===' is not an operator. "
+          "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?"),
+
+      MessageKind.UNSUPPORTED_BANG_EQ_EQ:
+        const MessageTemplate(MessageKind.UNSUPPORTED_BANG_EQ_EQ,
+          "'!==' is not an operator. "
+          "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?"),
+
+      MessageKind.UNSUPPORTED_PREFIX_PLUS:
+        const MessageTemplate(MessageKind.UNSUPPORTED_PREFIX_PLUS,
+          "'+' is not a prefix operator. ",
+          howToFix: "Try removing '+'.",
+          examples: const [
+              "main() => +2;  // No longer a valid way to write '2'"
+          ]),
+
+      MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP:
+        const MessageTemplate(MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP,
+          "No expression after 'throw'. "
+          "Did you mean 'rethrow'?"),
+
+      MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
+        const MessageTemplate(MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX,
+          "'typedef' not allowed here. ",
+          howToFix: "Try replacing 'typedef' with 'class'.",
+          examples: const [
+              """
+class B { }
+class M1 {  }
+typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
+main() { new C(); }
+"""]),
+
+      MessageKind.MIRRORS_EXPECTED_STRING:
+        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING,
+          "Can't use '#{name}' here because it's an instance of '#{type}' "
+          "and a 'String' value is expected.",
+          howToFix: "Did you forget to add quotes?",
+          examples: const [
+              """
+// 'Foo' is a type literal, not a string.
+@MirrorsUsed(symbols: const [Foo])
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
+        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE,
+          "Can't use '#{name}' here because it's an instance of '#{type}' "
+          "and a 'String' or 'Type' value is expected.",
+          howToFix: "Did you forget to add quotes?",
+          examples: const [
+              """
+// 'main' is a method, not a class.
+@MirrorsUsed(targets: const [main])
+import 'dart:mirrors';
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
+        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST,
+          "Can't use '#{name}' here because it's an instance of '#{type}' "
+          "and a 'String' or 'List' value is expected.",
+          howToFix: "Did you forget to add quotes?",
+          examples: const [
+              """
+// 'Foo' is not a string.
+@MirrorsUsed(symbols: Foo)
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
+        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST,
+          "Can't use '#{name}' here because it's an instance of '#{type}' "
+          "but a 'String', 'Type', or 'List' value is expected.",
+          howToFix: "Did you forget to add quotes?",
+          examples: const [
+              """
+// '1' is not a string.
+@MirrorsUsed(targets: 1)
+import 'dart:mirrors';
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
+        const MessageTemplate(
+          MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
+          "Can't find '#{name}' in the current library.",
+          // TODO(ahe): The closest identifiers in edit distance would be nice.
+          howToFix: "Did you forget to add an import?",
+          examples: const [
+              """
+// 'window' is not in scope because dart:html isn't imported.
+@MirrorsUsed(targets: 'window')
+import 'dart:mirrors';
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
+        const MessageTemplate(MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
+          "Can't find '#{name}' in the library '#{library}'.",
+          // TODO(ahe): The closest identifiers in edit distance would be nice.
+          howToFix: "Is '#{name}' spelled right?",
+          examples: const [
+              """
+// 'List' is misspelled.
+@MirrorsUsed(targets: 'dart.core.Lsit')
+import 'dart:mirrors';
+
+main() {}
+"""]),
+
+      MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT:
+        const MessageTemplate(MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
+          "Can't find '#{name}' in '#{element}'.",
+          // TODO(ahe): The closest identifiers in edit distance would be nice.
+          howToFix: "Is '#{name}' spelled right?",
+          examples: const [
+              """
+// 'addAll' is misspelled.
+@MirrorsUsed(targets: 'dart.core.List.addAl')
+import 'dart:mirrors';
+
+main() {}
+"""]),
+
+      MessageKind.INVALID_URI:
+        const MessageTemplate(MessageKind.INVALID_URI,
+          "'#{uri}' is not a valid URI.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [
+            """
+// can't have a '[' in a URI
+import '../../Udyn[mic ils/expect.dart';
+
+main() {}
+"""]),
+
+      MessageKind.INVALID_PACKAGE_CONFIG:
+          const MessageTemplate(MessageKind.INVALID_PACKAGE_CONFIG,
+            """Package config file '#{uri}' is invalid.
+#{exception}""",
+            howToFix: DONT_KNOW_HOW_TO_FIX
+      ),
+
+      MessageKind.INVALID_PACKAGE_URI:
+        const MessageTemplate(MessageKind.INVALID_PACKAGE_URI,
+          "'#{uri}' is not a valid package URI (#{exception}).",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [
+            """
+// can't have a 'top level' package URI
+import 'package:foo.dart';
+
+main() {}
+""", """
+// can't have 2 slashes
+import 'package://foo/foo.dart';
+
+main() {}
+""", """
+// package name must be valid
+import 'package:not\valid/foo.dart';
+
+main() {}
+"""]),
+
+      MessageKind.READ_SCRIPT_ERROR:
+        const MessageTemplate(MessageKind.READ_SCRIPT_ERROR,
+          "Can't read '#{uri}' (#{exception}).",
+          // Don't know how to fix since the underlying error is unknown.
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [
+              """
+// 'foo.dart' does not exist.
+import 'foo.dart';
+
+main() {}
+"""]),
+
+      MessageKind.READ_SELF_ERROR:
+        const MessageTemplate(MessageKind.READ_SELF_ERROR,
+          "#{exception}",
+          // Don't know how to fix since the underlying error is unknown.
+          howToFix: DONT_KNOW_HOW_TO_FIX),
+
+      MessageKind.EXTRANEOUS_MODIFIER:
+        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER,
+          "Can't have modifier '#{modifier}' here.",
+          howToFix: "Try removing '#{modifier}'.",
+          examples: const [
+              "var String foo; main(){}",
+              // "var get foo; main(){}",
+              "var set foo; main(){}",
+              "var final foo; main(){}",
+              "var var foo; main(){}",
+              "var const foo; main(){}",
+              "var abstract foo; main(){}",
+              "var static foo; main(){}",
+              "var external foo; main(){}",
+              "get var foo; main(){}",
+              "set var foo; main(){}",
+              "final var foo; main(){}",
+              "var var foo; main(){}",
+              "const var foo; main(){}",
+              "abstract var foo; main(){}",
+              "static var foo; main(){}",
+              "external var foo; main(){}"]),
+
+      MessageKind.EXTRANEOUS_MODIFIER_REPLACE:
+        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
+          "Can't have modifier '#{modifier}' here.",
+          howToFix:
+            "Try replacing modifier '#{modifier}' with 'var', 'final', "
+            "or a type.",
+          examples: const [
+              // "get foo; main(){}",
+              "set foo; main(){}",
+              "abstract foo; main(){}",
+              "static foo; main(){}",
+              "external foo; main(){}"]),
+
+      MessageKind.ABSTRACT_CLASS_INSTANTIATION:
+        const MessageTemplate(MessageKind.ABSTRACT_CLASS_INSTANTIATION,
+          "Can't instantiate abstract class.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const ["abstract class A {} main() { new A(); }"]),
+
+      MessageKind.BODY_EXPECTED:
+        const MessageTemplate(MessageKind.BODY_EXPECTED,
+          "Expected a function body or '=>'.",
+          // TODO(ahe): In some scenarios, we can suggest removing the 'static'
+          // keyword.
+          howToFix: "Try adding {}.",
+          examples: const [
+              "main();"]),
+
+      MessageKind.MIRROR_BLOAT:
+        const MessageTemplate(MessageKind.MIRROR_BLOAT,
+          "#{count} methods retained for use by dart:mirrors out of #{total}"
+          " total methods (#{percentage}%)."),
+
+      MessageKind.MIRROR_IMPORT:
+        const MessageTemplate(MessageKind.MIRROR_IMPORT,
+          "Import of 'dart:mirrors'."),
+
+      MessageKind.MIRROR_IMPORT_NO_USAGE:
+        const MessageTemplate(MessageKind.MIRROR_IMPORT_NO_USAGE,
+          "This import is not annotated with @MirrorsUsed, which may lead to "
+          "unnecessarily large generated code.",
+          howToFix:
+              "Try adding '@MirrorsUsed(...)' as described at "
+              "https://goo.gl/Akrrog."),
+
+      MessageKind.JS_PLACEHOLDER_CAPTURE:
+        const MessageTemplate(
+            MessageKind.JS_PLACEHOLDER_CAPTURE,
+            "JS code must not use '#' placeholders inside functions.",
+            howToFix:
+            "Use an immediately called JavaScript function to capture the"
+            " the placeholder values as JavaScript function parameters."),
+
+      MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
+        const MessageTemplate(
+          MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT,
+          "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant."),
+
+      MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
+        const MessageTemplate(MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
+              "'#{keyword}' is a reserved word and can't be used here.",
+              howToFix: "Try using a different name.",
+              examples: const ["do() {} main() {}"]),
+
+      MessageKind. NAMED_FUNCTION_EXPRESSION:
+        const MessageTemplate(MessageKind.NAMED_FUNCTION_EXPRESSION,
+          "Function expression '#{name}' cannot be named.",
+          howToFix: "Try removing the name.",
+          examples: const ["main() { var f = func() {}; }"]),
+
+      MessageKind.UNUSED_METHOD:
+        const MessageTemplate(MessageKind.UNUSED_METHOD,
+          "The method '#{name}' is never called.",
+          howToFix: "Consider deleting it.",
+          examples: const ["deadCode() {} main() {}"]),
+
+      MessageKind.UNUSED_CLASS:
+        const MessageTemplate(MessageKind.UNUSED_CLASS,
+          "The class '#{name}' is never used.",
+          howToFix: "Consider deleting it.",
+          examples: const ["class DeadCode {} main() {}"]),
+
+      MessageKind.UNUSED_TYPEDEF:
+        const MessageTemplate(MessageKind.UNUSED_TYPEDEF,
+          "The typedef '#{name}' is never used.",
+          howToFix: "Consider deleting it.",
+          examples: const ["typedef DeadCode(); main() {}"]),
+
+      MessageKind.ABSTRACT_METHOD:
+        const MessageTemplate(MessageKind.ABSTRACT_METHOD,
+          "The method '#{name}' has no implementation in "
+          "class '#{class}'.",
+          howToFix: "Try adding a body to '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+class Class {
+  method();
+}
+main() => new Class().method();
+"""]),
+
+      MessageKind.ABSTRACT_GETTER:
+        const MessageTemplate(MessageKind.ABSTRACT_GETTER,
+          "The getter '#{name}' has no implementation in "
+          "class '#{class}'.",
+          howToFix: "Try adding a body to '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+class Class {
+  get getter;
+}
+main() => new Class();
+"""]),
+
+      MessageKind.ABSTRACT_SETTER:
+        const MessageTemplate(MessageKind.ABSTRACT_SETTER,
+          "The setter '#{name}' has no implementation in "
+          "class '#{class}'.",
+          howToFix: "Try adding a body to '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+class Class {
+  set setter(_);
+}
+main() => new Class();
+"""]),
+
+      MessageKind.INHERIT_GETTER_AND_METHOD:
+        const MessageTemplate(MessageKind.INHERIT_GETTER_AND_METHOD,
+          "The class '#{class}' can't inherit both getters and methods "
+          "by the named '#{name}'.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const ["""
+class A {
+  get member => null;
+}
+class B {
+  member() {}
+}
+class Class implements A, B {
+}
+main() => new Class();
+"""]),
+
+      MessageKind.INHERITED_METHOD:
+        const MessageTemplate(MessageKind.INHERITED_METHOD,
+          "The inherited method '#{name}' is declared here in class "
+          "'#{class}'."),
+
+      MessageKind.INHERITED_EXPLICIT_GETTER:
+        const MessageTemplate(MessageKind.INHERITED_EXPLICIT_GETTER,
+          "The inherited getter '#{name}' is declared here in class "
+          "'#{class}'."),
+
+      MessageKind.INHERITED_IMPLICIT_GETTER:
+        const MessageTemplate(MessageKind.INHERITED_IMPLICIT_GETTER,
+          "The inherited getter '#{name}' is implicitly declared by this "
+          "field in class '#{class}'."),
+
+      MessageKind.UNIMPLEMENTED_METHOD_ONE:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_ONE,
+          "'#{class}' doesn't implement '#{method}' "
+          "declared in '#{declarer}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  m();
+}
+class C implements I {}
+main() => new C();
+""", """
+abstract class I {
+  m();
+}
+class C extends I {}
+main() => new C();
+"""]),
+
+      MessageKind.UNIMPLEMENTED_METHOD:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD,
+          "'#{class}' doesn't implement '#{method}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  m();
+}
+
+abstract class J {
+  m();
+}
+
+class C implements I, J {}
+
+main() {
+ new C();
+}
+""", """
+abstract class I {
+  m();
+}
+
+abstract class J {
+  m();
+}
+
+class C extends I implements J {}
+
+main() {
+ new C();
+}
+"""]),
+
+      MessageKind.UNIMPLEMENTED_METHOD_CONT:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_CONT,
+          "The method '#{name}' is declared here in class '#{class}'."),
+
+      MessageKind.UNIMPLEMENTED_SETTER_ONE:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER_ONE,
+          "'#{class}' doesn't implement the setter '#{name}' "
+          "declared in '#{declarer}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  set m(_);
+}
+class C implements I {}
+class D implements I {
+  set m(_) {}
+}
+main() {
+ new D().m = 0;
+ new C();
+}
+"""]),
+
+      MessageKind.UNIMPLEMENTED_SETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER,
+          "'#{class}' doesn't implement the setter '#{name}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  set m(_);
+}
+abstract class J {
+  set m(_);
+}
+class C implements I, J {}
+main() => new C();
+""", """
+abstract class I {
+  set m(_);
+}
+abstract class J {
+  set m(_);
+}
+class C extends I implements J {}
+main() => new C();
+"""]),
+
+      MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+          "The setter '#{name}' is declared here in class '#{class}'."),
+
+      MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
+          "The setter '#{name}' is implicitly declared by this field "
+          "in class '#{class}'."),
+
+      MessageKind.UNIMPLEMENTED_GETTER_ONE:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER_ONE,
+          "'#{class}' doesn't implement the getter '#{name}' "
+          "declared in '#{declarer}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  get m;
+}
+class C implements I {}
+main() => new C();
+""", """
+abstract class I {
+  get m;
+}
+class C extends I {}
+main() => new C();
+"""]),
+
+      MessageKind.UNIMPLEMENTED_GETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER,
+          "'#{class}' doesn't implement the getter '#{name}'.",
+          howToFix: "Try adding an implementation of '#{name}' or declaring "
+                    "'#{class}' to be 'abstract'.",
+          examples: const ["""
+abstract class I {
+  get m;
+}
+abstract class J {
+  get m;
+}
+class C implements I, J {}
+main() => new C();
+""", """
+abstract class I {
+  get m;
+}
+abstract class J {
+  get m;
+}
+class C extends I implements J {}
+main() => new C();
+"""]),
+
+      MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+          "The getter '#{name}' is declared here in class '#{class}'."),
+
+      MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER:
+        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+          "The getter '#{name}' is implicitly declared by this field "
+          "in class '#{class}'."),
+
+      MessageKind.INVALID_METADATA:
+        const MessageTemplate(MessageKind.INVALID_METADATA,
+          "A metadata annotation must be either a reference to a compile-time "
+          "constant variable or a call to a constant constructor.",
+          howToFix:
+            "Try using a different constant value or referencing it through a "
+            "constant variable.",
+          examples: const [
+'@Object main() {}',
+'@print main() {}']),
+
+      MessageKind.INVALID_METADATA_GENERIC:
+        const MessageTemplate(MessageKind.INVALID_METADATA_GENERIC,
+          "A metadata annotation using a constant constructor cannot use type "
+          "arguments.",
+          howToFix:
+            "Try removing the type arguments or referencing the constant "
+            "through a constant variable.",
+          examples: const ['''
+class C<T> {
+  const C();
+}
+@C<int>() main() {}
+''']),
+
+      MessageKind.EQUAL_MAP_ENTRY_KEY:
+        const MessageTemplate(MessageKind.EQUAL_MAP_ENTRY_KEY,
+          "An entry with the same key already exists in the map.",
+          howToFix:
+            "Try removing the previous entry or changing the key in one "
+            "of the entries.",
+          examples: const ["""
+main() {
+  var m = const {'foo': 1, 'foo': 2};
+}"""]),
+
+      MessageKind.BAD_INPUT_CHARACTER:
+        const MessageTemplate(MessageKind.BAD_INPUT_CHARACTER,
+          "Character U+#{characterHex} isn't allowed here.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const ["""
+main() {
+  String x = ç;
+}
+"""]),
+
+      MessageKind.UNTERMINATED_STRING:
+        const MessageTemplate(MessageKind.UNTERMINATED_STRING,
+          "String must end with #{quote}.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const ["""
+main() {
+  return '
+;
+}
+""",
+"""
+main() {
+  return \"
+;
+}
+""",
+"""
+main() {
+  return r'
+;
+}
+""",
+"""
+main() {
+  return r\"
+;
+}
+""",
+"""
+main() => '''
+""",
+"""
+main() => \"\"\"
+""",
+"""
+main() => r'''
+""",
+"""
+main() => r\"\"\"
+"""]),
+
+      MessageKind.UNMATCHED_TOKEN:
+        const MessageTemplate(MessageKind.UNMATCHED_TOKEN,
+          "Can't find '#{end}' to match '#{begin}'.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const[
+              "main(",
+              "main(){",
+              "main(){]}",
+            ]),
+
+      MessageKind.UNTERMINATED_TOKEN:
+        const MessageTemplate(MessageKind.UNTERMINATED_TOKEN,
+          // This is a fall-back message that shouldn't happen.
+          "Incomplete token."),
+
+      MessageKind.EXPONENT_MISSING:
+        const MessageTemplate(MessageKind.EXPONENT_MISSING,
+          "Numbers in exponential notation should always contain an exponent"
+          " (an integer number with an optional sign).",
+          howToFix:
+            "Make sure there is an exponent, and remove any whitespace "
+            "before it.",
+          examples: const ["""
+main() {
+  var i = 1e;
+}
+"""]),
+
+      MessageKind.HEX_DIGIT_EXPECTED:
+        const MessageTemplate(MessageKind.HEX_DIGIT_EXPECTED,
+          "A hex digit (0-9 or A-F) must follow '0x'.",
+          howToFix:
+            DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
+          examples: const ["""
+main() {
+  var i = 0x;
+}
+"""]),
+
+      MessageKind.MALFORMED_STRING_LITERAL:
+        const MessageTemplate(MessageKind.MALFORMED_STRING_LITERAL,
+          r"A '$' has special meaning inside a string, and must be followed by "
+          "an identifier or an expression in curly braces ({}).",
+          howToFix: r"Try adding a backslash (\) to escape the '$'.",
+          examples: const [r"""
+main() {
+  return '$';
+}
+""",
+r'''
+main() {
+  return "$";
+}
+''',
+r"""
+main() {
+  return '''$''';
+}
+""",
+r'''
+main() {
+  return """$""";
+}
+''']),
+
+      MessageKind.UNTERMINATED_COMMENT:
+        const MessageTemplate(MessageKind.UNTERMINATED_COMMENT,
+          "Comment starting with '/*' must end with '*/'.",
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [r"""
+main() {
+}
+/*"""]),
+
+      MessageKind.MISSING_TOKEN_BEFORE_THIS:
+        const MessageTemplate(MessageKind.MISSING_TOKEN_BEFORE_THIS,
+          "Expected '#{token}' before this.",
+          // Consider the second example below: the parser expects a ')' before
+          // 'y', but a ',' would also have worked. We don't have enough
+          // information to give a good suggestion.
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [
+              "main() => true ? 1;",
+              "main() => foo(x: 1 y: 2);",
+            ]),
+
+      MessageKind.MISSING_TOKEN_AFTER_THIS:
+        const MessageTemplate(MessageKind.MISSING_TOKEN_AFTER_THIS,
+          "Expected '#{token}' after this.",
+          // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
+          // to give a good suggestion.
+          howToFix: DONT_KNOW_HOW_TO_FIX,
+          examples: const [
+              "main(x) {x}",
+"""
+class S1 {}
+class S2 {}
+class S3 {}
+class A = S1 with S2, S3
+main() => new A();
+"""
+]),
+
+      MessageKind.CONSIDER_ANALYZE_ALL:
+        const MessageTemplate(MessageKind.CONSIDER_ANALYZE_ALL,
+          "Could not find '#{main}'.  Nothing will be analyzed.",
+          howToFix: "Try using '--analyze-all' to analyze everything.",
+          examples: const ['']),
+
+      MessageKind.MISSING_MAIN:
+        const MessageTemplate(MessageKind.MISSING_MAIN,
+          "Could not find '#{main}'.",
+          howToFix: "Try adding a method named '#{main}' to your program."
+          /* No example, test uses '--analyze-only' which will produce the above
+           * message [CONSIDER_ANALYZE_ALL].  An example for a human operator
+           * would be an empty file.*/),
+
+      MessageKind.MAIN_NOT_A_FUNCTION:
+        const MessageTemplate(MessageKind.MAIN_NOT_A_FUNCTION,
+          "'#{main}' is not a function.",
+          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
+          examples: const ['var main;']),
+
+      MessageKind.MAIN_WITH_EXTRA_PARAMETER:
+        const MessageTemplate(MessageKind.MAIN_WITH_EXTRA_PARAMETER,
+          "'#{main}' cannot have more than two parameters.",
+          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
+          examples: const ['main(a, b, c) {}']),
+
+      MessageKind.COMPILER_CRASHED:
+        const MessageTemplate(MessageKind.COMPILER_CRASHED,
+          "The compiler crashed when compiling this element."),
+
+      MessageKind.PLEASE_REPORT_THE_CRASH:
+        const MessageTemplate(MessageKind.PLEASE_REPORT_THE_CRASH, '''
+The compiler is broken.
+
+When compiling the above element, the compiler crashed. It is not
+possible to tell if this is caused by a problem in your program or
+not. Regardless, the compiler should not crash.
+
+The Dart team would greatly appreciate if you would take a moment to
+report this problem at http://dartbug.com/new.
+
+Please include the following information:
+
+* the name and version of your operating system,
+
+* the Dart SDK build number (#{buildId}), and
+
+* the entire message you see here (including the full stack trace
+  below as well as the source location above).
+'''),
+
+      MessageKind.POTENTIAL_MUTATION:
+        const MessageTemplate(MessageKind.POTENTIAL_MUTATION,
+          "Variable '#{variableName}' is not known to be of type "
+          "'#{shownType}' because it is potentially mutated in the scope for "
+          "promotion."),
+
+      MessageKind.POTENTIAL_MUTATION_HERE:
+        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_HERE,
+          "Variable '#{variableName}' is potentially mutated here."),
+
+      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE:
+        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
+          "Variable '#{variableName}' is not known to be of type "
+          "'#{shownType}' because it is potentially mutated within a closure."),
+
+      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
+        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
+              "Variable '#{variableName}' is potentially mutated in a "
+              "closure here."),
+
+      MessageKind.ACCESSED_IN_CLOSURE:
+        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE,
+          "Variable '#{variableName}' is not known to be of type "
+          "'#{shownType}' because it is accessed by a closure in the scope for "
+          "promotion and potentially mutated in the scope of "
+          "'#{variableName}'."),
+
+      MessageKind.ACCESSED_IN_CLOSURE_HERE:
+        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE_HERE,
+          "Variable '#{variableName}' is accessed in a closure here."),
+
+      MessageKind.NOT_MORE_SPECIFIC:
+        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC,
+          "Variable '#{variableName}' is not shown to have type "
+          "'#{shownType}' because '#{shownType}' is not more specific than the "
+          "known type '#{knownType}' of '#{variableName}'."),
+
+      MessageKind.NOT_MORE_SPECIFIC_SUBTYPE:
+        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUBTYPE,
+          "Variable '#{variableName}' is not shown to have type "
+          "'#{shownType}' because '#{shownType}' is not a subtype of the "
+          "known type '#{knownType}' of '#{variableName}'."),
+
+      MessageKind.NOT_MORE_SPECIFIC_SUGGESTION:
+        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
+          "Variable '#{variableName}' is not shown to have type "
+          "'#{shownType}' because '#{shownType}' is not more specific than the "
+          "known type '#{knownType}' of '#{variableName}'.",
+          howToFix:
+            "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'."),
+
+      MessageKind.NO_COMMON_SUBTYPES:
+        const MessageTemplate(MessageKind.NO_COMMON_SUBTYPES,
+           "Types '#{left}' and '#{right}' have no common subtypes."),
+
+      MessageKind.HIDDEN_WARNINGS_HINTS:
+        const MessageTemplate(MessageKind.HIDDEN_WARNINGS_HINTS,
+          "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}."),
+
+      MessageKind.HIDDEN_WARNINGS:
+        const MessageTemplate(MessageKind.HIDDEN_WARNINGS,
+          "#{warnings} warning(s) suppressed in #{uri}."),
+
+      MessageKind.HIDDEN_HINTS:
+        const MessageTemplate(MessageKind.HIDDEN_HINTS,
+          "#{hints} hint(s) suppressed in #{uri}."),
+
+      MessageKind.PREAMBLE:
+        const MessageTemplate(MessageKind.PREAMBLE,
+        "When run on the command-line, the compiled output might"
+        " require a preamble file located in:\n"
+        "  <sdk>/lib/_internal/js_runtime/lib/preambles."),
+
+      MessageKind.INVALID_SYNC_MODIFIER:
+        const MessageTemplate(MessageKind.INVALID_SYNC_MODIFIER,
+          "Invalid modifier 'sync'.",
+          howToFix: "Try replacing 'sync' with 'sync*'.",
+          examples: const [
+            "main() sync {}"
+          ]),
+
+      MessageKind.INVALID_AWAIT_FOR:
+        const MessageTemplate(MessageKind.INVALID_AWAIT_FOR,
+          "'await' is only supported on for-in loops.",
+          howToFix: "Try rewriting the loop as a for-in loop or removing the "
+                    "'await' keyword.",
+          examples: const ["""
+main() async* {
+  await for (int i = 0; i < 10; i++) {}
+}
+"""]),
+
+      MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
+        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
+          "The modifier '#{modifier}' is not allowed on an abstract method.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier or adding a "
+                    "body to the method.",
+          examples: const ["""
+abstract class A {
+  method() async;
+}
+class B extends A {
+  method() {}
+}
+main() {
+  A a = new B();
+  a.method();
+}
+"""]),
+
+      MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
+              "The modifier '#{modifier}' is not allowed on constructors.",
+              options: const ['--enable-async'],
+              howToFix: "Try removing the '#{modifier}' modifier.",
+              examples: const ["""
+class A {
+  A() async;
+}
+main() => new A();""",
+
+"""
+class A {
+  A();
+  factory A.a() async* {}
+}
+main() => new A.a();"""]),
+
+      MessageKind.ASYNC_MODIFIER_ON_SETTER:
+        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_SETTER,
+              "The modifier '#{modifier}' is not allowed on setters.",
+              options: const ['--enable-async'],
+              howToFix: "Try removing the '#{modifier}' modifier.",
+              examples: const ["""
+class A {
+  set foo(v) async {}
+}
+main() => new A().foo = 0;"""]),
+
+      MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
+        const MessageTemplate(MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
+          "The modifier '#{modifier}' is not allowed on methods implemented "
+          "using '=>'.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier or implementing "
+                    "the method body using a block: '{ ... }'.",
+          examples: const ["main() sync* => null;", "main() async* => null;"]),
+
+      // TODO(johnniwinther): Check for 'async' as identifier.
+      MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER:
+        const MessageTemplate(MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
+          "'#{keyword}' cannot be used as an identifier in a function body "
+          "marked with '#{modifier}'.",
+          options: const ['--enable-async'],
+          howToFix: "Try removing the '#{modifier}' modifier or renaming the "
+                    "identifier.",
+          examples: const ["""
+main() async {
+ var await;
+}""",
+"""
+main() async* {
+ var yield;
+}""",
+"""
+main() sync* {
+ var yield;
+}"""]),
+
+      MessageKind.RETURN_IN_GENERATOR:
+        const MessageTemplate(MessageKind.RETURN_IN_GENERATOR,
+          "'return' with a value is not allowed in a method body using the "
+          "'#{modifier}' modifier.",
+          howToFix: "Try removing the value, replacing 'return' with 'yield' "
+                    "or changing the method body modifier.",
+          examples: const [
+"""
+foo() async* { return 0; }
+main() => foo();
+""",
+
+"""
+foo() sync* { return 0; }
+main() => foo();
+"""]),
+
+      MessageKind.NATIVE_NOT_SUPPORTED:
+        const MessageTemplate(MessageKind.NATIVE_NOT_SUPPORTED,
+          "'native' modifier is not supported.",
+          howToFix: "Try removing the 'native' implementation or analyzing the "
+                    "code with the --allow-native-extensions option.",
+          examples: const ["""
+main() native "Main";
+"""]),
+
+      MessageKind.DART_EXT_NOT_SUPPORTED:
+        const MessageTemplate(MessageKind.DART_EXT_NOT_SUPPORTED,
+          "The 'dart-ext' scheme is not supported.",
+          howToFix: "Try analyzing the code with the --allow-native-extensions "
+                    "option.",
+          examples: const ["""
+import 'dart-ext:main';
+
+main() {}
+"""]),
+
+      MessageKind.LIBRARY_TAG_MUST_BE_FIRST:
+        const MessageTemplate(MessageKind.LIBRARY_TAG_MUST_BE_FIRST,
+          "The library declaration should come before other declarations.",
+          howToFix: "Try moving the declaration to the top of the file.",
+          examples: const [
+"""
+import 'dart:core';
+library foo;
+main() {}
+""",
+      ]),
+
+      MessageKind.ONLY_ONE_LIBRARY_TAG:
+        const MessageTemplate(MessageKind.ONLY_ONE_LIBRARY_TAG,
+          "There can only be one library declaration.",
+          howToFix: "Try removing all other library declarations.",
+          examples: const [
+"""
+library foo;
+library bar;
+main() {}
+""",
+"""
+library foo;
+import 'dart:core';
+library bar;
+main() {}
+""",
+      ]),
+
+      MessageKind.IMPORT_BEFORE_PARTS:
+        const MessageTemplate(MessageKind.IMPORT_BEFORE_PARTS,
+          "Import declarations should come before parts.",
+          howToFix: "Try moving this import further up in the file.",
+          examples: const [
+              const <String, String>{
+                'main.dart': """
+library test.main;
+part 'part.dart';
+import 'dart:core';
+main() {}
+""",
+                'part.dart': """
+part of test.main;
+""",
+          }]),
+
+      MessageKind.EXPORT_BEFORE_PARTS:
+        const MessageTemplate(MessageKind.EXPORT_BEFORE_PARTS,
+          "Export declarations should come before parts.",
+          howToFix: "Try moving this export further up in the file.",
+          examples: const [
+              const <String, String>{
+                'main.dart': """
+library test.main;
+part 'part.dart';
+export 'dart:core';
+main() {}
+""",
+               'part.dart': """
+part of test.main;
+""",
+          }]),
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Patch errors start.
+  //////////////////////////////////////////////////////////////////////////////
+
+      MessageKind.PATCH_RETURN_TYPE_MISMATCH:
+        const MessageTemplate(MessageKind.PATCH_RETURN_TYPE_MISMATCH,
+          "Patch return type '#{patchReturnType}' does not match "
+          "'#{originReturnType}' on origin method '#{methodName}'."),
+
+      MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
+        const MessageTemplate(
+          MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
+          "Required parameter count of patch method "
+          "(#{patchParameterCount}) does not match parameter count on origin "
+          "method '#{methodName}' (#{originParameterCount})."),
+
+      MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
+        const MessageTemplate(
+          MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
+          "Optional parameter count of patch method "
+          "(#{patchParameterCount}) does not match parameter count on origin "
+          "method '#{methodName}' (#{originParameterCount})."),
+
+      MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
+        const MessageTemplate(
+          MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
+          "Optional parameters of origin and patch method "
+          "'#{methodName}' must both be either named or positional."),
+
+      MessageKind.PATCH_PARAMETER_MISMATCH:
+        const MessageTemplate(MessageKind.PATCH_PARAMETER_MISMATCH,
+          "Patch method parameter '#{patchParameter}' does not match "
+          "'#{originParameter}' on origin method '#{methodName}'."),
+
+      MessageKind.PATCH_PARAMETER_TYPE_MISMATCH:
+        const MessageTemplate(MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
+          "Patch method parameter '#{parameterName}' type "
+          "'#{patchParameterType}' does not match '#{originParameterType}' on "
+          "origin method '#{methodName}'."),
+
+      MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
+        const MessageTemplate(MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION,
+          "External method without an implementation."),
+
+      MessageKind.PATCH_POINT_TO_FUNCTION:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_FUNCTION,
+          "This is the function patch '#{functionName}'."),
+
+      MessageKind.PATCH_POINT_TO_CLASS:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_CLASS,
+          "This is the class patch '#{className}'."),
+
+      MessageKind.PATCH_POINT_TO_GETTER:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_GETTER,
+          "This is the getter patch '#{getterName}'."),
+
+      MessageKind.PATCH_POINT_TO_SETTER:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_SETTER,
+          "This is the setter patch '#{setterName}'."),
+
+      MessageKind.PATCH_POINT_TO_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
+          "This is the constructor patch '#{constructorName}'."),
+
+      MessageKind.PATCH_POINT_TO_PARAMETER:
+        const MessageTemplate(MessageKind.PATCH_POINT_TO_PARAMETER,
+          "This is the patch parameter '#{parameterName}'."),
+
+      MessageKind.PATCH_NON_EXISTING:
+        const MessageTemplate(MessageKind.PATCH_NON_EXISTING,
+          "Origin does not exist for patch '#{name}'."),
+
+      // TODO(ahe): Eventually, this error should be removed as it will be
+      // handled by the regular parser.
+      MessageKind.PATCH_NONPATCHABLE:
+        const MessageTemplate(MessageKind.PATCH_NONPATCHABLE,
+          "Only classes and functions can be patched."),
+
+      MessageKind.PATCH_NON_EXTERNAL:
+        const MessageTemplate(MessageKind.PATCH_NON_EXTERNAL,
+          "Only external functions can be patched."),
+
+      MessageKind.PATCH_NON_CLASS:
+        const MessageTemplate(MessageKind.PATCH_NON_CLASS,
+          "Patching non-class with class patch '#{className}'."),
+
+      MessageKind.PATCH_NON_GETTER:
+        const MessageTemplate(MessageKind.PATCH_NON_GETTER,
+          "Cannot patch non-getter '#{name}' with getter patch."),
+
+      MessageKind.PATCH_NO_GETTER:
+        const MessageTemplate(MessageKind.PATCH_NO_GETTER,
+          "No getter found for getter patch '#{getterName}'."),
+
+      MessageKind.PATCH_NON_SETTER:
+        const MessageTemplate(MessageKind.PATCH_NON_SETTER,
+          "Cannot patch non-setter '#{name}' with setter patch."),
+
+      MessageKind.PATCH_NO_SETTER:
+        const MessageTemplate(MessageKind.PATCH_NO_SETTER,
+          "No setter found for setter patch '#{setterName}'."),
+
+      MessageKind.PATCH_NON_CONSTRUCTOR:
+        const MessageTemplate(MessageKind.PATCH_NON_CONSTRUCTOR,
+          "Cannot patch non-constructor with constructor patch "
+          "'#{constructorName}'."),
+
+      MessageKind.PATCH_NON_FUNCTION:
+        const MessageTemplate(MessageKind.PATCH_NON_FUNCTION,
+          "Cannot patch non-function with function patch "
+          "'#{functionName}'."),
+
+      MessageKind.INJECTED_PUBLIC_MEMBER:
+        const MessageTemplate(MessageKind.INJECTED_PUBLIC_MEMBER,
+            "Non-patch members in patch libraries must be private."),
+
+      MessageKind.EXTERNAL_WITH_BODY:
+        const MessageTemplate(MessageKind.EXTERNAL_WITH_BODY,
+          "External function '#{functionName}' cannot have a function body.",
+          options: const ["--output-type=dart"],
+          howToFix:
+            "Try removing the 'external' modifier or the function body.",
+          examples: const ["""
+external foo() => 0;
+main() => foo();
+""", """
+external foo() {}
+main() => foo();
+"""]),
+
+  //////////////////////////////////////////////////////////////////////////////
+  // Patch errors end.
+  //////////////////////////////////////////////////////////////////////////////
+
+      MessageKind.EXPERIMENTAL_ASSERT_MESSAGE:
+        const MessageTemplate(MessageKind.EXPERIMENTAL_ASSERT_MESSAGE,
+          "Experimental language feature 'assertion with message'"
+          " is not supported.",
+          howToFix:
+            "Use option '--assert-message' to use assertions with messages.",
+          examples: const [r'''
+main() {
+  int n = -7;
+  assert(n > 0, 'must be positive: $n');
+}
+''']),
+
+      MessageKind.IMPORT_EXPERIMENTAL_MIRRORS:
+        const MessageTemplate(MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, r'''
+
+****************************************************************
+* WARNING: dart:mirrors support in dart2js is experimental,
+*          and not recommended.
+*          This implementation of mirrors is incomplete,
+*          and often greatly increases the size of the generated
+*          JavaScript code.
+*
+* Your app imports dart:mirrors via:''''''
+$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
+*
+* You can disable this message by using the --enable-experimental-mirrors
+* command-line flag.
+*
+* To learn what to do next, please visit:
+*    http://dartlang.org/dart2js-reflection
+****************************************************************
+'''),
+
+      MessageKind.DISALLOWED_LIBRARY_IMPORT:
+        const MessageTemplate(MessageKind.DISALLOWED_LIBRARY_IMPORT, '''
+Your app imports the unsupported library '#{uri}' via:
+''''''
+$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
+
+Use the --categories option to support import of '#{uri}'.
+'''),
+
+      MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
+        const MessageTemplate(
+          MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND,
+          """
+dart:mirrors library is not supported when using this backend.
+
+Your app imports dart:mirrors via:""""""
+$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}"""),
+
+      MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
+        const MessageTemplate(MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS,
+          "Non-supported 'call' member on a native class, or a "
+          "subclass of a native class."),
+
+      MessageKind.DIRECTLY_THROWING_NSM:
+        const MessageTemplate(MessageKind.DIRECTLY_THROWING_NSM,
+          "This 'noSuchMethod' implementation is guaranteed to throw an "
+          "exception. The generated code will be smaller if it is "
+          "rewritten.",
+          howToFix: "Rewrite to "
+                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
+
+      MessageKind.COMPLEX_THROWING_NSM:
+        const MessageTemplate(MessageKind.COMPLEX_THROWING_NSM,
+          "This 'noSuchMethod' implementation is guaranteed to throw an "
+          "exception. The generated code will be smaller and the compiler "
+          "will be able to perform more optimizations if it is rewritten.",
+          howToFix: "Rewrite to "
+                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
+
+      MessageKind.COMPLEX_RETURNING_NSM:
+        const MessageTemplate(MessageKind.COMPLEX_RETURNING_NSM,
+          "Overriding 'noSuchMethod' causes the compiler to generate "
+          "more code and prevents the compiler from doing some optimizations.",
+          howToFix: "Consider removing this 'noSuchMethod' implementation."),
+
+      MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
+        const MessageTemplate(MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
+          "Unsupported version of package:lookup_map.",
+          howToFix: DONT_KNOW_HOW_TO_FIX),
+
+  }); // End of TEMPLATES.
+
+  /// Padding used before and between import chains in the message for
+  /// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
+  static const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
+
+  /// Padding used before and between import chains in the message for
+  /// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
+  static const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
+
+  /// Padding used before and between import chains in the message for
+  /// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
+  static const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
 
   toString() => template;
 
@@ -901,42 +3675,7 @@
     return new Message(this, arguments, terse);
   }
 
-  bool get hasHowToFix =>
-      howToFix != null && howToFix != dart2js_messages.DONT_KNOW_HOW_TO_FIX;
-
-  static final Map<MessageKind, MessageTemplate> TEMPLATES =
-      _constructMessageTemplates();
-
-  static String get IMPORT_EXPERIMENTAL_MIRRORS_PADDING =>
-      dart2js_messages.IMPORT_EXPERIMENTAL_MIRRORS_PADDING;
-
-  static String get MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING =>
-      dart2js_messages.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING;
-
-  static String get DISALLOWED_LIBRARY_IMPORT_PADDING =>
-      dart2js_messages.DISALLOWED_LIBRARY_IMPORT_PADDING;
-
-  static Map<MessageKind, MessageTemplate> _constructMessageTemplates() {
-    Map<MessageKind, MessageTemplate> result = <MessageKind, MessageTemplate>{};
-    for (MessageKind kind in MessageKind.values) {
-      String name = _KIND_TO_STRING_MAP[kind];
-      if (name == null) {
-        throw new ArgumentError("No mapping for $kind in _KIND_TO_STRING_MAP");
-      }
-      Map data =
-          shared_messages.MESSAGES[name] ?? dart2js_messages.MESSAGES[name];
-      if (data == null) throw new ArgumentError.value(name);
-
-      String id = data['id'];
-      String template = data['template'];
-      String howToFix = data['howToFix'];
-      List examples = data['examples'];
-      List<String> options = data['options'] ?? const <String>[];
-      result[kind] =
-          new MessageTemplate(kind, id, template, howToFix, examples, options);
-    }
-    return result;
-  }
+  bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
 }
 
 class Message {
@@ -946,13 +3685,10 @@
   String message;
 
   Message(this.template, this.arguments, this.terse) {
-    assert(() {
-      computeMessage();
-      return true;
-    });
+    assert(() { computeMessage(); return true; });
   }
 
-  MessageKind get kind => template.kind;
+  dynamic/*MessageKind | SharedMessageKind*/ get kind => template.kind;
 
   String computeMessage() {
     if (message == null) {
@@ -963,7 +3699,7 @@
       assert(invariant(
           CURRENT_ELEMENT_SPANNABLE,
           kind == MessageKind.GENERIC ||
-              !message.contains(new RegExp(r'#\{.+\}')),
+            !message.contains(new RegExp(r'#\{.+\}')),
           message: 'Missing arguments in error message: "$message"'));
       if (!terse && template.hasHowToFix) {
         String howToFix = template.howToFix;
@@ -980,8 +3716,8 @@
     return computeMessage();
   }
 
-  bool operator ==(other) {
-    if (other is! Message) return false;
+  bool operator==(other) {
+    if (other is !Message) return false;
     return (template == other.template) && (toString() == other.toString());
   }
 
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 207954d..d909a47 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -54,7 +54,7 @@
     compiler.dumpInfoTask._constantToNode.forEach((constant, node) {
       // TODO(sigmund): add dependencies on other constants
       var size = compiler.dumpInfoTask._nodeToSize[node];
-      var code = jsAst.prettyPrint(node, compiler).getText();
+      var code = jsAst.prettyPrint(node, compiler);
       var info = new ConstantInfo(
           size: size, code: code, outputUnit: _unitInfoForConstant(constant));
       _constantToInfo[constant] = info;
@@ -529,7 +529,7 @@
     // Concatenate rendered ASTs.
     StringBuffer sb = new StringBuffer();
     for (jsAst.Node ast in code) {
-      sb.writeln(jsAst.prettyPrint(ast, compiler).getText());
+      sb.writeln(jsAst.prettyPrint(ast, compiler));
     }
     return sb.toString();
   }
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index c25e955..469081c 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -11,6 +11,8 @@
     Compiler;
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart';
 import '../resolution/scope.dart' show
     Scope;
@@ -1430,7 +1432,7 @@
 
   /// Returns `true` if this class implements [Function] either by directly
   /// implementing the interface or by providing a [call] method.
-  bool implementsFunction(Compiler compiler);
+  bool implementsFunction(CoreClasses coreClasses);
 
   /// Returns `true` if this class extends [cls] directly or indirectly.
   ///
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 550b3c9..3f0d70c 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -13,6 +13,8 @@
 import '../constants/constant_constructors.dart';
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart';
 import '../diagnostics/messages.dart' show
     MessageTemplate;
@@ -2706,8 +2708,8 @@
     backendMembers.forEach(f);
   }
 
-  bool implementsFunction(Compiler compiler) {
-    return asInstanceOf(compiler.coreClasses.functionClass) != null ||
+  bool implementsFunction(CoreClasses coreClasses) {
+    return asInstanceOf(coreClasses.functionClass) != null ||
         callType != null;
   }
 
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index f897876..f9608ba 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -413,6 +413,9 @@
     FunctionSignature signature = function.functionSignature;
     signature.forEachOptionalParameter((ParameterElement element) {
       ast.Expression defaultValue = element.initializer;
+      // TODO(25566): The default value of a parameter of a redirecting factory
+      // constructor comes from the corresponding parameter of the target.
+
       // If this is a default value from a different context (because
       // the current function is synthetic, e.g., a constructor from
       // a mixin application), we have to start a new inferrer visitor
@@ -1482,54 +1485,50 @@
     return super.handleTypeLiteralInvoke(arguments);
   }
 
-  /// Handle constructor invocation of [element].
-  T handleConstructorSend(ast.Send node, ConstructorElement element) {
+  /// Handle constructor invocation of [constructor].
+  T handleConstructorSend(ast.Send node, ConstructorElement constructor) {
+    ConstructorElement target = constructor.implementation;
     ArgumentsTypes arguments = analyzeArguments(node.arguments);
     if (visitingInitializers) {
       if (ast.Initializers.isConstructorRedirect(node)) {
         isConstructorRedirect = true;
       } else if (ast.Initializers.isSuperConstructorCall(node)) {
         seenSuperConstructorCall = true;
-        analyzeSuperConstructorCall(element, arguments);
+        analyzeSuperConstructorCall(constructor, arguments);
       }
     }
-    // If we are looking at a new expression on a forwarding factory,
-    // we have to forward the call to the effective target of the
-    // factory.
-    if (element.isFactoryConstructor) {
-      // TODO(herhut): Remove the while loop once effectiveTarget forwards to
-      //               patches.
-      while (element.isFactoryConstructor) {
-        ConstructorElement constructor = element;
-        if (!constructor.isRedirectingFactory) break;
-        element = constructor.effectiveTarget.implementation;
-      }
+    // If we are looking at a new expression on a forwarding factory, we have to
+    // forward the call to the effective target of the factory.
+    // TODO(herhut): Remove the loop once effectiveTarget forwards to patches.
+    while (target.isFactoryConstructor) {
+      if (!target.isRedirectingFactory) break;
+      target = target.effectiveTarget.implementation;
     }
-    if (compiler.backend.isForeign(element)) {
-      return handleForeignSend(node, element);
+    if (compiler.backend.isForeign(target)) {
+      return handleForeignSend(node, target);
     }
     Selector selector = elements.getSelector(node);
     TypeMask mask = elements.getTypeMask(node);
     // In erroneous code the number of arguments in the selector might not
     // match the function element.
     // TODO(polux): return nonNullEmpty and check it doesn't break anything
-    if (!selector.applies(element, compiler.world) ||
-        (mask != null && !mask.canHit(element, selector, compiler.world))) {
+    if (!selector.applies(target, compiler.world) ||
+        (mask != null && !mask.canHit(target, selector, compiler.world))) {
       return types.dynamicType;
     }
 
-    T returnType = handleStaticSend(node, selector, mask, element, arguments);
-    if (Elements.isGrowableListConstructorCall(element, node, compiler)) {
+    T returnType = handleStaticSend(node, selector, mask, target, arguments);
+    if (Elements.isGrowableListConstructorCall(constructor, node, compiler)) {
       return inferrer.concreteTypes.putIfAbsent(
           node, () => types.allocateList(
               types.growableListType, node, outermostElement,
               types.nonNullEmpty(), 0));
-    } else if (Elements.isFixedListConstructorCall(element, node, compiler)
-        || Elements.isFilledListConstructorCall(element, node, compiler)) {
+    } else if (Elements.isFixedListConstructorCall(constructor, node, compiler)
+        || Elements.isFilledListConstructorCall(constructor, node, compiler)) {
 
       int length = findLength(node);
       T elementType =
-          Elements.isFixedListConstructorCall(element, node, compiler)
+          Elements.isFixedListConstructorCall(constructor, node, compiler)
               ? types.nullType
               : arguments.positional[1];
 
@@ -1537,15 +1536,14 @@
           node, () => types.allocateList(
               types.fixedListType, node, outermostElement,
               elementType, length));
-    } else if (Elements.isConstructorOfTypedArraySubclass(element, compiler)) {
+    } else if (
+        Elements.isConstructorOfTypedArraySubclass(constructor, compiler)) {
       int length = findLength(node);
-      ConstructorElement constructor = element.implementation;
-      constructor = constructor.effectiveTarget;
       T elementType = inferrer.returnTypeOfElement(
-          constructor.enclosingClass.lookupMember('[]'));
+          target.enclosingClass.lookupMember('[]'));
       return inferrer.concreteTypes.putIfAbsent(
         node, () => types.allocateList(
-          types.nonNullExact(constructor.enclosingClass), node,
+          types.nonNullExact(target.enclosingClass), node,
           outermostElement, elementType, length));
     } else {
       return returnType;
diff --git a/pkg/compiler/lib/src/io/code_output.dart b/pkg/compiler/lib/src/io/code_output.dart
index 967de65..7f5b996 100644
--- a/pkg/compiler/lib/src/io/code_output.dart
+++ b/pkg/compiler/lib/src/io/code_output.dart
@@ -102,8 +102,12 @@
   }
 }
 
+abstract class BufferedCodeOutput {
+  String getText();
+}
+
 /// [CodeOutput] using a [StringBuffer] as backend.
-class CodeBuffer extends AbstractCodeOutput {
+class CodeBuffer extends AbstractCodeOutput implements BufferedCodeOutput {
   StringBuffer buffer = new StringBuffer();
 
   @override
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 0e384c3..2ef185b 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -18,6 +18,8 @@
     Node,
     Send;
 
+import 'code_output.dart' show
+    CodeBuffer;
 import 'source_file.dart';
 import 'source_information.dart';
 
@@ -113,6 +115,32 @@
   SourceInformationProcessor createProcessor(SourceMapper mapper) {
     return new PositionSourceInformationProcessor(mapper);
   }
+
+  @override
+  void onComplete() {}
+
+  @override
+  SourceInformation buildSourceMappedMarker() {
+    return const SourceMappedMarker();
+  }
+}
+
+/// Marker used to tag the root nodes of source-mapped code.
+///
+/// This is needed to be able to distinguish JavaScript nodes that shouldn't
+/// have source locations (like the premable) from the nodes that should
+/// (like functions compiled from Dart code).
+class SourceMappedMarker extends SourceInformation {
+  const SourceMappedMarker();
+
+  @override
+  String get shortText => '';
+
+  @override
+  List<SourceLocation> get sourceLocations => const <SourceLocation>[];
+
+  @override
+  SourceSpan get sourceSpan => new SourceSpan(null, null, null);
 }
 
 /// [SourceInformationBuilder] that generates [PositionSourceInformation].
@@ -225,10 +253,31 @@
   final int closingPosition;
 
   CodePosition(this.startPosition, this.endPosition, this.closingPosition);
+
+  int getPosition(CodePositionKind kind) {
+    switch (kind) {
+      case CodePositionKind.START:
+        return startPosition;
+      case CodePositionKind.END:
+        return endPosition;
+      case CodePositionKind.CLOSING:
+        return closingPosition;
+    }
+  }
+
+  String toString() {
+    return 'CodePosition(start=$startPosition,'
+           'end=$endPosition,closing=$closingPosition)';
+  }
+}
+
+/// A map from a [js.Node] to its [CodePosition].
+abstract class CodePositionMap {
+  CodePosition operator [](js.Node node);
 }
 
 /// Registry for mapping [js.Node]s to their [CodePosition].
-class CodePositionRecorder {
+class CodePositionRecorder implements CodePositionMap {
   Map<js.Node, CodePosition> _codePositionMap =
       new Map<js.Node, CodePosition>.identity();
 
@@ -247,204 +296,107 @@
   CodePosition operator [](js.Node node) => _codePositionMap[node];
 }
 
+/// Enum values for the part of a Dart node used for the source location offset.
 enum SourcePositionKind {
+  /// The source mapping should point to the start of the Dart node.
+  ///
+  /// For instance the first '(' for the `(*)()` call and 'f' of both the
+  /// `foo()` and the `*.bar()` call:
+  ///
+  ///     (foo().bar())()
+  ///     ^                       // the start of the `(*)()` node
+  ///      ^                      // the start of the `foo()` node
+  ///      ^                      // the start of the `*.bar()` node
+  ///
   START,
-  CLOSING,
-  END,
+
+  /// The source mapping should point an inner position of the Dart node.
+  ///
+  /// For instance the second '(' of the `(*)()` call, the 'f' of the `foo()`
+  /// call and the 'b' of the `*.bar()` call:
+  ///
+  ///     (foo().bar())()
+  ///                  ^          // the inner position of the `(*)()` node
+  ///      ^                      // the inner position of the `foo()` node
+  ///            ^                // the inner position of the `*.bar()` node
+  ///
+  /// For function expressions the inner position is the closing brace or the
+  /// arrow:
+  ///
+  ///     foo() => () {}
+  ///           ^                 // the inner position of the 'foo' function
+  ///                  ^          // the inner position of the closure
+  ///
+  INNER,
 }
 
+SourceLocation getSourceLocation(
+    SourceInformation sourceInformation,
+    [SourcePositionKind sourcePositionKind = SourcePositionKind.START]) {
+  if (sourceInformation == null) return null;
+  switch (sourcePositionKind) {
+    case SourcePositionKind.START:
+      return sourceInformation.startPosition;
+    case SourcePositionKind.INNER:
+      return sourceInformation.closingPosition;
+  }
+}
+
+/// Enum values for the part of the JavaScript node used for the JavaScript
+/// code offset of a source mapping.
 enum CodePositionKind {
+  /// The source mapping is put on left-most offset of the node.
+  ///
+  /// For instance on the 'f' of a function or 'r' of a return statement:
+  ///
+  ///     foo: function() { return 0; }
+  ///          ^                              // the function start position
+  ///                       ^                 // the return start position
   START,
+
+  /// The source mapping is put on the closing token.
+  ///
+  /// For instance on the '}' of a function or the ';' of a return statement:
+  ///
+  ///     foo: function() { return 0; }
+  ///                                 ^       // the function closing position
+  ///                               ^         // the return closing position
+  ///
   CLOSING,
+
+  /// The source mapping is put at the end of the code for the node.
+  ///
+  /// For instance after '}' of a function or after the ';' of a return
+  /// statement:
+  ///
+  ///     foo: function() { return 0; }
+  ///                                  ^       // the function end position
+  ///                                ^         // the return end position
+  ///
   END,
 }
 
 /// Processor that associates [SourceLocation]s from [SourceInformation] on
 /// [js.Node]s with the target offsets in a [SourceMapper].
-class PositionSourceInformationProcessor
-    extends js.BaseVisitor implements SourceInformationProcessor {
-  final CodePositionRecorder codePositions = new CodePositionRecorder();
-  final SourceMapper sourceMapper;
+class PositionSourceInformationProcessor implements SourceInformationProcessor {
+  final CodePositionRecorder codePositionRecorder = new CodePositionRecorder();
+  CodePositionMap codePositionMap;
+  List<TraceListener> traceListeners;
 
-  PositionSourceInformationProcessor(this.sourceMapper);
-
-  void process(js.Node node) {
-    node.accept(this);
-  }
-
-  void visitChildren(js.Node node) {
-    node.visitChildren(this);
-  }
-
-  CodePosition getCodePosition(js.Node node) {
-    return codePositions[node];
-  }
-
-  /// Associates [sourceInformation] with the JavaScript [node].
-  ///
-  /// The offset into the JavaScript code is computed by pulling the
-  /// [codePositionKind] from the code positions associated with
-  /// [codePositionNode].
-  ///
-  /// The mapped Dart source location is computed by pulling the
-  /// [sourcePositionKind] source location from [sourceInformation].
-  void apply(js.Node node,
-             js.Node codePositionNode,
-             CodePositionKind codePositionKind,
-             SourceInformation sourceInformation,
-             SourcePositionKind sourcePositionKind) {
-    if (sourceInformation != null) {
-      CodePosition codePosition = getCodePosition(codePositionNode);
-      // We should always have recorded the needed code positions.
-      assert(invariant(
-          NO_LOCATION_SPANNABLE,
-          codePosition != null,
-          message:
-            "Code position missing for "
-            "${nodeToString(codePositionNode)}:\n"
-            "${DebugPrinter.prettyPrint(node)}"));
-      if (codePosition == null) return;
-      int codeLocation;
-      SourceLocation sourceLocation;
-      switch (codePositionKind) {
-        case CodePositionKind.START:
-          codeLocation = codePosition.startPosition;
-          break;
-        case CodePositionKind.CLOSING:
-          codeLocation = codePosition.closingPosition;
-          break;
-        case CodePositionKind.END:
-          codeLocation = codePosition.endPosition;
-          break;
-      }
-      switch (sourcePositionKind) {
-        case SourcePositionKind.START:
-          sourceLocation = sourceInformation.startPosition;
-          break;
-        case SourcePositionKind.CLOSING:
-          sourceLocation = sourceInformation.closingPosition;
-          break;
-        case SourcePositionKind.END:
-          sourceLocation = sourceInformation.endPosition;
-          break;
-      }
-      if (codeLocation != null && sourceLocation != null) {
-        sourceMapper.register(node, codeLocation, sourceLocation);
-      }
+  PositionSourceInformationProcessor(
+      SourceMapper sourceMapper,
+      [Coverage coverage]) {
+    codePositionMap = coverage != null
+              ? new CodePositionCoverage(codePositionRecorder, coverage)
+              : codePositionRecorder;
+    traceListeners = [new PositionTraceListener(sourceMapper)];
+    if (coverage != null) {
+      traceListeners.add(new CoverageListener(coverage));
     }
   }
 
-  @override
-  visitNode(js.Node node) {
-    SourceInformation sourceInformation = node.sourceInformation;
-    if (sourceInformation != null) {
-      /// Associates the left-most position of the JS code with the left-most
-      /// position of the Dart code.
-      apply(node,
-          node, CodePositionKind.START,
-          sourceInformation, SourcePositionKind.START);
-    }
-    visitChildren(node);
-  }
-
-  @override
-  visitFun(js.Fun node) {
-    SourceInformation sourceInformation = node.sourceInformation;
-    if (sourceInformation != null) {
-      /// Associates the end brace of the JavaScript function with the end brace
-      /// of the Dart function (or the `;` in case of arrow notation).
-      apply(node,
-          node, CodePositionKind.CLOSING,
-          sourceInformation, SourcePositionKind.CLOSING);
-    }
-
-    visitChildren(node);
-  }
-
-  @override
-  visitExpressionStatement(js.ExpressionStatement node) {
-    visitChildren(node);
-  }
-
-  @override
-  visitBinary(js.Binary node) {
-    visitChildren(node);
-  }
-
-  @override
-  visitAccess(js.PropertyAccess node) {
-    visitChildren(node);
-  }
-
-  @override
-  visitCall(js.Call node) {
-    SourceInformation sourceInformation = node.sourceInformation;
-    if (sourceInformation != null) {
-      if (node.target is js.PropertyAccess) {
-        js.PropertyAccess access = node.target;
-        js.Node target = access;
-        bool pureAccess = false;
-        while (target is js.PropertyAccess) {
-          js.PropertyAccess targetAccess = target;
-          if (targetAccess.receiver is js.VariableUse ||
-              targetAccess.receiver is js.This) {
-            pureAccess = true;
-            break;
-          } else {
-            target = targetAccess.receiver;
-          }
-        }
-        if (pureAccess) {
-          // a.m()   this.m()  a.b.c.d.m()
-          // ^       ^         ^
-          apply(
-              node,
-              node,
-              CodePositionKind.START,
-              sourceInformation,
-              SourcePositionKind.START);
-        } else {
-          // *.m()  *.a.b.c.d.m()
-          //   ^              ^
-          apply(
-              node,
-              access.selector,
-              CodePositionKind.START,
-              sourceInformation,
-              SourcePositionKind.CLOSING);
-        }
-      } else if (node.target is js.VariableUse) {
-        // m()
-        // ^
-        apply(
-            node,
-            node,
-            CodePositionKind.START,
-            sourceInformation,
-            SourcePositionKind.START);
-      } else if (node.target is js.Fun || node.target is js.New) {
-        // function(){}()  new Function("...")()
-        //             ^                      ^
-        apply(
-            node,
-            node.target,
-            CodePositionKind.END,
-            sourceInformation,
-            SourcePositionKind.CLOSING);
-      } else {
-        assert(invariant(NO_LOCATION_SPANNABLE, false,
-            message: "Unexpected property access ${nodeToString(node)}:\n"
-                     "${DebugPrinter.prettyPrint(node)}"));
-        // Don't know....
-        apply(
-            node,
-            node,
-            CodePositionKind.START,
-            sourceInformation,
-            SourcePositionKind.START);
-      }
-    }
-    visitChildren(node);
+  void process(js.Node node, CodeBuffer codeBuffer) {
+    new JavaScriptTracer(codePositionMap, traceListeners).apply(node);
   }
 
   @override
@@ -452,7 +404,776 @@
                    int startPosition,
                    int endPosition,
                    int closingPosition) {
-    codePositions.registerPositions(
+    codePositionRecorder.registerPositions(
         node, startPosition, endPosition, closingPosition);
   }
 }
+
+/// [TraceListener] that register [SourceLocation]s with a [SourceMapper].
+class PositionTraceListener extends TraceListener {
+  final SourceMapper sourceMapper;
+
+  PositionTraceListener(this.sourceMapper);
+
+  @override
+  void onStep(js.Node node, Offset offset, StepKind kind) {
+    SourceInformation sourceInformation = node.sourceInformation;
+    if (sourceInformation == null) return;
+
+    SourcePositionKind sourcePositionKind = SourcePositionKind.START;
+    switch (kind) {
+      case StepKind.FUN:
+        sourcePositionKind = SourcePositionKind.INNER;
+        break;
+      case StepKind.CALL:
+        CallPosition callPosition =
+            CallPosition.getSemanticPositionForCall(node);
+        sourcePositionKind = callPosition.sourcePositionKind;
+        break;
+      case StepKind.NEW:
+      case StepKind.RETURN:
+      case StepKind.BREAK:
+      case StepKind.CONTINUE:
+      case StepKind.THROW:
+      case StepKind.EXPRESSION_STATEMENT:
+      case StepKind.IF_CONDITION:
+      case StepKind.FOR_INITIALIZER:
+      case StepKind.FOR_CONDITION:
+      case StepKind.FOR_UPDATE:
+      case StepKind.WHILE_CONDITION:
+      case StepKind.DO_CONDITION:
+      case StepKind.SWITCH_EXPRESSION:
+        break;
+    }
+    int codeLocation = offset.subexpressionOffset;
+    SourceLocation sourceLocation =
+        getSourceLocation(sourceInformation, sourcePositionKind);
+    if (codeLocation != null && sourceLocation != null) {
+      sourceMapper.register(node, codeLocation, sourceLocation);
+    }
+  }
+}
+
+/// The position of a [js.Call] node.
+class CallPosition {
+  final js.Node node;
+  final CodePositionKind codePositionKind;
+  final SourcePositionKind sourcePositionKind;
+
+  CallPosition(this.node, this.codePositionKind, this.sourcePositionKind);
+
+  /// Computes the [CallPosition] for [node].
+  static CallPosition getSemanticPositionForCall(js.Call node) {
+    if (node.target is js.PropertyAccess) {
+      js.PropertyAccess access = node.target;
+      js.Node target = access;
+      bool pureAccess = false;
+      while (target is js.PropertyAccess) {
+        js.PropertyAccess targetAccess = target;
+        if (targetAccess.receiver is js.VariableUse ||
+            targetAccess.receiver is js.This) {
+          pureAccess = true;
+          break;
+        } else {
+          target = targetAccess.receiver;
+        }
+      }
+      if (pureAccess) {
+        // a.m()   this.m()  a.b.c.d.m()
+        // ^       ^         ^
+        return new CallPosition(
+            node,
+            CodePositionKind.START,
+            SourcePositionKind.START);
+      } else {
+        // *.m()  *.a.b.c.d.m()
+        //   ^              ^
+        return new CallPosition(
+            access.selector,
+            CodePositionKind.START,
+            SourcePositionKind.INNER);
+      }
+    } else if (node.target is js.VariableUse) {
+      // m()
+      // ^
+      return new CallPosition(
+          node,
+          CodePositionKind.START,
+          SourcePositionKind.START);
+    } else if (node.target is js.Fun || node.target is js.New) {
+      // function(){}()  new Function("...")()
+      //             ^                      ^
+      return new CallPosition(
+          node.target,
+          CodePositionKind.END,
+          SourcePositionKind.INNER);
+    } else if (node.target is js.Binary || node.target is js.Call) {
+      // (0,a)()   m()()
+      //      ^       ^
+      return new CallPosition(
+          node.target,
+          CodePositionKind.END,
+          SourcePositionKind.INNER);
+    } else {
+      assert(invariant(NO_LOCATION_SPANNABLE, false,
+          message: "Unexpected property access ${nodeToString(node)}:\n"
+                   "${DebugPrinter.prettyPrint(node)}"));
+      // Don't know....
+      return new CallPosition(
+          node,
+          CodePositionKind.START,
+          SourcePositionKind.START);
+    }
+  }
+}
+
+class Offset {
+  /// The offset of the enclosing statement relative to the beginning of the
+  /// file.
+  ///
+  /// For instance:
+  ///
+  ///     foo().bar(baz());
+  ///     ^                  // the statement offset of the `foo()` call
+  ///     ^                  // the statement offset of the `*.bar()` call
+  ///     ^                  // the statement offset of the `baz()` call
+  ///
+  final int statementOffset;
+
+  /// The `subexpression` offset of the step. This is the (mostly) unique
+  /// offset relative to the beginning of the file, that identifies the
+  /// current of execution.
+  ///
+  /// For instance:
+  ///
+  ///     foo().bar(baz());
+  ///     ^                   // the subexpression offset of the `foo()` call
+  ///           ^             // the subexpression offset of the `*.bar()` call
+  ///               ^         // the subexpression offset of the `baz()` call
+  ///
+  /// Here, even though the JavaScript node for the `*.bar()` call contains
+  /// the `foo()` its execution is identified by the `bar` identifier more than
+  /// the foo identifier.
+  ///
+  final int subexpressionOffset;
+
+  /// The `left-to-right` offset of the step. This is like [subexpressionOffset]
+  /// bute restricted so that the offset of each subexpression in execution
+  /// order is monotonically increasing.
+  ///
+  /// For instance:
+  ///
+  ///     foo().bar(baz());
+  ///     ^                   // the left-to-right offset of the `foo()` call
+  ///           ^             // the left-to-right offset of the `*.bar()` call
+  ///     ^                   // the left-to-right offset of the `baz()` call
+  ///
+  /// Here, `baz()` is executed before `foo()` so we need to use 'f' as its best
+  /// position under the restriction.
+  ///
+  final int leftToRightOffset;
+
+  Offset(this.statementOffset, this.leftToRightOffset, this.subexpressionOffset);
+
+  String toString() {
+    return 'Offset[statementOffset=$statementOffset,'
+        'leftToRightOffset=$leftToRightOffset,'
+        'subexpressionOffset=$subexpressionOffset]';
+  }
+}
+
+enum BranchKind {
+  CONDITION,
+  LOOP,
+  CATCH,
+  FINALLY,
+  CASE,
+}
+
+enum StepKind {
+  FUN,
+  CALL,
+  NEW,
+  RETURN,
+  BREAK,
+  CONTINUE,
+  THROW,
+  EXPRESSION_STATEMENT,
+  IF_CONDITION,
+  FOR_INITIALIZER,
+  FOR_CONDITION,
+  FOR_UPDATE,
+  WHILE_CONDITION,
+  DO_CONDITION,
+  SWITCH_EXPRESSION,
+}
+
+/// Listener for the [JavaScriptTracer].
+abstract class TraceListener {
+  /// Called before [root] node is procesed by the [JavaScriptTracer].
+  void onStart(js.Node root) {}
+
+  /// Called after [root] node has been procesed by the [JavaScriptTracer].
+  void onEnd(js.Node root) {}
+
+  /// Called when a branch of the given [kind] is started. [value] is provided
+  /// to distinguish true/false branches of [BranchKind.CONDITION] and cases of
+  /// [Branch.CASE].
+  void pushBranch(BranchKind kind, [value]) {}
+
+  /// Called when the current branch ends.
+  void popBranch() {}
+
+  /// Called when [node] defines a step of the given [kind] at the given
+  /// [offset] when the generated JavaScript code.
+  void onStep(js.Node node, Offset offset, StepKind kind) {}
+}
+
+/// Visitor that computes the [js.Node]s the are part of the JavaScript
+/// steppable execution and thus needs source mapping locations.
+class JavaScriptTracer extends js.BaseVisitor  {
+  final CodePositionMap codePositions;
+  final List<TraceListener> listeners;
+
+  /// The steps added by subexpressions.
+  List steps = [];
+
+  /// The offset of the current statement.
+  int statementOffset;
+
+  /// The current offset in left-to-right progression.
+  int leftToRightOffset;
+
+  /// The offset of the surrounding statement, used for the first subexpression.
+  int offsetPosition;
+
+  bool active;
+
+  JavaScriptTracer(this.codePositions,
+           this.listeners,
+           {this.active: false});
+
+  void notifyStart(js.Node node) {
+    listeners.forEach((listener) => listener.onStart(node));
+  }
+
+  void notifyEnd(js.Node node) {
+    listeners.forEach((listener) => listener.onEnd(node));
+  }
+
+  void notifyPushBranch(BranchKind kind, [value]) {
+    if (active) {
+      listeners.forEach((listener) => listener.pushBranch(kind, value));
+    }
+  }
+
+  void notifyPopBranch() {
+    if (active) {
+      listeners.forEach((listener) => listener.popBranch());
+    }
+  }
+
+  void notifyStep(js.Node node, Offset offset, StepKind kind) {
+    if (active) {
+      listeners.forEach((listener) => listener.onStep(node, offset, kind));
+    }
+  }
+
+  void apply(js.Node node) {
+    notifyStart(node);
+    node.accept(this);
+    notifyEnd(node);
+  }
+
+  @override
+  visitNode(js.Node node) {
+    node.visitChildren(this);
+  }
+
+  visit(js.Node node, [BranchKind branch, value]) {
+    if (node != null) {
+      if (branch != null) {
+        notifyPushBranch(branch, value);
+        node.accept(this);
+        notifyPopBranch();
+      } else {
+        node.accept(this);
+      }
+    }
+  }
+
+  visitList(List<js.Node> nodeList) {
+    if (nodeList != null) {
+      for (js.Node node in nodeList) {
+        visit(node);
+      }
+    }
+  }
+
+  @override
+  visitFun(js.Fun node) {
+    bool activeBefore = active;
+    if (!active) {
+      active = node.sourceInformation != null;
+    }
+    visit(node.body);
+    leftToRightOffset = statementOffset =
+        getSyntaxOffset(node, kind: CodePositionKind.CLOSING);
+    Offset offset = getOffsetForNode(node, statementOffset);
+    notifyStep(node, offset, StepKind.FUN);
+    active = activeBefore;
+  }
+
+  @override
+  visitBlock(js.Block node) {
+    for (js.Statement statement in node.statements) {
+      visit(statement);
+    }
+  }
+
+  int getSyntaxOffset(js.Node node,
+                      {CodePositionKind kind: CodePositionKind.START}) {
+    CodePosition codePosition = codePositions[node];
+    if (codePosition != null) {
+      return codePosition.getPosition(kind);
+    }
+    return null;
+  }
+
+  visitSubexpression(js.Node parent,
+                     js.Expression child,
+                     int codeOffset,
+                     StepKind kind) {
+    var oldSteps = steps;
+    steps = [];
+    offsetPosition = codeOffset;
+    visit(child);
+    if (steps.isEmpty) {
+      notifyStep(parent,
+          getOffsetForNode(parent, offsetPosition),
+          kind);
+    }
+    steps = oldSteps;
+  }
+
+  @override
+  visitExpressionStatement(js.ExpressionStatement node) {
+    statementOffset = getSyntaxOffset(node);
+    visitSubexpression(
+        node, node.expression, statementOffset,
+        StepKind.EXPRESSION_STATEMENT);
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitEmptyStatement(js.EmptyStatement node) {}
+
+  @override
+  visitCall(js.Call node) {
+    visit(node.target);
+    int oldPosition = offsetPosition;
+    offsetPosition = null;
+    visitList(node.arguments);
+    offsetPosition = oldPosition;
+    CallPosition callPosition =
+        CallPosition.getSemanticPositionForCall(node);
+    js.Node positionNode = callPosition.node;
+    int callOffset = getSyntaxOffset(
+        positionNode, kind: callPosition.codePositionKind);
+    if (offsetPosition == null) {
+      offsetPosition = callOffset;
+    }
+    Offset offset = getOffsetForNode(positionNode, offsetPosition);
+    notifyStep(node, offset, StepKind.CALL);
+    steps.add(node);
+    offsetPosition = null;
+  }
+
+  @override
+  visitNew(js.New node) {
+    visit(node.target);
+    visitList(node.arguments);
+    notifyStep(
+        node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.NEW);
+    steps.add(node);
+    offsetPosition = null;
+  }
+
+  @override
+  visitAccess(js.PropertyAccess node) {
+    visit(node.receiver);
+    visit(node.selector);
+  }
+
+  @override
+  visitVariableUse(js.VariableUse node) {}
+
+  @override
+  visitLiteralBool(js.LiteralBool node) {}
+
+  @override
+  visitLiteralString(js.LiteralString node) {}
+
+  @override
+  visitLiteralNumber(js.LiteralNumber node) {}
+
+  @override
+  visitLiteralNull(js.LiteralNull node) {}
+
+  @override
+  visitName(js.Name node) {}
+
+  @override
+  visitVariableDeclarationList(js.VariableDeclarationList node) {
+    visitList(node.declarations);
+  }
+
+  @override
+  visitVariableDeclaration(js.VariableDeclaration node) {}
+
+  @override
+  visitVariableInitialization(js.VariableInitialization node) {
+    visit(node.leftHandSide);
+    visit(node.value);
+  }
+
+  @override
+  visitAssignment(js.Assignment node) {
+    visit(node.leftHandSide);
+    visit(node.value);
+  }
+
+  @override
+  visitIf(js.If node) {
+    statementOffset = getSyntaxOffset(node);
+    visitSubexpression(node, node.condition, statementOffset,
+        StepKind.IF_CONDITION);
+    statementOffset = null;
+    visit(node.then, BranchKind.CONDITION, true);
+    visit(node.otherwise, BranchKind.CONDITION, false);
+  }
+
+  @override
+  visitFor(js.For node) {
+    int offset = statementOffset = getSyntaxOffset(node);
+    statementOffset = offset;
+    leftToRightOffset = null;
+    if (node.init != null) {
+      visitSubexpression(node, node.init, getSyntaxOffset(node),
+          StepKind.FOR_INITIALIZER);
+    }
+
+    if (node.condition != null) {
+      visitSubexpression(node, node.condition, getSyntaxOffset(node.condition),
+          StepKind.FOR_CONDITION);
+    }
+
+    notifyPushBranch(BranchKind.LOOP);
+    visit(node.body);
+
+    statementOffset = offset;
+    if (node.update != null) {
+      visitSubexpression(node, node.update, getSyntaxOffset(node.update),
+          StepKind.FOR_UPDATE);
+    }
+
+    notifyPopBranch();
+  }
+
+  @override
+  visitWhile(js.While node) {
+    statementOffset = getSyntaxOffset(node);
+    if (node.condition != null) {
+      visitSubexpression(node, node.condition, getSyntaxOffset(node.condition),
+          StepKind.WHILE_CONDITION);
+    }
+    statementOffset = null;
+    leftToRightOffset = null;
+
+    visit(node.body, BranchKind.LOOP);
+  }
+
+  @override
+  visitDo(js.Do node) {
+    statementOffset = getSyntaxOffset(node);
+    visit(node.body);
+    if (node.condition != null) {
+      visitSubexpression(node, node.condition, getSyntaxOffset(node.condition),
+          StepKind.DO_CONDITION);
+    }
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitBinary(js.Binary node) {
+    visit(node.left);
+    visit(node.right);
+  }
+
+  @override
+  visitThis(js.This node) {}
+
+  @override
+  visitReturn(js.Return node) {
+    statementOffset = getSyntaxOffset(node);
+    visit(node.value);
+    notifyStep(
+        node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.RETURN);
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitThrow(js.Throw node) {
+    statementOffset = getSyntaxOffset(node);
+    visit(node.expression);
+    notifyStep(
+        node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.THROW);
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitContinue(js.Continue node) {
+    statementOffset = getSyntaxOffset(node);
+    notifyStep(
+        node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.CONTINUE);
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitBreak(js.Break node) {
+    statementOffset = getSyntaxOffset(node);
+    notifyStep(
+        node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.BREAK);
+    statementOffset = null;
+    leftToRightOffset = null;
+  }
+
+  @override
+  visitTry(js.Try node) {
+    visit(node.body);
+    visit(node.catchPart, BranchKind.CATCH);
+    visit(node.finallyPart, BranchKind.FINALLY);
+  }
+
+  @override
+  visitCatch(js.Catch node) {
+    visit(node.body);
+  }
+
+  @override
+  visitConditional(js.Conditional node) {
+    visit(node.condition);
+    visit(node.then, BranchKind.CONDITION, true);
+    visit(node.otherwise, BranchKind.CONDITION, false);
+  }
+
+  @override
+  visitPrefix(js.Prefix node) {
+    visit(node.argument);
+  }
+
+  @override
+  visitPostfix(js.Postfix node) {
+    visit(node.argument);
+  }
+
+  @override
+  visitObjectInitializer(js.ObjectInitializer node) {
+    visitList(node.properties);
+  }
+
+  @override
+  visitProperty(js.Property node) {
+    visit(node.name);
+    visit(node.value);
+  }
+
+  @override
+  visitRegExpLiteral(js.RegExpLiteral node) {}
+
+  @override
+  visitSwitch(js.Switch node) {
+    statementOffset = getSyntaxOffset(node);
+    visitSubexpression(node, node.key, getSyntaxOffset(node),
+        StepKind.SWITCH_EXPRESSION);
+    statementOffset = null;
+    leftToRightOffset = null;
+    for (int i = 0; i < node.cases.length; i++) {
+      visit(node.cases[i], BranchKind.CASE, i);
+    }
+  }
+
+  @override
+  visitCase(js.Case node) {
+    visit(node.expression);
+    visit(node.body);
+  }
+
+  @override
+  visitDefault(js.Default node) {
+    visit(node.body);
+  }
+
+  @override
+  visitArrayInitializer(js.ArrayInitializer node) {
+    visitList(node.elements);
+  }
+
+  @override
+  visitArrayHole(js.ArrayHole node) {}
+
+  @override
+  visitLabeledStatement(js.LabeledStatement node) {
+    statementOffset = getSyntaxOffset(node);
+    visit(node.body);
+    statementOffset = null;
+  }
+
+  Offset getOffsetForNode(js.Node node, int codeOffset) {
+    if (codeOffset == null) {
+      CodePosition codePosition = codePositions[node];
+      if (codePosition != null) {
+        codeOffset = codePosition.startPosition;
+      }
+    }
+    if (leftToRightOffset != null && leftToRightOffset < codeOffset) {
+      leftToRightOffset = codeOffset;
+    }
+    if (leftToRightOffset == null) {
+      leftToRightOffset = statementOffset;
+    }
+    return new Offset(statementOffset, leftToRightOffset, codeOffset);
+  }
+}
+
+
+class Coverage {
+  Set<js.Node> _nodesWithInfo = new Set<js.Node>();
+  int _nodesWithInfoCount = 0;
+  Set<js.Node> _nodesWithoutInfo = new Set<js.Node>();
+  int _nodesWithoutInfoCount = 0;
+  Map<Type, int> _nodesWithoutInfoCountByType = <Type, int>{};
+  Set<js.Node> _nodesWithoutOffset = new Set<js.Node>();
+  int _nodesWithoutOffsetCount = 0;
+
+  void registerNodeWithInfo(js.Node node) {
+    _nodesWithInfo.add(node);
+  }
+
+  void registerNodeWithoutInfo(js.Node node) {
+    _nodesWithoutInfo.add(node);
+  }
+
+  void registerNodesWithoutOffset(js.Node node) {
+    _nodesWithoutOffset.add(node);
+  }
+
+  void collapse() {
+    _nodesWithInfoCount += _nodesWithInfo.length;
+    _nodesWithInfo.clear();
+    _nodesWithoutOffsetCount += _nodesWithoutOffset.length;
+    _nodesWithoutOffset.clear();
+
+    _nodesWithoutInfoCount += _nodesWithoutInfo.length;
+    for (js.Node node in _nodesWithoutInfo) {
+      if (node is js.ExpressionStatement) {
+        _nodesWithoutInfoCountByType.putIfAbsent(
+            node.expression.runtimeType, () => 0);
+        _nodesWithoutInfoCountByType[node.expression.runtimeType]++;
+      } else {
+        _nodesWithoutInfoCountByType.putIfAbsent(
+            node.runtimeType, () => 0);
+        _nodesWithoutInfoCountByType[node.runtimeType]++;
+      }
+    }
+    _nodesWithoutInfo.clear();
+  }
+
+  String getCoverageReport() {
+    collapse();
+    StringBuffer sb = new StringBuffer();
+    int total = _nodesWithInfoCount + _nodesWithoutInfoCount;
+    if (total > 0) {
+      sb.write(_nodesWithoutInfoCount);
+      sb.write('/');
+      sb.write(total);
+      sb.write(' (');
+      sb.write((100.0 * _nodesWithInfoCount / total).toStringAsFixed(2));
+      sb.write('%) nodes with info.');
+    } else {
+      sb.write('No nodes.');
+    }
+    if (_nodesWithoutOffsetCount > 0) {
+      sb.write(' ');
+      sb.write(_nodesWithoutOffsetCount);
+      sb.write(' node');
+      if (_nodesWithoutOffsetCount > 1) {
+        sb.write('s');
+      }
+      sb.write(' without offset.');
+    }
+    if (_nodesWithoutInfoCount > 0) {
+      sb.write('\nNodes without info (');
+      sb.write(_nodesWithoutInfoCount);
+      sb.write(') by runtime type:');
+      _nodesWithoutInfoCountByType.forEach((Type type, int count) {
+        sb.write('\n ');
+        sb.write(count);
+        sb.write(' ');
+        sb.write(type);
+        sb.write(' node');
+        if (count > 1) {
+          sb.write('s');
+        }
+      });
+      sb.write('\n');
+    }
+    return sb.toString();
+  }
+
+  String toString() => getCoverageReport();
+}
+
+/// [TraceListener] that registers [onStep] callbacks with [coverage].
+class CoverageListener extends TraceListener {
+  final Coverage coverage;
+
+  CoverageListener(this.coverage);
+
+  @override
+  void onStep(js.Node node, Offset offset, StepKind kind) {
+    SourceInformation sourceInformation = node.sourceInformation;
+    if (sourceInformation != null) {
+      coverage.registerNodeWithInfo(node);
+    } else {
+      coverage.registerNodeWithoutInfo(node);
+    }
+  }
+
+  @override
+  void onEnd(js.Node node) {
+    coverage.collapse();
+  }
+}
+
+/// [CodePositionMap] that registers calls with [Coverage].
+class CodePositionCoverage implements CodePositionMap {
+  final CodePositionMap codePositions;
+  final Coverage coverage;
+
+  CodePositionCoverage(this.codePositions, this.coverage);
+
+  @override
+  CodePosition operator [](js.Node node) {
+    CodePosition codePosition = codePositions[node];
+    if (codePosition == null) {
+      coverage.registerNodesWithoutOffset(node);
+   }
+    return codePosition;
+  }
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index 1855755..0138b41 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -21,6 +21,8 @@
 /// Interface for passing source information, for instance for use in source
 /// maps, through the backend.
 abstract class SourceInformation extends JavaScriptNodeSourceInformation {
+  const SourceInformation();
+
   SourceSpan get sourceSpan;
 
   /// The source location associated with the start of the JS node.
@@ -47,6 +49,12 @@
   SourceInformationBuilder createBuilderForContext(AstElement element) {
     return const SourceInformationBuilder();
   }
+
+  /// Generate [SourceInformation] marker for non-preamble code.
+  SourceInformation buildSourceMappedMarker() => null;
+
+  /// Called when compilation has completed.
+  void onComplete() {}
 }
 
 /// Interface for generating [SourceInformation].
diff --git a/pkg/compiler/lib/src/io/start_end_information.dart b/pkg/compiler/lib/src/io/start_end_information.dart
index 988c77d..8cae566 100644
--- a/pkg/compiler/lib/src/io/start_end_information.dart
+++ b/pkg/compiler/lib/src/io/start_end_information.dart
@@ -116,7 +116,7 @@
 }
 
 class StartEndSourceInformationStrategy
-    implements JavaScriptSourceInformationStrategy {
+    extends JavaScriptSourceInformationStrategy {
   const StartEndSourceInformationStrategy();
 
   @override
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 3a9fd2e..df510a8 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -20,12 +20,30 @@
 
 import 'js_source_mapping.dart';
 
-CodeBuffer prettyPrint(Node node,
-                       Compiler compiler,
-                       {DumpInfoTask monitor,
-                        bool allowVariableMinification: true,
-                        Renamer renamerForNames:
-                            JavaScriptPrintingOptions.identityRenamer}) {
+String prettyPrint(
+    Node node,
+    Compiler compiler,
+    {bool allowVariableMinification: true,
+     Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) {
+  // TODO(johnniwinther): Do we need all the options here?
+  JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
+      shouldCompressOutput: compiler.enableMinification,
+      minifyLocalVariables: allowVariableMinification,
+      preferSemicolonToNewlineInMinifiedOutput: USE_LAZY_EMITTER,
+      renamerForNames: renamerForNames);
+  SimpleJavaScriptPrintingContext context =
+      new SimpleJavaScriptPrintingContext();
+  Printer printer = new Printer(options, context);
+  printer.visit(node);
+  return context.getText();
+}
+
+CodeBuffer createCodeBuffer(
+    Node node,
+    Compiler compiler,
+    {DumpInfoTask monitor,
+     bool allowVariableMinification: true,
+     Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) {
   JavaScriptSourceInformationStrategy sourceInformationFactory =
       compiler.backend.sourceInformationStrategy;
   JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
@@ -35,14 +53,14 @@
       renamerForNames: renamerForNames);
   CodeBuffer outBuffer = new CodeBuffer();
   SourceInformationProcessor sourceInformationProcessor =
-      sourceInformationFactory.createProcessor(
-          new SourceLocationsMapper(outBuffer));
+        sourceInformationFactory.createProcessor(
+            new SourceLocationsMapper(outBuffer));
   Dart2JSJavaScriptPrintingContext context =
       new Dart2JSJavaScriptPrintingContext(
           compiler.reporter, monitor, outBuffer, sourceInformationProcessor);
   Printer printer = new Printer(options, context);
   printer.visit(node);
-  sourceInformationProcessor.process(node);
+  sourceInformationProcessor.process(node, outBuffer);
   return outBuffer;
 }
 
@@ -137,13 +155,13 @@
   /// A [js.Literal] that represents the string result of unparsing [ast].
   ///
   /// When its string [value] is requested, the node pretty-prints the given
-  /// [ast] and, if [protectForEval] is true, wraps the resulting
-  /// string in parenthesis. The result is also escaped.
+  /// [ast] and, if [protectForEval] is true, wraps the resulting string in
+  /// parenthesis. The result is also escaped.
   UnparsedNode(this.tree, this._compiler, this._protectForEval);
 
   LiteralString get _literal {
     if (_cachedLiteral == null) {
-      String text = prettyPrint(tree, _compiler).getText();
+      String text = prettyPrint(tree, _compiler);
       if (_protectForEval) {
         if (tree is Fun) text = '($text)';
         if (tree is LiteralExpression) {
@@ -164,6 +182,12 @@
   String get value => _literal.value;
 }
 
+/// True if the given template consists of just a placeholder. Such templates
+/// are sometimes used to manually promote the type of an expression.
+bool isIdentityTemplate(Template template) {
+  return template.ast is InterpolatedExpression;
+}
+
 /// Returns `true` if [template] will immediately give a TypeError if the first
 /// placeholder is `null` or `undefined`.
 bool isNullGuardOnFirstArgument(Template template) {
diff --git a/pkg/compiler/lib/src/js/js_debug.dart b/pkg/compiler/lib/src/js/js_debug.dart
index 43ec130..c8cbd0de 100644
--- a/pkg/compiler/lib/src/js/js_debug.dart
+++ b/pkg/compiler/lib/src/js/js_debug.dart
@@ -7,7 +7,12 @@
 library js.debug;
 
 import 'package:js_ast/js_ast.dart';
-import '../util/util.dart' show Indentation, Tagging;
+
+import '../io/code_output.dart' show
+    BufferedCodeOutput;
+import '../util/util.dart' show
+    Indentation,
+    Tagging;
 
 /// Unparse the JavaScript [node].
 String nodeToString(Node node) {
@@ -25,8 +30,8 @@
 class DebugPrinter extends BaseVisitor with Indentation, Tagging<Node> {
   StringBuffer sb = new StringBuffer();
 
-  void visitNodeWithChildren(Node node, String type) {
-    openNode(node, type);
+  void visitNodeWithChildren(Node node, String type, [Map params]) {
+    openNode(node, type, params);
     node.visitChildren(this);
     closeNode();
   }
@@ -42,6 +47,11 @@
   }
 
   @override
+  void visitBinary(Binary node) {
+    visitNodeWithChildren(node, '${node.runtimeType}', {'op': node.op});
+  }
+
+  @override
   void visitLiteralString(LiteralString node) {
     openAndCloseNode(node, '${node.runtimeType}', {'value': node.value});
   }
@@ -57,7 +67,8 @@
 }
 
 /// Simple printing context that doesn't throw on errors.
-class LenientPrintingContext extends SimpleJavaScriptPrintingContext {
+class LenientPrintingContext extends SimpleJavaScriptPrintingContext
+    implements BufferedCodeOutput {
   @override
   void error(String message) {
     buffer.write('>>$message<<');
diff --git a/pkg/compiler/lib/src/js/js_source_mapping.dart b/pkg/compiler/lib/src/js/js_source_mapping.dart
index 0378a58..cd72e35 100644
--- a/pkg/compiler/lib/src/js/js_source_mapping.dart
+++ b/pkg/compiler/lib/src/js/js_source_mapping.dart
@@ -5,7 +5,10 @@
 library js.source_mapping;
 
 import 'js.dart';
-import '../io/code_output.dart' show SourceLocations;
+import '../io/code_output.dart' show
+    BufferedCodeOutput,
+    CodeBuffer,
+    SourceLocations;
 import '../io/source_information.dart' show
     SourceLocation,
     SourceInformation,
@@ -64,5 +67,5 @@
 
   /// Process the source information and code positions for the [node] and all
   /// its children.
-  void process(Node node) {}
+  void process(Node node, BufferedCodeOutput code) {}
 }
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 05b00d1..7407ef7 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -502,7 +502,7 @@
 
   bool enabledNoSuchMethod = false;
 
-  final SourceInformationStrategy sourceInformationStrategy;
+  SourceInformationStrategy sourceInformationStrategy;
 
   final BackendHelpers helpers;
   final BackendImpacts impacts;
@@ -520,7 +520,7 @@
         this.sourceInformationStrategy =
             generateSourceMap
                 ? (useNewSourceInfo
-                     ? const PositionSourceInformationStrategy()
+                     ? new PositionSourceInformationStrategy()
                      : const StartEndSourceInformationStrategy())
                 : const JavaScriptSourceInformationStrategy(),
         helpers = new BackendHelpers(compiler),
@@ -940,14 +940,14 @@
 
   final Map<String, Set<ClassElement>> interceptedClassesCache =
       new Map<String, Set<ClassElement>>();
+  final Set<ClassElement> _noClasses = new Set<ClassElement>();
 
-  /**
-   * Returns a set of interceptor classes that contain a member named
-   * [name]. Returns [:null:] if there is no class.
-   */
+  /// Returns a set of interceptor classes that contain a member named [name]
+  ///
+  /// Returns an empty set if there is no class. Do not modify the returned set.
   Set<ClassElement> getInterceptedClassesOn(String name) {
     Set<Element> intercepted = interceptedElements[name];
-    if (intercepted == null) return null;
+    if (intercepted == null) return _noClasses;
     return interceptedClassesCache.putIfAbsent(name, () {
       // Populate the cache by running through all the elements and
       // determine if the given selector applies to them.
@@ -974,13 +974,12 @@
     Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin);
     Set<ClassElement> result = null;
     for (MixinApplicationElement use in uses) {
-      Iterable<ClassElement> subclasses = classWorld.strictSubclassesOf(use);
-      for (ClassElement subclass in subclasses) {
+      classWorld.forEachStrictSubclassOf(use, (ClassElement subclass) {
         if (isNativeOrExtendsNative(subclass)) {
           if (result == null) result = new Set<ClassElement>();
           result.add(subclass);
         }
-      }
+      });
     }
     return result;
   }
@@ -1251,6 +1250,10 @@
       addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry);
       addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry);
       addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry);
+      // Literal lists can be translated into calls to these functions:
+      enqueueInResolution(helpers.jsArrayTypedConstructor, registry);
+      enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
+      enqueueInResolution(helpers.getTypeArgumentByIndex, registry);
     } else if (cls == coreClasses.intClass ||
                cls == helpers.jsIntClass) {
       addInterceptors(helpers.jsIntClass, enqueuer, registry);
@@ -1630,7 +1633,12 @@
       }
     }
 
-    generatedCode[element] = functionCompiler.compile(work);
+    jsAst.Fun function = functionCompiler.compile(work);
+    if (function.sourceInformation == null) {
+      function = function.withSourceInformation(
+          sourceInformationStrategy.buildSourceMappedMarker());
+    }
+    generatedCode[element] = function;
     WorldImpact worldImpact =
         impactTransformer.transformCodegenImpact(work.registry.worldImpact);
     compiler.dumpInfoTask.registerImpact(element, worldImpact);
@@ -1661,7 +1669,7 @@
    */
   String getGeneratedCode(Element element) {
     assert(invariant(element, element.isDeclaration));
-    return jsAst.prettyPrint(generatedCode[element], compiler).getText();
+    return jsAst.prettyPrint(generatedCode[element], compiler);
   }
 
   int assembleProgram() {
@@ -2191,7 +2199,7 @@
         });
         // 4) all overriding members of subclasses/subtypes (should be resolved)
         if (compiler.world.hasAnyStrictSubtype(cls)) {
-          for (ClassElement subcls in compiler.world.strictSubtypesOf(cls)) {
+          compiler.world.forEachStrictSubtypeOf(cls, (ClassElement subcls) {
             subcls.forEachClassMember((Member member) {
               if (memberNames.contains(member.name)) {
                 // TODO(20993): find out why this assertion fails.
@@ -2202,7 +2210,7 @@
                 }
               }
             });
-          }
+          });
         }
         // 5) all its closures
         List<LocalFunctionElement> closures = closureMap[cls];
@@ -2509,13 +2517,13 @@
       compiler.enabledInvokeOn = true;
     }
   }
-
+/*
   CodeBuffer codeOf(Element element) {
     return generatedCode.containsKey(element)
         ? jsAst.prettyPrint(generatedCode[element], compiler)
         : null;
   }
-
+*/
   FunctionElement helperForBadMain() => helpers.badMain;
 
   FunctionElement helperForMissingMain() => helpers.missingMain;
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index f25e13b..29e6743 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -652,4 +652,4 @@
     }
     return _closure;
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index bc8ed93..1815ee2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -91,7 +91,10 @@
   js.Fun buildFunction(tree_ir.FunctionDefinition function) {
     registerDefaultParameterValues(function.element);
     currentFunction = function.element;
-    visitStatement(function.body);
+    tree_ir.Statement statement = function.body;
+    while (statement != null) {
+      statement = visitStatement(statement);
+    }
 
     List<js.Parameter> parameters = new List<js.Parameter>();
     Set<tree_ir.Variable> parameterSet = new Set<tree_ir.Variable>();
@@ -121,6 +124,9 @@
       if (assign.op != null) break; // Compound assignment.
       js.VariableUse use = assign.leftHandSide;
 
+      // Do not touch non-local variables.
+      if (!usedVariableNames.contains(use.name)) break;
+
       // We cannot declare a variable more than once.
       if (!declaredVariables.add(use.name)) break;
 
@@ -144,6 +150,9 @@
       if (assign.op != null) break pullFromForLoop; // Compound assignment.
       js.VariableUse use = assign.leftHandSide;
 
+      // Do not touch non-local variables.
+      if (!usedVariableNames.contains(use.name)) break pullFromForLoop;
+
       // We cannot declare a variable more than once.
       if (!declaredVariables.add(use.name)) break pullFromForLoop;
 
@@ -218,9 +227,11 @@
 
   List<js.Expression> visitExpressionList(
       List<tree_ir.Expression> expressions) {
-    return new List<js.Expression>.generate(expressions.length,
-        (int index) => visitExpression(expressions[index]),
-        growable: false);
+    List<js.Expression> result = new List<js.Expression>(expressions.length);
+    for (int i = 0; i < expressions.length; ++i) {
+      result[i] = visitExpression(expressions[i]);
+    }
+    return result;
   }
 
   giveup(tree_ir.Node node,
@@ -364,26 +375,6 @@
   }
 
   @override
-  js.Expression visitLiteralMap(tree_ir.LiteralMap node) {
-    ConstructorElement constructor;
-    if (node.entries.isEmpty) {
-      constructor = glue.mapLiteralConstructorEmpty;
-    } else {
-      constructor = glue.mapLiteralConstructor;
-    }
-    List<js.Expression> entries =
-        new List<js.Expression>(2 * node.entries.length);
-    for (int i = 0; i < node.entries.length; i++) {
-      entries[2 * i] = visitExpression(node.entries[i].key);
-      entries[2 * i + 1] = visitExpression(node.entries[i].value);
-    }
-    List<js.Expression> args = entries.isEmpty
-         ? <js.Expression>[]
-         : <js.Expression>[new js.ArrayInitializer(entries)];
-    return buildStaticInvoke(constructor, args);
-  }
-
-  @override
   js.Expression visitLogicalOperator(tree_ir.LogicalOperator node) {
     return new js.Binary(
         node.operator,
@@ -405,13 +396,19 @@
   ///
   /// 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_);
+  bool tryRegisterInstanceofCheck(ClassElement class_) {
+    if (glue.classWorld.isInstantiated(class_)) {
+      // Ensure the class remains instantiated during backend tree-shaking.
+      // TODO(asgerf): We could have a more precise hook to inform the emitter
+      // that the JS constructor function is needed, without the class being
+      // instantiated.
+      registry.registerInstantiatedClass(class_);
+      return true;
+    }
+    // Will throw if the JS constructor is not emitted, so do not allow the
+    // instanceof check.  This should only happen when certain optimization
+    // passes are disabled, as the type check itself is trivial.
+    return false;
   }
 
   @override
@@ -435,8 +432,8 @@
         // TODO(sra): Implement fast cast via calling 'boolTypeCast'.
       } else if (node.isTypeTest &&
                  node.typeArguments.isEmpty &&
-                 glue.mayGenerateInstanceofCheck(type)) {
-        registerInstanceofCheck(clazz);
+                 glue.mayGenerateInstanceofCheck(type) &&
+                 tryRegisterInstanceofCheck(clazz)) {
         return js.js('# instanceof #', [value, glue.constructorAccess(clazz)]);
       }
 
@@ -618,14 +615,15 @@
   }
 
   @override
-  void visitExpressionStatement(tree_ir.ExpressionStatement node) {
+  visitExpressionStatement(tree_ir.ExpressionStatement node) {
     js.Expression exp = visitExpression(node.expression);
     if (node.next is tree_ir.Unreachable && emitUnreachableAsReturn.last) {
       // Emit as 'return exp' to assist local analysis in the VM.
       accumulator.add(new js.Return(exp));
+      return null;
     } else {
       accumulator.add(new js.ExpressionStatement(exp));
-      visitStatement(node.next);
+      return node.next;
     }
   }
 
@@ -639,7 +637,7 @@
   }
 
   @override
-  void visitIf(tree_ir.If node) {
+  visitIf(tree_ir.If node) {
     js.Expression condition = visitExpression(node.condition);
     int usesBefore = fallthrough.useCount;
     // Unless the 'else' part ends the method. make sure to terminate any
@@ -651,21 +649,22 @@
     if (thenHasFallthrough) {
       js.Statement elseBody = buildBodyStatement(node.elseStatement);
       accumulator.add(new js.If(condition, thenBody, elseBody));
+      return null;
     } else {
       // The 'then' body cannot complete normally, so emit a short 'if'
       // and put the 'else' body after it.
       accumulator.add(new js.If.noElse(condition, thenBody));
-      visitStatement(node.elseStatement);
+      return node.elseStatement;
     }
   }
 
   @override
-  void visitLabeledStatement(tree_ir.LabeledStatement node) {
+  visitLabeledStatement(tree_ir.LabeledStatement node) {
     fallthrough.push(node.next);
     js.Statement body = buildBodyStatement(node.body);
     fallthrough.pop();
     accumulator.add(insertLabel(node.label, body));
-    visitStatement(node.next);
+    return node.next;
   }
 
   /// Creates a name for [label] if it does not already have one.
@@ -697,7 +696,9 @@
   js.Statement buildBodyStatement(tree_ir.Statement statement) {
     List<js.Statement> savedAccumulator = accumulator;
     accumulator = <js.Statement>[];
-    visitStatement(statement);
+    while (statement != null) {
+      statement = visitStatement(statement);
+    }
     js.Statement result = _bodyAsStatement();
     accumulator = savedAccumulator;
     return result;
@@ -706,7 +707,9 @@
   js.Block buildBodyBlock(tree_ir.Statement statement) {
     List<js.Statement> savedAccumulator = accumulator;
     accumulator = <js.Statement>[];
-    visitStatement(statement);
+    while (statement != null) {
+      statement = visitStatement(statement);
+    }
     js.Statement result = new js.Block(accumulator);
     accumulator = savedAccumulator;
     return result;
@@ -717,7 +720,7 @@
   }
 
   @override
-  void visitFor(tree_ir.For node) {
+  visitFor(tree_ir.For node) {
     js.Expression condition = visitExpression(node.condition);
     shortBreak.push(node.next);
     shortContinue.push(node);
@@ -744,12 +747,11 @@
       loopNode = new js.For(init, condition, update, body);
     }
     accumulator.add(insertLabel(node.label, loopNode));
-    visitStatement(node.next);
+    return node.next;
   }
 
   @override
   void visitWhileTrue(tree_ir.WhileTrue node) {
-    js.Expression condition = new js.LiteralBool(true);
     // A short break in the while will jump to the current fallthrough target.
     shortBreak.push(fallthrough.target);
     shortContinue.push(node);
@@ -764,7 +766,8 @@
       fallthrough.use();
     }
     shortBreak.pop();
-    accumulator.add(insertLabel(node.label, new js.While(condition, jsBody)));
+    accumulator.add(
+        insertLabel(node.label, new js.For(null, null, null, jsBody)));
   }
 
   bool isNull(tree_ir.Expression node) {
@@ -824,17 +827,14 @@
       registry.registerInstantiatedClosure(classElement.methodElement);
     }
     js.Expression instance = new js.New(
-        glue.constructorAccess(classElement),
-        visitExpressionList(node.arguments))
+            glue.constructorAccess(classElement),
+            visitExpressionList(node.arguments))
         .withSourceInformation(node.sourceInformation);
 
-    List<tree_ir.Expression> typeInformation = node.typeInformation;
-    assert(typeInformation.isEmpty ||
-        typeInformation.length == classElement.typeVariables.length);
-    if (typeInformation.isNotEmpty) {
+    tree_ir.Expression typeInformation = node.typeInformation;
+    if (typeInformation != null) {
       FunctionElement helper = glue.getAddRuntimeTypeInformation();
-      js.Expression typeArguments = new js.ArrayInitializer(
-          visitExpressionList(typeInformation));
+      js.Expression typeArguments = visitExpression(typeInformation);
       return buildStaticHelperInvocation(helper,
           <js.Expression>[instance, typeArguments],
           sourceInformation: node.sourceInformation);
@@ -921,8 +921,7 @@
     registry.registerStaticUse(
         new StaticUse.staticSet(node.element.declaration));
     js.Expression field = glue.staticFieldAccess(node.element);
-    js.Expression value = visitExpression(node.value);
-    return new js.Assignment(field, value);
+    return makeAssignment(field, node.value, compound: node.compound);
   }
 
   @override
@@ -987,7 +986,17 @@
   @override
   js.Expression visitTypeExpression(tree_ir.TypeExpression node) {
     List<js.Expression> arguments = visitExpressionList(node.arguments);
-    return glue.generateTypeRepresentation(node.dartType, arguments, registry);
+    switch (node.kind) {
+      case tree_ir.TypeExpressionKind.COMPLETE:
+        return glue.generateTypeRepresentation(
+            node.dartType, arguments, registry);
+      case tree_ir.TypeExpressionKind.INSTANCE:
+        // We expect only flat types for the INSTANCE representation.
+        assert(node.dartType ==
+               (node.dartType.element as ClassElement).thisType);
+        registry.registerInstantiatedClass(glue.listClass);
+        return new js.ArrayInitializer(arguments);
+    }
   }
 
   js.Node handleForeignCode(tree_ir.ForeignCode node) {
@@ -1015,14 +1024,14 @@
   }
 
   @override
-  void visitYield(tree_ir.Yield node) {
+  visitYield(tree_ir.Yield node) {
     js.Expression value = visitExpression(node.input);
     accumulator.add(new js.DartYield(value, node.hasStar));
-    visitStatement(node.next);
+    return node.next;
   }
 
   @override
-  void visitNullCheck(tree_ir.NullCheck node) {
+  visitNullCheck(tree_ir.NullCheck node) {
     js.Expression value = visitExpression(node.value);
     // TODO(sra): Try to use the selector even when [useSelector] is false. The
     // reason we use 'toString' is that it is always defined so avoids a slow
@@ -1044,7 +1053,7 @@
     } else {
       accumulator.add(new js.ExpressionStatement(access));
     }
-    visitStatement(node.next);
+    return node.next;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index b7d4c24..46ef1a5 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -228,8 +228,7 @@
     ClassWorld classWorld = _compiler.world;
     if (classWorld.isUsedAsMixin(cls)) return true;
 
-    Iterable<ClassElement> subclasses = _compiler.world.strictSubclassesOf(cls);
-    return subclasses.any((ClassElement subclass) {
+    return _compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
       return !_backend.rti.isTrivialSubstitution(subclass, cls);
     });
   }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 034dd10..6e0619b 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -103,7 +103,7 @@
         }
 
         if (tracer != null) {
-          tracer.traceCompilation(element.name, null);
+          tracer.traceCompilation('$element', null);
         }
         cps.FunctionDefinition cpsFunction = compileToCpsIr(element);
         optimizeCpsBeforeInlining(cpsFunction);
@@ -131,6 +131,49 @@
     }
   }
 
+  String stringify(cps.FunctionDefinition node) {
+    return new SExpressionStringifier().withTypes().visit(node);
+  }
+
+  /// For debugging purposes, replace a call to [applyCpsPass] with a call
+  /// to [debugCpsPass] to check that this pass is idempotent.
+  ///
+  /// This runs [pass] followed by shrinking reductions, and then checks that
+  /// one more run of [pass] does not change the IR.  The intermediate shrinking
+  /// reductions pass is omitted if [pass] itself is shrinking reductions.
+  ///
+  /// If [targetName] is given, functions whose name contains that substring
+  /// will be dumped out if the idempotency test fails.
+  void debugCpsPass(cps_opt.Pass makePass(),
+                    cps.FunctionDefinition cpsFunction,
+                    [String targetName]) {
+    String original = stringify(cpsFunction);
+    cps_opt.Pass pass = makePass();
+    pass.rewrite(cpsFunction);
+    assert(checkCpsIntegrity(cpsFunction, pass.passName));
+    if (pass is! ShrinkingReducer) {
+      new ShrinkingReducer().rewrite(cpsFunction);
+    }
+    String before = stringify(cpsFunction);
+    makePass().rewrite(cpsFunction);
+    String after = stringify(cpsFunction);
+    if (before != after) {
+      print('SExpression changed for ${cpsFunction.element}');
+      if (targetName != null && '${cpsFunction.element}'.contains(targetName)) {
+        print(original);
+        print('\n-->\n');
+        print(before);
+        print('\n-->\n');
+        print(after);
+        compiler.outputProvider('original', 'dump')..add(original)..close();
+        compiler.outputProvider('before', 'dump')..add(before)..close();
+        compiler.outputProvider('after', 'dump')..add(after)..close();
+      }
+    }
+    traceGraph(pass.passName, cpsFunction);
+    dumpTypedIr(pass.passName, cpsFunction);
+  }
+
   void applyCpsPass(cps_opt.Pass pass, cps.FunctionDefinition cpsFunction) {
     cpsOptimizationTask.measureSubtask(pass.passName, () {
       pass.rewrite(cpsFunction);
@@ -141,8 +184,10 @@
   }
 
   cps.FunctionDefinition compileToCpsIr(AstElement element) {
-    cps.FunctionDefinition cpsFunction =
-        cpsBuilderTask.buildNode(element, typeSystem);
+    cps.FunctionDefinition cpsFunction = inliner.cache.getUnoptimized(element);
+    if (cpsFunction != null) return cpsFunction;
+
+    cpsFunction = cpsBuilderTask.buildNode(element, typeSystem);
     if (cpsFunction == null) {
       if (cpsBuilderTask.bailoutMessage == null) {
         giveUp('unable to build cps definition of $element');
@@ -157,6 +202,11 @@
     // insert fewer getInterceptor calls.
     applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
     applyCpsPass(new UnsugarVisitor(glue), cpsFunction);
+    applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+    applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+    applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
+
+    inliner.cache.putUnoptimized(element, cpsFunction);
     return cpsFunction;
   }
 
@@ -208,9 +258,6 @@
 
   void optimizeCpsBeforeInlining(cps.FunctionDefinition cpsFunction) {
     cpsOptimizationTask.measure(() {
-      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
-      applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
-      applyCpsPass(new InsertRefinements(typeSystem), cpsFunction);
       applyCpsPass(new TypePropagator(this), cpsFunction);
       applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
@@ -219,9 +266,16 @@
 
   void optimizeCpsAfterInlining(cps.FunctionDefinition cpsFunction) {
     cpsOptimizationTask.measure(() {
+      applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new RedundantRefinementEliminator(typeSystem), cpsFunction);
+      applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
+      applyCpsPass(new TypePropagator(this, recomputeAll: true), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new EagerlyLoadStatics(), cpsFunction);
       applyCpsPass(new GVN(compiler, typeSystem), cpsFunction);
+      applyCpsPass(new DuplicateBranchEliminator(), cpsFunction);
+      applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
       applyCpsPass(new BoundsChecker(typeSystem, compiler.world), cpsFunction);
       applyCpsPass(new LoopInvariantBranchMotion(), cpsFunction);
@@ -230,6 +284,7 @@
       applyCpsPass(new MutableVariableEliminator(), cpsFunction);
       applyCpsPass(new RedundantJoinEliminator(), cpsFunction);
       applyCpsPass(new RedundantPhiEliminator(), cpsFunction);
+      applyCpsPass(new UpdateRefinements(typeSystem), cpsFunction);
       applyCpsPass(new ShrinkingReducer(), cpsFunction);
       applyCpsPass(new OptimizeInterceptors(backend, typeSystem), cpsFunction);
       applyCpsPass(new BackwardNullCheckRemover(typeSystem), cpsFunction);
@@ -267,7 +322,7 @@
 
     treeOptimizationTask.measure(() {
       applyTreePass(new StatementRewriter());
-      applyTreePass(new VariableMerger());
+      applyTreePass(new VariableMerger(minifying: compiler.enableMinification));
       applyTreePass(new LoopRewriter());
       applyTreePass(new LogicalRewriter());
       applyTreePass(new PullIntoInitializers());
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 290d563..f6ebd07 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -274,8 +274,17 @@
         compiler.backend.typeImplementation.computeType(compiler.resolution));
   }
 
-  // Integer checks don't verify that the number is not -0.0.
-  bool isInt(ConstantValue constant) => constant.isInt || constant.isMinusZero;
+  // Integer checks report true for -0.0, INFINITY, and -INFINITY.  At
+  // runtime an 'X is int' check is implemented as:
+  //
+  // typeof(X) === "number" && Math.floor(X) === X
+  //
+  // We consistently match that runtime semantics at compile time as well.
+  bool isInt(ConstantValue constant) {
+    return constant.isInt || constant.isMinusZero ||
+        constant.isPositiveInfinity ||
+        constant.isNegativeInfinity;
+  }
   bool isDouble(ConstantValue constant)
       => constant.isDouble && !constant.isMinusZero;
   bool isString(ConstantValue constant) => constant.isString;
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index 99d383c..eca1917 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -49,6 +49,8 @@
 import '../dart_types.dart';
 import '../deferred_load.dart' show
     DeferredLoadTask;
+import '../diagnostics/invariant.dart' show
+    DEBUG_MODE;
 import '../dump_info.dart' show
     DumpInfoTask;
 import '../elements/elements.dart';
diff --git a/pkg/compiler/lib/src/js_backend/namer_names.dart b/pkg/compiler/lib/src/js_backend/namer_names.dart
index 60e1597..31a1747 100644
--- a/pkg/compiler/lib/src/js_backend/namer_names.dart
+++ b/pkg/compiler/lib/src/js_backend/namer_names.dart
@@ -8,7 +8,12 @@
   int get _kind;
   _NamerName get _target => this;
 
-  toString() => throw new UnsupportedError("Cannot convert a name to a string");
+  String toString() {
+    if (DEBUG_MODE) {
+      return 'Name($key)';
+    }
+    throw new UnsupportedError("Cannot convert a name to a string");
+  }
 }
 
 enum _NamerNameKinds {
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 849fae3..1501a93 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -236,8 +236,7 @@
       classesNeedingRti.add(cls);
 
       // TODO(ngeoffray): This should use subclasses, not subtypes.
-      Iterable<ClassElement> classes = compiler.world.strictSubtypesOf(cls);
-      classes.forEach((ClassElement sub) {
+      compiler.world.forEachStrictSubtypeOf(cls, (ClassElement sub) {
         potentiallyAddForRti(sub);
       });
 
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index fb34fae..f2c1ded 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -74,6 +74,7 @@
     TypeCheck,
     TypeChecks,
     TypeVariableHandler;
+import '../../js/js_debug.dart';
 import '../../universe/call_structure.dart' show
     CallStructure;
 import '../../universe/selector.dart' show
@@ -1609,9 +1610,8 @@
     outputBuffers[mainOutputUnit] = mainOutput;
 
 
-    mainOutput.addBuffer(jsAst.prettyPrint(program,
-                                           compiler,
-                                           monitor: compiler.dumpInfoTask));
+    mainOutput.addBuffer(jsAst.createCodeBuffer(
+        program, compiler, monitor: compiler.dumpInfoTask));
 
     if (compiler.deferredMapUri != null) {
       outputDeferredMap();
@@ -2055,9 +2055,8 @@
 
       outputBuffers[outputUnit] = output;
 
-      output.addBuffer(jsAst.prettyPrint(outputAsts[outputUnit],
-                                         compiler,
-                                         monitor: compiler.dumpInfoTask));
+      output.addBuffer(jsAst.createCodeBuffer(
+          outputAsts[outputUnit], compiler, monitor: compiler.dumpInfoTask));
 
       // Make a unique hash of the code (before the sourcemaps are added)
       // This will be used to retrieve the initializing function from the global
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index dbc6c9b..eb66c1a 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -22,6 +22,8 @@
     ClosureClassMap,
     ClosureFieldElement,
     CapturedVariable;
+import '../core_types.dart' show
+    CoreClasses;
 import '../dart_types.dart' show
     DartType,
     FunctionType,
@@ -34,6 +36,7 @@
 import '../elements/elements.dart' show
     ClassElement,
     ConstructorBodyElement,
+    ConstructorElement,
     Element,
     Elements,
     ElementKind,
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 96838ac..a0b9b48 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -159,15 +159,16 @@
 
     program.finalizers.forEach((js.TokenFinalizer f) => f.finalizeTokens());
 
+    // TODO(johnnniwinther): Support source maps in this emitter.
     for (int i = 0; i < fragmentsCode.length; ++i) {
-      String code = js.prettyPrint(fragmentsCode[i], compiler).getText();
+      String code = js.createCodeBuffer(fragmentsCode[i], compiler).getText();
       totalSize += code.length;
       compiler.outputProvider(fragments[i+1].outputFileName, deferredExtension)
         ..add(code)
         ..close();
     }
 
-    String mainCode = js.prettyPrint(mainAst, compiler).getText();
+    String mainCode = js.createCodeBuffer(mainAst, compiler).getText();
     compiler.outputProvider(mainFragment.outputFileName, 'js')
         ..add(buildGeneratedBy(compiler))
         ..add(mainCode)
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 43aa528..fdea7ff 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -178,12 +178,42 @@
   }
 
   List<jsAst.DeferredNumber> reifyDefaultArguments(FunctionElement function) {
+    function = function.implementation;
     FunctionSignature signature = function.functionSignature;
     if (signature.optionalParameterCount == 0) return const [];
+
+    // Optional parameters of redirecting factory constructors take their
+    // defaults from the corresponding parameters of the redirection target.
+    Map<ParameterElement, ParameterElement> targetParameterMap;
+    if (function is ConstructorElement) {
+      // TODO(sra): dart2js generates a redirecting factory constructor body
+      // that has the signature of the redirecting constructor that calls the
+      // redirection target. This is wrong - it should have the signature of the
+      // target. This would make the reified default arguments trivial.
+
+      ConstructorElement constructor = function;
+      while (constructor.isRedirectingFactory &&
+             !constructor.isCyclicRedirection) {
+        // TODO(sra): Remove the loop once effectiveTarget forwards to patches.
+        constructor = constructor.effectiveTarget.implementation;
+      }
+
+      if (constructor != function) {
+        if (signature.hasOptionalParameters) {
+          targetParameterMap =
+              mapRedirectingFactoryConstructorOptionalParameters(
+                  signature, constructor.functionSignature);
+        }
+      }
+    }
+
     List<jsAst.DeferredNumber> defaultValues = <jsAst.DeferredNumber>[];
     for (ParameterElement element in signature.optionalParameters) {
-      ConstantValue constant =
-          _backend.constants.getConstantValueForVariable(element);
+      ParameterElement parameter =
+          (targetParameterMap == null) ? element : targetParameterMap[element];
+      ConstantValue constant = (parameter == null)
+          ? null
+          : _backend.constants.getConstantValueForVariable(parameter);
       jsAst.Expression expression = (constant == null)
           ? new jsAst.LiteralNull()
           : _emitter.constantReference(constant);
@@ -192,6 +222,40 @@
     return defaultValues;
   }
 
+  Map<ParameterElement, ParameterElement>
+  mapRedirectingFactoryConstructorOptionalParameters(
+      FunctionSignature source, FunctionSignature target) {
+    var map = <ParameterElement, ParameterElement>{};
+
+    if (source.optionalParametersAreNamed !=
+        target.optionalParametersAreNamed) {
+      // No legal optional arguments due to mismatch between named vs positional
+      // optional arguments.
+      return map;
+    }
+
+    if (source.optionalParametersAreNamed) {
+      for (ParameterElement element in source.optionalParameters) {
+        for (ParameterElement redirectedElement in target.optionalParameters) {
+          if (element.name == redirectedElement.name) {
+            map[element] = redirectedElement;
+            break;
+          }
+        }
+      }
+    } else {
+      int i = source.requiredParameterCount;
+      for (ParameterElement element in source.orderedOptionalParameters) {
+        if (i >= target.requiredParameterCount && i < target.parameterCount) {
+          map[element] =
+              target.orderedOptionalParameters[i - target.requiredParameterCount];
+        }
+        ++i;
+      }
+    }
+    return map;
+  }
+
   jsAst.Expression reifyMetadata(MetadataAnnotation annotation) {
     ConstantValue constant =
         _backend.constants.getConstantValueForMetadata(annotation);
@@ -229,9 +293,8 @@
 
   _MetadataEntry _addGlobalMetadata(jsAst.Node node) {
     String nameToKey(jsAst.Name name) => "${name.key}";
-    String printed = jsAst.prettyPrint(node, _compiler,
-                                       renamerForNames: nameToKey)
-                          .getText();
+    String printed = jsAst.prettyPrint(
+        node, _compiler, renamerForNames: nameToKey);
     return _globalMetadataMap.putIfAbsent(printed, () {
       _BoundMetadataEntry result = new _BoundMetadataEntry(node);
       if (_compiler.hasIncrementalSupport) {
@@ -366,4 +429,4 @@
     node.accept(this);
     return _foundUnboundToken;
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 61c1b08..9c48f4d 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -35,6 +35,7 @@
 
   JavaScriptBackend get backend => compiler.backend;
   TypeTestRegistry get typeTestRegistry => emitterTask.typeTestRegistry;
+  CoreClasses get coreClasses => compiler.coreClasses;
 
   Set<ClassElement> get checkedClasses =>
       typeTestRegistry.checkedClasses;
@@ -181,7 +182,7 @@
     }
 
     if (superclass != null &&
-        superclass != compiler.coreClasses.objectClass &&
+        superclass != coreClasses.objectClass &&
         !haveSameTypeVariables(cls, superclass)) {
       // We cannot inherit the generated substitutions, because the type
       // variable layout for this class is different.  Instead we generate
@@ -217,7 +218,7 @@
 
     // A class that defines a `call` method implicitly implements
     // [Function] and needs checks for all typedefs that are used in is-checks.
-    if (checkedClasses.contains(compiler.coreClasses.functionClass) ||
+    if (checkedClasses.contains(coreClasses.functionClass) ||
         checkedFunctionTypes.isNotEmpty) {
       Element call = cls.lookupLocalMember(Identifiers.call);
       if (call == null) {
@@ -228,8 +229,8 @@
         FunctionElement callFunction = call;
         // A superclass might already implement the Function interface. In such
         // a case, we can avoid emiting the is test here.
-        if (!cls.superclass.implementsFunction(compiler)) {
-          _generateInterfacesIsTests(compiler.coreClasses.functionClass,
+        if (!cls.superclass.implementsFunction(coreClasses)) {
+          _generateInterfacesIsTests(coreClasses.functionClass,
                                     generateIsTest,
                                     generateSubstitution,
                                     generated);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 9e81bca..65d0519 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -281,7 +281,7 @@
         isSplit ? buildDeferredInitializerGlobal() : new js.Block.empty(),
         code]);
 
-    mainOutput.addBuffer(js.prettyPrint(program, compiler,
+    mainOutput.addBuffer(js.createCodeBuffer(program, compiler,
         monitor: compiler.dumpInfoTask));
 
     if (shouldGenerateSourceMap) {
@@ -335,7 +335,7 @@
         buildDeferredInitializerGlobal(),
         js.js.statement('$deferredInitializersGlobal.current = #', code)]);
 
-    output.addBuffer(js.prettyPrint(program, compiler,
+    output.addBuffer(js.createCodeBuffer(program, compiler,
         monitor: compiler.dumpInfoTask));
 
     // Make a unique hash of the code (before the sourcemaps are added)
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 438dbe6..cd61a71 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -111,6 +111,9 @@
   static NativeBehavior get PURE => NativeBehavior._makePure();
   static NativeBehavior get PURE_ALLOCATION =>
       NativeBehavior._makePure(isAllocation: true);
+  static NativeBehavior get CHANGES_OTHER => NativeBehavior._makeChangesOther();
+  static NativeBehavior get DEPENDS_OTHER => NativeBehavior._makeDependsOther();
+
 
   String toString() {
     return 'NativeBehavior('
@@ -132,6 +135,18 @@
     return behavior;
   }
 
+  static NativeBehavior _makeChangesOther() {
+    // TODO(25544): Have a distinct effect instead of using static properties to
+    // model 'other' effects.
+    return _makePure()..sideEffects.setChangesStaticProperty();
+  }
+
+  static NativeBehavior _makeDependsOther() {
+    // TODO(25544): Have a distinct effect instead of using static properties to
+    // model 'other' effects.
+    return _makePure()..sideEffects.setDependsOnStaticPropertyStore();
+  }
+
   /// Processes the type specification string of a call to JS and stores the
   /// result in the [typesReturned] and [typesInstantiated]. It furthermore
   /// computes the side effects, and, if given, invokes [setSideEffects] with
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index a23a490..36feaa4 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -6,7 +6,8 @@
 
 import '../common.dart';
 import '../common/names.dart' show
-    Identifiers;
+    Identifiers,
+    Names;
 import '../common/resolution.dart' show
     Resolution;
 import '../compiler.dart' show
@@ -76,9 +77,12 @@
   /// Compute all members of [cls] and checked that [cls] implements its
   /// interface unless it is abstract or declares a `noSuchMethod` method.
   void computeAllMembers() {
-    Map<Name, Member> declaredMembers = computeMembers(null, null);
-    if (!cls.isAbstract &&
-        !declaredMembers.containsKey(const PublicName('noSuchMethod'))) {
+    computeMembers(null, null);
+    if (!cls.isAbstract) {
+      Member member = classMembers[Names.noSuchMethod_];
+      if (member != null && !member.declarer.isObject) {
+        return;
+      }
       // Check for unimplemented members on concrete classes that neither have
       // a `@proxy` annotation nor declare a `noSuchMethod` method.
       checkInterfaceImplementation();
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 540ba50..0c8e57c 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -4198,9 +4198,11 @@
       // If the isolate library is not used, we just generate code
       // to fetch the static state.
       String name = backend.namer.staticStateHolder;
-      push(new HForeignCode(js.js.parseForeignJS(name),
-                            backend.dynamicType,
-                            <HInstruction>[]));
+      push(new HForeignCode(
+          js.js.parseForeignJS(name),
+          backend.dynamicType,
+          <HInstruction>[],
+          nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
     } else {
       // Call a helper method from the isolate library. The isolate
       // library uses its own isolate structure, that encapsulates
@@ -4478,7 +4480,7 @@
         js.js.parseForeignJS("$isolateName = #"),
         backend.dynamicType,
         <HInstruction>[pop()],
-        nativeBehavior: native.NativeBehavior.PURE,
+        nativeBehavior: native.NativeBehavior.CHANGES_OTHER,
         effects: sideEffects));
   }
 
@@ -4488,7 +4490,8 @@
     }
     push(new HForeignCode(js.js.parseForeignJS(backend.namer.staticStateHolder),
                           backend.dynamicType,
-                          <HInstruction>[]));
+                          <HInstruction>[],
+                          nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
   }
 
   void handleForeignSend(ast.Send node, FunctionElement element) {
@@ -4837,8 +4840,7 @@
     ClassWorld classWorld = compiler.world;
     if (classWorld.isUsedAsMixin(cls)) return true;
 
-    Iterable<ClassElement> subclasses = compiler.world.strictSubclassesOf(cls);
-    return subclasses.any((ClassElement subclass) {
+    return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
       return !rti.isTrivialSubstitution(subclass, cls);
     });
   }
@@ -7147,21 +7149,64 @@
     FunctionSignature targetSignature = targetConstructor.functionSignature;
     FunctionSignature redirectingSignature =
         redirectingConstructor.functionSignature;
-    redirectingSignature.forEachRequiredParameter((ParameterElement element) {
-      inputs.add(localsHandler.readLocal(element));
-    });
+
+    List<Element> targetRequireds = targetSignature.requiredParameters;
+    List<Element> redirectingRequireds
+        = redirectingSignature.requiredParameters;
+
     List<Element> targetOptionals =
         targetSignature.orderedOptionalParameters;
     List<Element> redirectingOptionals =
         redirectingSignature.orderedOptionalParameters;
-    int i = 0;
-    for (; i < redirectingOptionals.length; i++) {
-      ParameterElement parameter = redirectingOptionals[i];
+
+    // TODO(25579): This code can do the wrong thing redirecting constructor and
+    // the target do not correspond. It is correct if there is no
+    // warning. Ideally the redirecting constructor and the target would be the
+    // same function.
+
+    void loadLocal(ParameterElement parameter) {
       inputs.add(localsHandler.readLocal(parameter));
     }
-    for (; i < targetOptionals.length; i++) {
-      inputs.add(handleConstantForOptionalParameter(targetOptionals[i]));
+    void loadPosition(int position, ParameterElement optionalParameter) {
+      if (position < redirectingRequireds.length) {
+        loadLocal(redirectingRequireds[position]);
+      } else if (position < redirectingSignature.parameterCount &&
+                 !redirectingSignature.optionalParametersAreNamed) {
+        loadLocal(redirectingOptionals[position - redirectingRequireds.length]);
+      } else if (optionalParameter != null) {
+        inputs.add(handleConstantForOptionalParameter(optionalParameter));
+      } else {
+        // Wrong.
+        inputs.add(graph.addConstantNull(compiler));
+      }
     }
+
+    int position = 0;
+
+    for (ParameterElement targetParameter in targetRequireds) {
+      loadPosition(position++, null);
+    }
+
+    if (targetOptionals.isNotEmpty) {
+      if (targetSignature.optionalParametersAreNamed) {
+        for (ParameterElement parameter in targetOptionals) {
+          ParameterElement redirectingParameter =
+              redirectingOptionals.firstWhere(
+                  (p) => p.name == parameter.name,
+                  orElse: () => null);
+          if (redirectingParameter == null) {
+            inputs.add(handleConstantForOptionalParameter(parameter));
+          } else {
+            inputs.add(localsHandler.readLocal(redirectingParameter));
+          }
+        }
+      } else {
+        for (ParameterElement parameter in targetOptionals) {
+          loadPosition(position++, parameter);
+        }
+      }
+    }
+
     ClassElement targetClass = targetConstructor.enclosingClass;
     if (backend.classNeedsRti(targetClass)) {
       ClassElement cls = redirectingConstructor.enclosingClass;
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 9cfb66b..8d5e08f 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -100,8 +100,7 @@
     // All intercepted classes extend `Interceptor`, so if the receiver can't be
     // a class extending `Interceptor` then it can be called directly.
     return new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, classWorld)
-        .intersection(receiver.instructionType, classWorld)
-        .isEmpty;
+        .isDisjoint(receiver.instructionType, classWorld);
   }
 
   HInstruction tryComputeConstantInterceptor(
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index c98ceb1..a8d82ae 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -593,8 +593,7 @@
     // Intersection of int and double return conflicting, so
     // we don't optimize on numbers to preserve the runtime semantics.
     if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) {
-      TypeMask intersection = leftType.intersection(rightType, compiler.world);
-      if (intersection.isEmpty && !intersection.isNullable) {
+      if (leftType.isDisjoint(rightType, compiler.world)) {
         return makeFalse();
       }
     }
@@ -737,8 +736,7 @@
           : new TypeMask.nonNullSubtype(element, classWorld);
       if (expressionMask.union(typeMask, classWorld) == typeMask) {
         return graph.addConstantBool(true, compiler);
-      } else if (expressionMask.intersection(typeMask,
-                                             compiler.world).isEmpty) {
+      } else if (expressionMask.isDisjoint(typeMask, compiler.world)) {
         return graph.addConstantBool(false, compiler);
       }
     }
@@ -2154,10 +2152,8 @@
     if (nonEscapingReceivers.contains(second)) return false;
     // Typed arrays of different types might have a shared buffer.
     if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true;
-    TypeMask intersection = first.instructionType.intersection(
+    return !first.instructionType.isDisjoint(
         second.instructionType, compiler.world);
-    if (intersection.isEmpty) return false;
-    return true;
   }
 
   bool isFinal(Element element) {
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index a940e71..7cd149e 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -682,6 +682,9 @@
     } else {
       constantNum = constant;
     }
+    if (constantNum.isPositiveInfinity || constantNum.isNegativeInfinity) {
+      return info.newUnboundRange();
+    }
     if (constantNum.isMinusZero) constantNum = new IntConstantValue(0);
     Value value = info.newIntValue(constantNum.primitiveValue);
     return info.newNormalizedRange(value, value);
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 3b3a74a..1ada85b 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
@@ -292,14 +292,6 @@
     return node;
   }
 
-  Expression visitLiteralMap(LiteralMap node) {
-    super.visitLiteralMap(node);
-    if (node.type != null) {
-      ++impureCounter; // Type casts can throw.
-    }
-    return node;
-  }
-
   Expression visitTypeOperator(TypeOperator node) {
     super.visitTypeOperator(node);
     if (!node.isTypeTest) {
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 f23533c..1c92ff5 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -372,6 +372,7 @@
            exp is CreateInvocationMirror ||
            exp is CreateInstance ||
            exp is CreateBox ||
+           exp is TypeExpression ||
            exp is GetStatic && exp.element.isFunction ||
            exp is Interceptor ||
            exp is ApplyBuiltinOperator ||
@@ -579,13 +580,11 @@
   }
 
   Expression visitLogicalOperator(LogicalOperator node) {
-    node.left = visitExpression(node.left);
-
     // Impure expressions may not propagate across the branch.
     inEmptyEnvironment(() {
       node.right = visitExpression(node.right);
     });
-
+    node.left = visitExpression(node.left);
     return node;
   }
 
@@ -739,31 +738,32 @@
     return node;
   }
 
-  Expression visitLiteralMap(LiteralMap node) {
-    // Process arguments right-to-left, the opposite of evaluation order.
-    for (LiteralMapEntry entry in node.entries.reversed) {
-      entry.value = visitExpression(entry.value);
-      entry.key = visitExpression(entry.key);
-    }
-    return node;
-  }
-
   Expression visitTypeOperator(TypeOperator node) {
     _rewriteList(node.typeArguments);
     node.value = visitExpression(node.value);
     return node;
   }
 
-  bool sameVariable(Expression e1, Expression e2) {
-    return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
-  }
-
   bool isCompoundableBuiltin(Expression e) {
     return e is ApplyBuiltinOperator &&
-           e.arguments.length == 2 &&
+           e.arguments.length >= 2 &&
            isCompoundableOperator(e.operator);
   }
 
+  /// Converts a compoundable operator application into the right-hand side for
+  /// use in a compound assignment, discarding the left-hand value.
+  ///
+  /// For example, for `x + y + z` it returns `y + z`.
+  Expression contractCompoundableBuiltin(ApplyBuiltinOperator e) {
+    assert(isCompoundableBuiltin(e));
+    if (e.arguments.length > 2) {
+      assert(e.operator == BuiltinOperator.StringConcatenate);
+      return new ApplyBuiltinOperator(e.operator, e.arguments.skip(1).toList());
+    } else {
+      return e.arguments[1];
+    }
+  }
+
   void destroyVariableUse(VariableUse node) {
     --node.variable.readCount;
   }
@@ -774,13 +774,12 @@
     if (isCompoundableBuiltin(node.value)) {
       ApplyBuiltinOperator rhs = node.value;
       Expression left = rhs.arguments[0];
-      Expression right = rhs.arguments[1];
       if (left is GetField &&
           left.field == node.field &&
-          sameVariable(left.object, node.object)) {
-        destroyVariableUse(left.object);
+          samePrimary(left.object, node.object)) {
+        destroyPrimaryExpression(left.object);
         node.compound = rhs.operator;
-        node.value = right;
+        node.value = contractCompoundableBuiltin(rhs);
       }
     }
     node.object = visitExpression(node.object);
@@ -800,6 +799,16 @@
   Expression visitSetStatic(SetStatic node) {
     allowRhsPropagation.add(true);
     node.value = visitExpression(node.value);
+    if (isCompoundableBuiltin(node.value)) {
+      ApplyBuiltinOperator rhs = node.value;
+      Expression left = rhs.arguments[0];
+      if (left is GetStatic &&
+          left.element == node.element &&
+          !left.useLazyGetter) {
+        node.compound = rhs.operator;
+        node.value = contractCompoundableBuiltin(rhs);
+      }
+    }
     allowRhsPropagation.removeLast();
     return node;
   }
@@ -814,6 +823,9 @@
   }
 
   Expression visitCreateInstance(CreateInstance node) {
+    if (node.typeInformation != null) {
+      node.typeInformation = visitExpression(node.typeInformation);
+    }
     _rewriteList(node.arguments);
     return node;
   }
@@ -859,14 +871,13 @@
     if (isCompoundableBuiltin(node.value)) {
       ApplyBuiltinOperator rhs = node.value;
       Expression left = rhs.arguments[0];
-      Expression right = rhs.arguments[1];
       if (left is GetIndex &&
-          sameVariable(left.object, node.object) &&
-          sameVariable(left.index, node.index)) {
-        destroyVariableUse(left.object);
-        destroyVariableUse(left.index);
+          samePrimary(left.object, node.object) &&
+          samePrimary(left.index, node.index)) {
+        destroyPrimaryExpression(left.object);
+        destroyPrimaryExpression(left.index);
         node.compound = rhs.operator;
-        node.value = right;
+        node.value = contractCompoundableBuiltin(rhs);
       }
     }
     node.index = visitExpression(node.index);
@@ -1244,8 +1255,8 @@
 
   @override
   Statement visitYield(Yield node) {
-    node.input = visitExpression(node.input);
     node.next = visitStatement(node.next);
+    node.input = visitExpression(node.input);
     return node;
   }
 
@@ -1358,3 +1369,22 @@
     new VariableUseVisitor(callback).visitExpression(node);
   }
 }
+
+bool sameVariable(Expression e1, Expression e2) {
+  return e1 is VariableUse && e2 is VariableUse && e1.variable == e2.variable;
+}
+
+/// True if [e1] and [e2] are primary expressions (expressions without
+/// subexpressions) with the same value.
+bool samePrimary(Expression e1, Expression e2) {
+  return sameVariable(e1, e2) || (e1 is This && e2 is This);
+}
+
+/// Decrement the reference count for [e] if it is a variable use.
+void destroyPrimaryExpression(Expression e) {
+  if (e is VariableUse) {
+    --e.variable.readCount;
+  } else {
+    assert(e is This);
+  }
+}
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
index fb31f02..bcc16ca 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/variable_merger.dart
@@ -12,22 +12,19 @@
 /// This phase cleans up artifacts introduced by the translation through CPS,
 /// where each source variable is translated into several copies. The copies
 /// are merged again when they are not live simultaneously.
-class VariableMerger extends RecursiveVisitor implements Pass {
+class VariableMerger implements Pass {
   String get passName => 'Variable merger';
 
-  void rewrite(FunctionDefinition node) {
-    rewriteFunction(node);
-    visitStatement(node.body);
-  }
+  final bool minifying;
 
-  /// Rewrites the given function.
-  /// This is called for the outermost function and inner functions.
-  void rewriteFunction(FunctionDefinition node) {
-    BlockGraphBuilder builder = new BlockGraphBuilder();
-    builder.build(node);
+  VariableMerger({this.minifying: false});
+
+  void rewrite(FunctionDefinition node) {
+    BlockGraphBuilder builder = new BlockGraphBuilder()..build(node);
     _computeLiveness(builder.blocks);
-    Map<Variable, Variable> subst =
-        _computeRegisterAllocation(builder.blocks, node.parameters);
+    PriorityPairs priority = new PriorityPairs()..build(node);
+    Map<Variable, Variable> subst = _computeRegisterAllocation(
+        builder.blocks, node.parameters, priority, minifying: minifying);
     new SubstituteVariables(subst).apply(node);
   }
 }
@@ -248,6 +245,54 @@
   }
 }
 
+/// Collects prioritized variable pairs -- pairs that lead to significant code
+/// reduction if merged into one variable.
+///
+/// These arise from moving assigments `v1 = v2`, and compoundable assignments
+/// `v1 = v2 [+] E` where [+] is a compoundable operator.
+//
+// TODO(asgerf): We could have a more fine-grained priority level. All pairs
+//   are treated as equally important, but some pairs can eliminate more than
+//   one assignment.
+//   Also, some assignments are more important to remove than others, as they
+//   can block a later optimization, such rewriting a loop, or removing the
+//   'else' part of an 'if'.
+//
+class PriorityPairs extends RecursiveVisitor {
+  final Map<Variable, List<Variable>> _priority = <Variable, List<Variable>>{};
+
+  void build(FunctionDefinition node) {
+    visitStatement(node.body);
+  }
+
+  void _prioritize(Variable x, Variable y) {
+    _priority.putIfAbsent(x, () => new List<Variable>()).add(y);
+    _priority.putIfAbsent(y, () => new List<Variable>()).add(x);
+  }
+
+  visitAssign(Assign node) {
+    super.visitAssign(node);
+    Expression value = node.value;
+    if (value is VariableUse) {
+      _prioritize(node.variable, value.variable);
+    } else if (value is ApplyBuiltinOperator &&
+               isCompoundableOperator(value.operator) &&
+               value.arguments[0] is VariableUse) {
+      VariableUse use = value.arguments[0];
+      _prioritize(node.variable, use.variable);
+    }
+  }
+
+  /// Returns the other half of every priority pair containing [variable].
+  List<Variable> getPriorityPairsWith(Variable variable) {
+    return _priority[variable] ?? const <Variable>[];
+  }
+
+  bool hasPriorityPairs(Variable variable) {
+    return _priority.containsKey(variable);
+  }
+}
+
 /// Computes liveness information of the given control-flow graph.
 ///
 /// The results are stored in [Block.liveIn] and [Block.liveOut].
@@ -331,14 +376,6 @@
   }
 }
 
-/// For testing purposes, this flag can be passed to merge variables that
-/// originated from different source variables.
-///
-/// Correctness should not depend on the fact that we only merge variables
-/// originating from the same source variable. Setting this flag makes a bug
-/// more likely to provoke a test case failure.
-const bool NO_PRESERVE_VARS = const bool.fromEnvironment('NO_PRESERVE_VARS');
-
 /// Based on liveness information, computes a map of variable substitutions to
 /// merge variables.
 ///
@@ -348,23 +385,30 @@
 ///
 /// We then compute a graph coloring, where the color of a node denotes which
 /// variable it will be substituted by.
-///
-/// We never merge variables that originated from distinct source variables,
-/// so we build a separate register interference graph for each source variable.
 Map<Variable, Variable> _computeRegisterAllocation(List<Block> blocks,
-                                                   List<Variable> parameters) {
+                                                   List<Variable> parameters,
+                                                   PriorityPairs priority,
+                                                   {bool minifying}) {
   Map<Variable, Set<Variable>> interference = <Variable, Set<Variable>>{};
 
-  /// Group for the given variable. We attempt to merge variables in the same
-  /// group.
-  /// By default, variables are grouped based on their source variable name,
-  /// but this can be disabled for testing purposes.
-  String group(Variable variable) {
-    if (NO_PRESERVE_VARS) return '';
-    // Group variables based on the source variable's name, not its element,
-    // so if multiple locals are declared with the same name, they will
-    // map to the same (hoisted) variable in the output.
-    return variable.element == null ? '' : variable.element.name;
+  bool allowUnmotivatedMerge(Variable x, Variable y) {
+    if (minifying) return true;
+    // Do not allow merging temporaries with named variables if they are
+    // not connected by a phi.  That would leads to confusing mergings like:
+    //    var v0 = receiver.length;
+    //        ==>
+    //    receiver = receiver.length;
+    return x.element?.name == y.element?.name;
+  }
+
+  bool allowPhiMerge(Variable x, Variable y) {
+    if (minifying) return true;
+    // Temporaries may be merged with a named variable if this eliminates a phi.
+    // The presence of the phi implies that the two variables can contain the
+    // same value, so it is not that confusing that they get the same name.
+    return x.element == null ||
+           y.element == null ||
+           x.element.name == y.element.name;
   }
 
   Set<Variable> empty = new Set<Variable>();
@@ -372,12 +416,10 @@
   // At the assignment to a variable x, add an edge to every variable that is
   // live after the assignment (if it came from the same source variable).
   for (Block block in blocks) {
-    // Group the liveOut set by source variable.
-    Map<String, Set<Variable>> liveOut = <String, Set<Variable>>{};
+    // Track the live set while traversing the block.
+    Set<Variable> live = new Set<Variable>();
     for (Variable variable in block.liveOut) {
-      liveOut.putIfAbsent(
-          group(variable),
-          () => new Set<Variable>()).add(variable);
+      live.add(variable);
       interference.putIfAbsent(variable, () => new Set<Variable>());
     }
     // Get variables that are live at the catch block.
@@ -388,8 +430,6 @@
     for (VariableAccess access in block.accesses.reversed) {
       Variable variable = access.variable;
       interference.putIfAbsent(variable, () => new Set<Variable>());
-      Set<Variable> live =
-          liveOut.putIfAbsent(group(variable), () => new Set<Variable>());
       if (access.isRead) {
         live.add(variable);
       } else {
@@ -410,42 +450,89 @@
   List<Variable> variables = interference.keys.toList();
   variables.sort((x, y) => interference[y].length - interference[x].length);
 
-  Map<String, List<Variable>> registers = <String, List<Variable>>{};
+  List<Variable> registers = <Variable>[];
   Map<Variable, Variable> subst = <Variable, Variable>{};
 
-  // Parameters are special in that they must have a ParameterElement and
-  // cannot be merged with each other. Ensure that they are not substituted.
-  // Other variables can still be substituted by a parameter.
-  for (Variable parameter in parameters) {
-    if (parameter.isCaptured) continue;
-    subst[parameter] = parameter;
-    registers[group(parameter)] = <Variable>[parameter];
+  /// Called when [variable] has been assigned [target] as its register/color.
+  /// Will immediately try to satisfy its priority pairs by assigning the same
+  /// color the other half of each pair.
+  void searchPriorityPairs(Variable variable, Variable target) {
+    if (!priority.hasPriorityPairs(variable)) {
+      return; // Most variables (around 90%) do not have priority pairs.
+    }
+    List<Variable> worklist = <Variable>[variable];
+    while (worklist.isNotEmpty) {
+      Variable v1 = worklist.removeLast();
+      for (Variable v2 in priority.getPriorityPairsWith(v1)) {
+        // If v2 already has a color, we cannot change it.
+        if (subst.containsKey(v2)) continue;
+
+        // Do not merge differently named variables.
+        if (!allowPhiMerge(v1, v2)) continue;
+
+        // Ensure the graph coloring remains valid. If a neighbour of v2 already
+        // has the desired color, we cannot assign the same color to v2.
+        if (interference[v2].any((v3) => subst[v3] == target)) continue;
+
+        subst[v2] = target;
+        target.element ??= v2.element; // Preserve the name.
+        worklist.add(v2);
+      }
+    }
   }
 
+  void assignRegister(Variable variable, Variable registerRepresentative) {
+    subst[variable] = registerRepresentative;
+    // Ensure this register is never assigned to a variable with another name.
+    // This also ensures that named variables keep their name when merged
+    // with a temporary.
+    registerRepresentative.element ??= variable.element;
+    searchPriorityPairs(variable, registerRepresentative);
+  }
+
+  void assignNewRegister(Variable variable) {
+    registers.add(variable);
+    subst[variable] = variable;
+    searchPriorityPairs(variable, variable);
+  }
+
+  // Parameters cannot be merged with each other. Ensure that they are not
+  // substituted.  Other variables can still be substituted by a parameter.
+  for (Variable parameter in parameters) {
+    if (parameter.isCaptured) continue;
+    registers.add(parameter);
+    subst[parameter] = parameter;
+  }
+
+  // Try to merge parameters with locals to eliminate phis.
+  for (Variable parameter in parameters) {
+    searchPriorityPairs(parameter, parameter);
+  }
+
+  v1loop:
   for (Variable v1 in variables) {
-    // Parameters have already been assigned a substitute; skip those.
+    // Ignore if the variable has already been assigned a register.
     if (subst.containsKey(v1)) continue;
 
-    List<Variable> register = registers[group(v1)];
-
-    // Optimization: For the first variable in a group, allocate a new color
-    // without iterating over its interference edges.
-    if (register == null) {
-      registers[group(v1)] = <Variable>[v1];
-      subst[v1] = v1;
-      continue;
-    }
-
     // Optimization: If there are no interference edges for this variable,
-    // assign it the first color without copying the register list.
+    // find a color for it without copying the register list.
     Set<Variable> interferenceSet = interference[v1];
     if (interferenceSet.isEmpty) {
-      subst[v1] = register[0];
+      // Use the first register where naming constraints allow the merge.
+      for (Variable v2 in registers) {
+        if (allowUnmotivatedMerge(v1, v2)) {
+          assignRegister(v1, v2);
+          continue v1loop;
+        }
+      }
+      // No register allows merging with this one, create a new register.
+      assignNewRegister(v1);
       continue;
     }
 
     // Find an unused color.
-    Set<Variable> potential = new Set<Variable>.from(register);
+    Set<Variable> potential = new Set<Variable>.from(
+          registers.where((v2) => allowUnmotivatedMerge(v1, v2)));
     for (Variable v2 in interferenceSet) {
       Variable v2subst = subst[v2];
       if (v2subst != null) {
@@ -456,10 +543,9 @@
 
     if (potential.isEmpty) {
       // If no free color was found, add this variable as a new color.
-      register.add(v1);
-      subst[v1] = v1;
+      assignNewRegister(v1);
     } else {
-      subst[v1] = potential.first;
+      assignRegister(v1, potential.first);
     }
   }
 
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 b846c87..15dc292 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -504,7 +504,7 @@
     return new CreateInstance(
         node.classElement,
         translateArguments(node.arguments),
-        translateArguments(node.typeInformation),
+        getVariableUseOrNull(node.typeInformation),
         node.sourceInformation);
   }
 
@@ -543,17 +543,6 @@
             translateArguments(node.values));
   }
 
-  Expression visitLiteralMap(cps_ir.LiteralMap node) {
-    return new LiteralMap(
-        node.dartType,
-        new List<LiteralMapEntry>.generate(node.entries.length, (int index) {
-          return new LiteralMapEntry(
-              getVariableUse(node.entries[index].key),
-              getVariableUse(node.entries[index].value));
-        })
-    );
-  }
-
   Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
     return new ReifyRuntimeType(
         getVariableUse(node.value), node.sourceInformation);
@@ -568,6 +557,7 @@
 
   Expression visitTypeExpression(cps_ir.TypeExpression node) {
     return new TypeExpression(
+        node.kind,
         node.dartType,
         node.arguments.map(getVariableUse).toList());
   }
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 19eeb05..2b4d301 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -13,6 +13,8 @@
 
 import '../cps_ir/builtin_operator.dart';
 export '../cps_ir/builtin_operator.dart';
+import '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
+export '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
 
 // These imports are only used for the JavaScript specific nodes.  If we want to
 // support more than one native backend, we should probably create better
@@ -114,7 +116,8 @@
     assert(host != null);
   }
 
-  String toString() => element == null ? 'Variable' : element.toString();
+  String toString() =>
+      element == null ? 'Variable.${hashCode}' : element.toString();
 }
 
 /// Read the value of a variable.
@@ -312,25 +315,6 @@
   }
 }
 
-class LiteralMapEntry {
-  Expression key;
-  Expression value;
-
-  LiteralMapEntry(this.key, this.value);
-}
-
-class LiteralMap extends Expression {
-  final InterfaceType type;
-  final List<LiteralMapEntry> entries;
-
-  LiteralMap(this.type, this.entries);
-
-  accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this);
-  accept1(ExpressionVisitor1 visitor, arg) {
-    return visitor.visitLiteralMap(this, arg);
-  }
-}
-
 /// Type test or type cast.
 ///
 /// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`,
@@ -688,7 +672,7 @@
 class CreateInstance extends Expression {
   ClassElement classElement;
   List<Expression> arguments;
-  List<Expression> typeInformation;
+  Expression typeInformation;
   SourceInformation sourceInformation;
 
   CreateInstance(this.classElement, this.arguments,
@@ -760,8 +744,9 @@
   Element element;
   Expression value;
   SourceInformation sourceInformation;
+  BuiltinOperator compound;
 
-  SetStatic(this.element, this.value, this.sourceInformation);
+  SetStatic(this.element, this.value, this.sourceInformation, {this.compound});
 
   accept(ExpressionVisitor visitor) => visitor.visitSetStatic(this);
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetStatic(this, arg);
@@ -920,10 +905,11 @@
 /// are replaced by the values in [arguments].
 /// (See documentation on the TypeExpression CPS node for more details.)
 class TypeExpression extends Expression {
+  final TypeExpressionKind kind;
   final DartType dartType;
   final List<Expression> arguments;
 
-  TypeExpression(this.dartType, this.arguments);
+  TypeExpression(this.kind, this.dartType, this.arguments);
 
   accept(ExpressionVisitor visitor) {
     return visitor.visitTypeExpression(this);
@@ -999,7 +985,6 @@
   E visitLogicalOperator(LogicalOperator node);
   E visitNot(Not node);
   E visitLiteralList(LiteralList node);
-  E visitLiteralMap(LiteralMap node);
   E visitTypeOperator(TypeOperator node);
   E visitGetField(GetField node);
   E visitSetField(SetField node);
@@ -1037,7 +1022,6 @@
   E visitLogicalOperator(LogicalOperator node, A arg);
   E visitNot(Not node, A arg);
   E visitLiteralList(LiteralList node, A arg);
-  E visitLiteralMap(LiteralMap node, A arg);
   E visitTypeOperator(TypeOperator node, A arg);
   E visitGetField(GetField node, A arg);
   E visitSetField(SetField node, A arg);
@@ -1156,13 +1140,6 @@
     node.values.forEach(visitExpression);
   }
 
-  visitLiteralMap(LiteralMap node) {
-    node.entries.forEach((LiteralMapEntry entry) {
-      visitExpression(entry.key);
-      visitExpression(entry.value);
-    });
-  }
-
   visitTypeOperator(TypeOperator node) {
     visitExpression(node.value);
     node.typeArguments.forEach(visitExpression);
@@ -1243,7 +1220,7 @@
 
   visitCreateInstance(CreateInstance node) {
     node.arguments.forEach(visitExpression);
-    node.typeInformation.forEach(visitExpression);
+    if (node.typeInformation != null) visitExpression(node.typeInformation);
   }
 
   visitReifyRuntimeType(ReifyRuntimeType node) {
@@ -1390,14 +1367,6 @@
     return node;
   }
 
-  visitLiteralMap(LiteralMap node) {
-    node.entries.forEach((LiteralMapEntry entry) {
-      entry.key = visitExpression(entry.key);
-      entry.value = visitExpression(entry.value);
-    });
-    return node;
-  }
-
   visitTypeOperator(TypeOperator node) {
     node.value = visitExpression(node.value);
     _replaceExpressions(node.typeArguments);
@@ -1492,7 +1461,9 @@
 
   visitCreateInstance(CreateInstance node) {
     _replaceExpressions(node.arguments);
-    _replaceExpressions(node.typeInformation);
+    if (node.typeInformation != null) {
+      node.typeInformation = visitExpression(node.typeInformation);
+    }
     return node;
   }
 
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 979647a..6d2ce7e 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -414,16 +414,6 @@
     return "list [$values]";
   }
 
-  String visitLiteralMap(LiteralMap node) {
-    List<String> entries = new List<String>();
-    node.entries.forEach((LiteralMapEntry entry) {
-      String key = visitExpression(entry.key);
-      String value = visitExpression(entry.value);
-      entries.add("$key: $value");
-    });
-    return "map [${entries.join(', ')}]";
-  }
-
   String visitConstant(Constant node) {
     return "${node.value.toStructuredString()}";
   }
@@ -533,7 +523,9 @@
 
   @override
   String visitTypeExpression(TypeExpression node) {
-    return node.dartType.toString();
+    String kind = '${node.kind}'.split('.').last;
+    String args = node.arguments.map(visitExpression).join(', ');
+    return 'TypeExpression($kind, ${node.dartType}, $args)';
   }
 
   @override
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 1129465..e7ecab1 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -36,15 +36,15 @@
 
   @override
   TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {
-    // We have to distinguish -0.0 from 0, but for all practical purposes
-    // -0.0 is an integer.
-    // TODO(17235): this kind of special casing should only happen in the
-    // backend.
-    if (constant.isMinusZero &&
-        compiler.backend.constantSystem.isInt(constant)) {
-      return compiler.typesTask.uint31Type;
+    // We have to recognize double constants that are 'is int'.
+    if (compiler.backend.constantSystem.isInt(constant)) {
+      if (constant.isMinusZero) {
+        return compiler.typesTask.uint31Type;
+      } else {
+        assert(constant.isPositiveInfinity || constant.isNegativeInfinity);
+        return compiler.typesTask.intType;
+      }
     }
-    assert(!compiler.backend.constantSystem.isInt(constant));
     return compiler.typesTask.doubleType;
   }
 
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 6516d96..914e673 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -358,6 +358,47 @@
     }
   }
 
+  bool isDisjoint(TypeMask other, ClassWorld classWorld) {
+    if (other is! FlatTypeMask) return other.isDisjoint(this, classWorld);
+    FlatTypeMask flatOther = other;
+
+    if (isNullable && flatOther.isNullable) return false;
+    if (isEmpty || flatOther.isEmpty) return true;
+    if (base == flatOther.base) return false;
+    if (isExact && flatOther.isExact) return true;
+
+    if (isExact) return !flatOther.contains(base, classWorld);
+    if (flatOther.isExact) return !contains(flatOther.base, classWorld);
+
+    // Normalization guarantees that isExact === !isSubclass && !isSubtype.
+    // Both are subclass or subtype masks, so if there is a subclass
+    // relationship, they are not disjoint.
+    if (classWorld.isSubclassOf(flatOther.base, base)) return false;
+    if (classWorld.isSubclassOf(base, flatOther.base)) return false;
+
+    // Two different base classes have no common subclass unless one is a
+    // subclass of the other (checked above).
+    if (isSubclass && flatOther.isSubclass) return true;
+
+    return _isDisjointHelper(this, flatOther, classWorld);
+  }
+
+  static bool _isDisjointHelper(
+      FlatTypeMask a, FlatTypeMask b, ClassWorld classWorld) {
+    if (!a.isSubclass && b.isSubclass) {
+      return _isDisjointHelper(b, a, classWorld);
+    }
+    assert(a.isSubclass || a.isSubtype);
+    assert(b.isSubtype);
+    var elements = a.isSubclass
+      ? classWorld.strictSubclassesOf(a.base)
+      : classWorld.strictSubtypesOf(a.base);
+    for (var element in elements) {
+      if (classWorld.isSubtypeOf(element, b.base)) return false;
+    }
+    return true;
+  }
+
   TypeMask intersectionSame(FlatTypeMask other, ClassWorld classWorld) {
     assert(base == other.base);
     // The two masks share the base type, so we must chose the most
@@ -685,16 +726,7 @@
     if (xSubset == null) return null;
     Iterable<ClassElement> ySubset = containedSubset(y, classWorld);
     if (ySubset == null) return null;
-    Iterable<ClassElement> smallSet, largeSet;
-    if (xSubset.length <= ySubset.length) {
-      smallSet = xSubset;
-      largeSet = ySubset;
-    } else {
-      smallSet = ySubset;
-      largeSet = xSubset;
-    }
-    var result = smallSet.where((ClassElement each) => largeSet.contains(each));
-    return result.toSet();
+    return xSubset.toSet().intersection(ySubset.toSet());
   }
 
   static Iterable<ClassElement> containedSubset(FlatTypeMask x,
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index ce29f50..a4400c6 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -84,6 +84,10 @@
     return forwardTo.union(other, classWorld);
   }
 
+  bool isDisjoint(TypeMask other, ClassWorld classWorld) {
+    return forwardTo.isDisjoint(other, classWorld);
+  }
+
   TypeMask intersection(TypeMask other, ClassWorld classWorld) {
     return forwardTo.intersection(other, classWorld);
   }
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 3339738..736df0d 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -329,6 +329,10 @@
    */
   TypeMask union(TypeMask other, ClassWorld classWorld);
 
+
+  /// Returns whether the intersection of this and [other] is empty.
+  bool isDisjoint(TypeMask other, ClassWorld classWorld);
+
   /**
    * Returns a type mask representing the intersection of [this] and [other].
    */
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 4a8397e..6166349 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -118,11 +118,11 @@
         // 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);
+        size = classWorld.strictSubclassCount(candidate);
+        assert(size <= classWorld.strictSubtypeCount(candidate));
       } else {
         kind = FlatTypeMask.SUBTYPE;
-        size = classWorld.strictSubtypesOf(candidate).length;
+        size = classWorld.strictSubtypeCount(candidate);
       }
       // Update the best candidate if the new one is better.
       if (bestElement == null || size < bestSize) {
@@ -152,12 +152,17 @@
   TypeMask intersection(var other, ClassWorld classWorld) {
     other = TypeMask.nonForwardingMask(other);
     if (!other.isUnion && disjointMasks.contains(other)) return other;
+    if (other.isUnion && this == other) return this;
 
     List<TypeMask> intersections = <TypeMask>[];
     for (TypeMask current in disjointMasks) {
       if (other.isUnion) {
-        for (FlatTypeMask flatOther in other.disjointMasks) {
-          intersections.add(current.intersection(flatOther, classWorld));
+        if (other.disjointMasks.contains(current)) {
+          intersections.add(current);
+        } else {
+          for (FlatTypeMask flatOther in other.disjointMasks) {
+            intersections.add(current.intersection(flatOther, classWorld));
+          }
         }
       } else {
         intersections.add(current.intersection(other, classWorld));
@@ -166,6 +171,13 @@
     return new TypeMask.unionOf(intersections, classWorld);
   }
 
+  bool isDisjoint(TypeMask other, ClassWorld classWorld) {
+    for (var current in disjointMasks) {
+      if (!current.isDisjoint(other, classWorld)) return false;
+    }
+    return true;
+  }
+
   TypeMask nullable() {
     if (isNullable) return this;
     List<FlatTypeMask> newList = new List<FlatTypeMask>.from(disjointMasks);
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index d895de2..3790a03 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,6 +6,7 @@
 
 import 'dart:collection' show
     IterableBase;
+import '../common.dart';
 import '../elements/elements.dart' show
     ClassElement;
 import '../util/enumset.dart' show
@@ -92,12 +93,14 @@
     return mask;
   }
 
+  final ClassHierarchyNode parentNode;
   final ClassElement cls;
   final EnumSet<Instantiation> _mask =
       new EnumSet<Instantiation>.fromValues(
           const <Instantiation>[Instantiation.UNINSTANTIATED]);
 
   ClassElement _leastUpperInstantiatedSubclass;
+  int _instantiatedSubclassCount = 0;
 
   /// `true` if [cls] has been directly instantiated.
   ///
@@ -111,14 +114,23 @@
 
   void set isDirectlyInstantiated(bool value) {
     if (value != isDirectlyInstantiated) {
+      ClassHierarchyNode parent = parentNode;
       if (value) {
         _mask.remove(Instantiation.UNINSTANTIATED);
         _mask.add(Instantiation.DIRECTLY_INSTANTIATED);
+        while (parent != null) {
+          parent._updateInstantiatedSubclassCount(1);
+          parent = parent.parentNode;
+        }
       } else {
         _mask.remove(Instantiation.DIRECTLY_INSTANTIATED);
         if (_mask.isEmpty) {
           _mask.add(Instantiation.UNINSTANTIATED);
         }
+        while (parent != null) {
+          parent._updateInstantiatedSubclassCount(-1);
+          parent = parent.parentNode;
+        }
       }
     }
   }
@@ -131,12 +143,18 @@
   ///   class C extends B {}
   ///   main() => [new B(), new C()];
   ///
-  bool get isIndirectlyInstantiated =>
-      _mask.contains(Instantiation.INDIRECTLY_INSTANTIATED);
+  bool get isIndirectlyInstantiated => _instantiatedSubclassCount > 0;
 
-  void set isIndirectlyInstantiated(bool value) {
-    if (value != isIndirectlyInstantiated) {
-      if (value) {
+  /// The number of strict subclasses that are directly or indirectly
+  /// instantiated.
+  int get instantiatedSubclassCount => _instantiatedSubclassCount;
+
+  void _updateInstantiatedSubclassCount(int change) {
+    bool before = isIndirectlyInstantiated;
+    _instantiatedSubclassCount += change;
+    bool after = isIndirectlyInstantiated;
+    if (before != after) {
+      if (after) {
         _mask.remove(Instantiation.UNINSTANTIATED);
         _mask.add(Instantiation.INDIRECTLY_INSTANTIATED);
       } else {
@@ -151,7 +169,11 @@
   /// The nodes for the direct subclasses of [cls].
   Link<ClassHierarchyNode> _directSubclasses = const Link<ClassHierarchyNode>();
 
-  ClassHierarchyNode(this.cls);
+  ClassHierarchyNode(this.parentNode, this.cls) {
+    if (parentNode != null) {
+      parentNode.addDirectSubclass(this);
+    }
+  }
 
   /// Adds [subclass] as a direct subclass of [cls].
   void addDirectSubclass(ClassHierarchyNode subclass) {
@@ -177,24 +199,6 @@
 
   /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
   ///
-  /// The directly instantiated, indirectly instantiated and uninstantiated
-  /// subclasses of [cls] are returned if [includeDirectlyInstantiated],
-  /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
-  /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
-  Iterable<ClassElement> subclasses(
-      {bool includeDirectlyInstantiated: true,
-       bool includeIndirectlyInstantiated: true,
-       bool includeUninstantiated: true,
-       bool strict: false}) {
-    EnumSet<Instantiation> mask = createMask(
-        includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
-        includeUninstantiated: includeUninstantiated);
-    return subclassesByMask(mask, strict: strict);
-  }
-
-  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
-  ///
   /// Subclasses are included if their instantiation properties intersect with
   /// their corresponding [Instantiation] values in [mask]. If [strict] is
   /// `true`, [cls] itself is _not_ returned.
@@ -205,6 +209,65 @@
         this, mask, includeRoot: !strict);
   }
 
+  /// Applies [predicate] to each subclass of [cls] matching the criteria
+  /// specified by [mask] and [strict]. If [predicate] returns `true` on a
+  /// class, visitation is stopped immediately and the function returns `true`.
+  ///
+  /// [predicate] is applied to subclasses if their instantiation properties
+  /// intersect with their corresponding [Instantiation] values in [mask]. If
+  /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
+  bool anySubclass(
+      bool predicate(ClassElement cls),
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+
+    ForEach wrapper(ClassElement cls) {
+      return predicate(cls) ? ForEach.STOP : ForEach.CONTINUE;
+    }
+    return forEachSubclass(wrapper, mask, strict: strict) == ForEach.STOP;
+  }
+
+  /// Applies [f] to each subclass of [cls] matching the criteria specified by
+  /// [mask] and [strict].
+  ///
+  /// [f] is a applied to subclasses if their instantiation properties intersect
+  /// with their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [f] is _not_ called on [cls] itself.
+  ///
+  /// The visitation of subclasses can be cut short by the return value of [f].
+  /// If [ForEach.STOP] is returned, no further classes are visited and the
+  /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
+  /// subclasses of the last visited class are skipped, but visitation
+  /// continues. The return value of the function is either [ForEach.STOP], if
+  /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
+  /// the end.
+  ForEach forEachSubclass(
+      ForEachFunction f,
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    ForEach forEach;
+    if (!strict && mask.intersects(_mask)) {
+      forEach = f(cls);
+    }
+    // Interpret `forEach == null` as `forEach == ForEach.CONTINUE`.
+    forEach ??= ForEach.CONTINUE;
+
+    if (forEach == ForEach.CONTINUE) {
+      if (mask.contains(Instantiation.UNINSTANTIATED) || isInstantiated) {
+        for (ClassHierarchyNode subclass in _directSubclasses) {
+          ForEach subForEach = subclass.forEachSubclass(f, mask);
+          if (subForEach == ForEach.STOP) {
+            return subForEach;
+          }
+        }
+      }
+    }
+    if (forEach == ForEach.STOP) {
+      return forEach;
+    }
+    return ForEach.CONTINUE;
+  }
+
   /// Returns the most specific subclass of [cls] (including [cls]) that is
   /// directly instantiated or a superclass of all directly instantiated
   /// subclasses. If [cls] is not instantiated, `null` is returned.
@@ -275,7 +338,8 @@
         if (instantiatedOnly && !child.isInstantiated) {
           continue;
         }
-        if (withRespectTo != null && !child.subclasses().any(isRelatedTo)) {
+        if (withRespectTo != null &&
+            !child.anySubclass(isRelatedTo, ClassHierarchyNode.ALL)) {
           continue;
         }
         if (needsComma) {
@@ -367,22 +431,31 @@
 
   ClassElement get cls => node.cls;
 
-  /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
-  ///
-  /// The directly instantiated, indirectly instantiated and uninstantiated
-  /// subclasses of [cls] are returned if [includeDirectlyInstantiated],
-  /// [includeIndirectlyInstantiated], and [includeUninstantiated] are `true`,
-  /// respectively. If [strict] is `true`, [cls] itself is _not_ returned.
-  Iterable<ClassElement> subclasses(
-      {bool includeDirectlyInstantiated: true,
-       bool includeIndirectlyInstantiated: true,
-       bool includeUninstantiated: true,
-       bool strict: false}) {
-    EnumSet<Instantiation> mask = ClassHierarchyNode.createMask(
-        includeDirectlyInstantiated: includeDirectlyInstantiated,
-        includeIndirectlyInstantiated:includeIndirectlyInstantiated,
-        includeUninstantiated: includeUninstantiated);
-    return subclassesByMask(mask, strict: strict);
+  /// Returns the number of directly instantiated subtypes of [cls].
+  int get instantiatedSubtypeCount {
+    int count = node.instantiatedSubclassCount;
+    if (_directSubtypes != null) {
+      for (ClassHierarchyNode subtypeNode in _directSubtypes) {
+        if (subtypeNode.isDirectlyInstantiated) {
+          count++;
+        }
+        count += subtypeNode.instantiatedSubclassCount;
+      }
+    }
+    return count;
+  }
+
+  /// Returns `true` if all instantiated subtypes of [cls] are subclasses of
+  /// [cls].
+  bool get hasOnlyInstantiatedSubclasses {
+    if (_directSubtypes != null) {
+      for (ClassHierarchyNode subtypeNode in _directSubtypes) {
+        if (subtypeNode.isInstantiated) {
+          return false;
+        }
+      }
+    }
+    return true;
   }
 
   /// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
@@ -414,7 +487,6 @@
     return subtypesByMask(mask, strict: strict);
   }
 
-
   /// Returns an [Iterable] of the subtypes of [cls] possibly including [cls].
   ///
   /// Subtypes are included if their instantiation properties intersect with
@@ -434,6 +506,91 @@
         includeRoot: !strict);
   }
 
+  /// Applies [predicate] to each subclass of [cls] matching the criteria
+  /// specified by [mask] and [strict]. If [predicate] returns `true` on a
+  /// class, visitation is stopped immediately and the function returns `true`.
+  ///
+  /// [predicate] is applied to subclasses if their instantiation properties
+  /// intersect with their corresponding [Instantiation] values in [mask]. If
+  /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
+  bool anySubclass(
+      bool predicate(ClassElement cls),
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return node.anySubclass(predicate, mask, strict: strict);
+  }
+
+  /// Applies [f] to each subclass of [cls] matching the criteria specified by
+  /// [mask] and [strict].
+  ///
+  /// [f] is a applied to subclasses if their instantiation properties intersect
+  /// with their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [f] is _not_ called on [cls] itself.
+  ///
+  /// The visitation of subclasses can be cut short by the return value of [f].
+  /// If [ForEach.STOP] is returned, no further classes are visited and the
+  /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
+  /// subclasses of the last visited class are skipped, but visitation
+  /// continues. The return value of the function is either [ForEach.STOP], if
+  /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
+  /// the end.
+  ForEach forEachSubclass(
+      ForEachFunction f,
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    return node.forEachSubclass(f, mask, strict: strict);
+  }
+
+  /// Applies [predicate] to each subtype of [cls] matching the criteria
+  /// specified by [mask] and [strict]. If [predicate] returns `true` on a
+  /// class, visitation is stopped immediately and the function returns `true`.
+  ///
+  /// [predicate] is applied to subtypes if their instantiation properties
+  /// intersect with their corresponding [Instantiation] values in [mask]. If
+  /// [strict] is `true`, [predicate] is _not_ called on [cls] itself.
+  bool anySubtype(
+      bool predicate(ClassElement cls),
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+
+    ForEach wrapper(ClassElement cls) {
+      return predicate(cls) ? ForEach.STOP : ForEach.CONTINUE;
+    }
+    return forEachSubtype(wrapper, mask, strict: strict) == ForEach.STOP;
+  }
+
+  /// Applies [f] to each subtype of [cls] matching the criteria specified by
+  /// [mask] and [strict].
+  ///
+  /// [f] is a applied to subtypes if their instantiation properties intersect
+  /// with their corresponding [Instantiation] values in [mask]. If [strict] is
+  /// `true`, [f] is _not_ called on [cls] itself.
+  ///
+  /// The visitation of subtypes can be cut short by the return value of [f].
+  /// If [ForEach.STOP] is returned, no further classes are visited and the
+  /// function stops immediately. If [ForEach.SKIP_SUBCLASSES] is returned, the
+  /// subclasses of the last visited class are skipped, but visitation
+  /// continues. The return value of the function is either [ForEach.STOP], if
+  /// visitation was stopped, or [ForEach.CONTINUE] if visitation continued to
+  /// the end.
+  ForEach forEachSubtype(
+      ForEachFunction f,
+      EnumSet<Instantiation> mask,
+      {bool strict: false}) {
+    ForEach forEach = node.forEachSubclass(f, mask, strict: strict);
+    forEach ??= ForEach.CONTINUE;
+    if (forEach == ForEach.CONTINUE && _directSubtypes != null) {
+      for (ClassHierarchyNode subclass in _directSubtypes) {
+        ForEach subForEach = subclass.forEachSubclass(f, mask);
+        if (subForEach == ForEach.STOP) {
+          return subForEach;
+        }
+      }
+    }
+    assert(forEach != ForEach.SKIP_SUBCLASSES);
+    return forEach;
+  }
+
   /// Adds [subtype] as a subtype of [cls].
   void addSubtype(ClassHierarchyNode subtype) {
     if (node.contains(subtype.cls)) {
@@ -695,3 +852,20 @@
     return false;
   }
 }
+
+/// Enum values returned from the [ForEachFunction] provided to the `forEachX`
+/// functions of [ClassHierarchyNode] and [ClassSet]. The value is used to
+/// control the continued iteration.
+enum ForEach {
+  /// Iteration continues.
+  CONTINUE,
+  /// Iteration stops immediately.
+  STOP,
+  /// Iteration skips the subclasses of the current class.
+  SKIP_SUBCLASSES,
+}
+
+/// Visiting function used for the `forEachX` functions of [ClassHierarchyNode]
+/// and [ClassSet]. The return value controls the continued iteration. If `null`
+/// is returned, iteration continues to the end.
+typedef ForEach ForEachFunction(ClassElement cls);
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 30b2081..da08fb6 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -93,6 +93,18 @@
   /// including [cls] itself.
   Iterable<ClassElement> strictSubclassesOf(ClassElement cls);
 
+  /// Returns the number of live classes that extend [cls] _not_
+  /// including [cls] itself.
+  int strictSubclassCount(ClassElement cls);
+
+  /// Applies [f] to each live class that extend [cls] _not_ including [cls]
+  /// itself.
+  void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls));
+
+  /// Returns `true` if [predicate] applies to any live class that extend [cls]
+  /// _not_ including [cls] itself.
+  bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls));
+
   /// Returns an iterable over the directly instantiated that implement [cls]
   /// possibly including [cls] itself, if it is live.
   Iterable<ClassElement> subtypesOf(ClassElement cls);
@@ -101,6 +113,18 @@
   /// including [cls] if it is live.
   Iterable<ClassElement> strictSubtypesOf(ClassElement cls);
 
+  /// Returns the number of live classes that implement [cls] _not_
+  /// including [cls] itself.
+  int strictSubtypeCount(ClassElement cls);
+
+  /// Applies [f] to each live class that implements [cls] _not_ including [cls]
+  /// itself.
+  void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls));
+
+  /// Returns `true` if [predicate] applies to any live class that implements
+  /// [cls] _not_ including [cls] itself.
+  bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls));
+
   /// Returns `true` if [a] and [b] have any known common subtypes.
   bool haveAnyCommonSubtypes(ClassElement a, ClassElement b);
 
@@ -248,6 +272,36 @@
         ClassHierarchyNode.DIRECTLY_INSTANTIATED, strict: true);
   }
 
+  /// Returns the number of live classes that extend [cls] _not_
+  /// including [cls] itself.
+  int strictSubclassCount(ClassElement cls) {
+    ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+    if (subclasses == null) return 0;
+    return subclasses.instantiatedSubclassCount;
+  }
+
+  /// Applies [f] to each live class that extend [cls] _not_ including [cls]
+  /// itself.
+  void forEachStrictSubclassOf(ClassElement cls, ForEach f(ClassElement cls)) {
+    ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+    if (subclasses == null) return;
+    subclasses.forEachSubclass(
+        f,
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+        strict: true);
+  }
+
+  /// Returns `true` if [predicate] applies to any live class that extend [cls]
+  /// _not_ including [cls] itself.
+  bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) {
+    ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
+    if (subclasses == null) return false;
+    return subclasses.anySubclass(
+        predicate,
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+        strict: true);
+  }
+
   /// Returns an iterable over the directly instantiated that implement [cls]
   /// possibly including [cls] itself, if it is live.
   Iterable<ClassElement> subtypesOf(ClassElement cls) {
@@ -272,6 +326,36 @@
     }
   }
 
+  /// Returns the number of live classes that implement [cls] _not_
+  /// including [cls] itself.
+  int strictSubtypeCount(ClassElement cls) {
+    ClassSet classSet = _classSets[cls.declaration];
+    if (classSet == null) return 0;
+    return classSet.instantiatedSubtypeCount;
+  }
+
+  /// Applies [f] to each live class that implements [cls] _not_ including [cls]
+  /// itself.
+  void forEachStrictSubtypeOf(ClassElement cls, ForEach f(ClassElement cls)) {
+    ClassSet classSet = _classSets[cls.declaration];
+    if (classSet == null) return;
+    classSet.forEachSubtype(
+        f,
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+        strict: true);
+  }
+
+  /// Returns `true` if [predicate] applies to any live class that extend [cls]
+  /// _not_ including [cls] itself.
+  bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) {
+    ClassSet classSet = _classSets[cls.declaration];
+    if (classSet == null) return false;
+    return classSet.anySubtype(
+        predicate,
+        ClassHierarchyNode.DIRECTLY_INSTANTIATED,
+        strict: true);
+  }
+
   /// Returns `true` if [a] and [b] have any known common subtypes.
   bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) {
     ClassSet classSetA = _classSets[a.declaration];
@@ -298,7 +382,7 @@
   /// Returns `true` if any directly instantiated class other than [cls]
   /// implements [cls].
   bool hasAnyStrictSubtype(ClassElement cls) {
-    return !strictSubtypesOf(cls).isEmpty;
+    return strictSubtypeCount(cls) > 0;
   }
 
   /// Returns `true` if all directly instantiated classes that implement [cls]
@@ -306,10 +390,12 @@
   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);
-    return subclasses != null && (subclasses.length == subtypes.length);
+    ClassSet classSet = _classSets[cls.declaration];
+    if (classSet == null) {
+      // Vacuously true.
+      return true;
+    }
+    return classSet.hasOnlyInstantiatedSubclasses;
   }
 
   @override
@@ -501,11 +587,11 @@
   ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) {
     cls = cls.declaration;
     return _classHierarchyNodes.putIfAbsent(cls, () {
-      ClassHierarchyNode node = new ClassHierarchyNode(cls);
+      ClassHierarchyNode parentNode;
       if (cls.superclass != null) {
-        _ensureClassHierarchyNode(cls.superclass).addDirectSubclass(node);
+        parentNode = _ensureClassHierarchyNode(cls.superclass);
       }
-      return node;
+      return new ClassHierarchyNode(parentNode, cls);
     });
   }
 
@@ -534,31 +620,28 @@
     });
   }
 
-  void _updateClassHierarchyNodeForClass(
-      ClassElement cls,
-      {bool directlyInstantiated: false,
-       bool indirectlyInstantiated: false}) {
-    ClassHierarchyNode node = getClassHierarchyNode(cls);
-    bool changed = false;
-    if (directlyInstantiated && !node.isDirectlyInstantiated) {
-      node.isDirectlyInstantiated = true;
-      changed = true;
-    }
-    if (indirectlyInstantiated && !node.isIndirectlyInstantiated) {
-      node.isIndirectlyInstantiated = true;
-      changed = true;
-    }
-    if (changed && cls.superclass != null) {
-      _updateClassHierarchyNodeForClass(
-          cls.superclass, indirectlyInstantiated: true);
-    }
+  void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) {
     // Ensure that classes implicitly implementing `Function` are in its
     // subtype set.
+    ClassElement cls = node.cls;
     if (cls != coreClasses.functionClass &&
-        cls.implementsFunction(compiler)) {
+        cls.implementsFunction(coreClasses)) {
       ClassSet subtypeSet = _ensureClassSet(coreClasses.functionClass);
       subtypeSet.addSubtype(node);
     }
+    if (!node.isInstantiated && node.parentNode != null) {
+      _updateSuperClassHierarchyNodeForClass(node.parentNode);
+    }
+  }
+
+  void _updateClassHierarchyNodeForClass(
+      ClassElement cls,
+      {bool directlyInstantiated: false}) {
+    ClassHierarchyNode node = getClassHierarchyNode(cls);
+    _updateSuperClassHierarchyNodeForClass(node);
+    if (directlyInstantiated) {
+      node.isDirectlyInstantiated = true;
+    }
   }
 
   void populate() {
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 3b7e3ea..922f69a 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -13,12 +13,9 @@
     path: ../../sdk/lib/_internal/js_runtime
   sdk_library_metadata:
     path: ../../sdk/lib/_internal/sdk_library_metadata
-  dart2js_info:
-    path: ../../../../dart2js_info
+  dart2js_info: ^0.2.4
   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
deleted file mode 100644
index 8d9b8ca..0000000
--- a/pkg/dart_messages/bin/json_converter.dart
+++ /dev/null
@@ -1,20 +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.
-
-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
index 2d7ed53..f94b384 100644
--- a/pkg/dart_messages/bin/message_id.dart
+++ b/pkg/dart_messages/bin/message_id.dart
@@ -23,7 +23,7 @@
 /// Computes a random message ID that hasn't been used before.
 void main() {
   var usedIds =
-      shared_messages.MESSAGES.values.map((entry) => entry['id']).toSet();
+      shared_messages.MESSAGES.values.map((entry) => entry.id).toSet();
 
   print("${usedIds.length} existing ids");
 
diff --git a/pkg/dart_messages/bin/publish.dart b/pkg/dart_messages/bin/publish.dart
new file mode 100644
index 0000000..c7b9c11
--- /dev/null
+++ b/pkg/dart_messages/bin/publish.dart
@@ -0,0 +1,224 @@
+// 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';
+
+const String jsonPath = '../lib/generated/shared_messages.json';
+const String dart2jsPath =
+    '../../compiler/lib/src/diagnostics/generated/shared_messages.dart';
+const String analyzerPath =
+    '../../analyzer/lib/src/generated/generated/shared_messages.dart';
+
+final String dontEditWarning = """
+/*
+DON'T EDIT. GENERATED. DON'T EDIT.
+This file has been generated by 'publish.dart' in the dart_messages package.
+
+Messages are maintained in `lib/shared_messages.dart` of that same package.
+After any change to that file, run `bin/publish.dart` to generate a new version
+of the json, dart2js and analyzer representations.
+*/""";
+
+const String copyrightHeader = '''
+// 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.''';
+
+void markAsReadonly(String path) {
+  // TODO(15078): mark as read-only. Currently not possible:
+  // http://dartbug.com/15078.
+}
+
+void emitJson() {
+  var input = MESSAGES;
+  var outPath = Platform.script.resolve(jsonPath).toFilePath();
+  print("Emitting JSON:");
+  print("  Input: ${input.length} entries");
+  print("  Output: $outPath");
+  new File(outPath).writeAsStringSync(messagesAsJson);
+  print("Emitting JSON done.");
+}
+
+/// Escapes the given string [str].
+///
+/// The parameter [str] may be `null` in which case the result is "null".
+String escapeString(String str) {
+  return JSON.encode(str);
+}
+
+/// Emits the messages in dart2js format.
+///
+/// The dart2js-format consists of two entities:
+///   1. the `MessageKind` enum, and
+///   2. the MessageKind-to-Template map `TEMPLATES`.
+///
+/// The template is an instance of MessageTemplate:
+///
+///     const MessageTemplate(
+///        this.kind,
+///        this.template,
+///        {this.howToFix,
+///         this.examples,
+///         this.options: const <String>[]});
+///
+/// A sample output thus looks as follows:
+///
+///     enum MessageKind {
+///       EXAMPLE_MESSAGE,
+///     }
+///
+///     const Map<MessageKind, MessageTemplate> {
+///       EXAMPLE_MESSAGE: const MessageTemplate(
+///         EXAMPLE_MESSAGE,
+///         "Don't use #foo with #bar",
+///         howToFix: "Just don't do it",
+///         options: const ['--some-flag']),
+///         examples: const ['''
+///     some example with bad code;'''],
+///     };
+void emitDart2js() {
+  var input = MESSAGES;
+  var outPath = Platform.script.resolve(dart2jsPath).toFilePath();
+  print("Emitting dart2js:");
+  print("  Input: ${input.length} entries");
+  print("  Output: $outPath");
+
+  var enumIds = input.keys.toList();
+
+  StringBuffer out = new StringBuffer();
+  out.writeln(copyrightHeader);
+  out.writeln(dontEditWarning);
+  out.writeln("import '../messages.dart' show MessageTemplate;");
+  out.writeln();
+  out.write(("enum SharedMessageKind {\n  "));
+  // We generate on one line on purpose, so that users are less likely to
+  // modify the generated file.
+  out.writeln(enumIds.join(",\n  "));
+  out.writeln("}");
+  out.writeln();
+  out.writeln("const Map<SharedMessageKind, MessageTemplate> TEMPLATES = "
+      "const <SharedMessageKind, MessageTemplate>{ ");
+  input.forEach((name, message) {
+    out.writeln("  SharedMessageKind.$name: const MessageTemplate(");
+    // TODO(floitsch): include id.
+    out.writeln("    SharedMessageKind.$name,");
+    out.write("    ");
+    out.write(escapeString(message.template));
+    if (message.howToFix != null) {
+      out.write(",\n    howToFix: ${escapeString(message.howToFix)}");
+    }
+    if (message.options != null) {
+      out.write(",\n    options: const [");
+      out.write(message.options.map(escapeString).join(","));
+      out.writeln("]");
+    }
+    if (message.examples != null) {
+      out.writeln(",\n    examples: const [");
+      for (var example in message.examples) {
+        if (example is String) {
+          out.writeln("      r'''");
+          out.write(example);
+          out.write("'''");
+        } else if (example is Map) {
+          out.writeln("      const {");
+          example.forEach((String fileName, String content) {
+            out.writeln("      '$fileName': r'''");
+            out.write(content);
+            out.writeln("''',");
+          });
+          out.write("      }");
+        }
+        out.writeln(",");
+      }
+      out.writeln("    ]");
+    }
+    out.writeln("  ),  // Generated. Don't edit.");
+  });
+  out.writeln("};");
+
+  new File(outPath).writeAsStringSync(out.toString());
+  print("Emitting dart2js done.");
+}
+
+String convertToAnalyzerTemplate(String template, holeOrder) {
+  var holeMap;
+  if (holeOrder != null) {
+    holeMap = {};
+    for (int i = 0; i < holeOrder.length; i++) {
+      holeMap[holeOrder[i]] = i;
+    }
+  }
+  int seenHoles = 0;
+  return template.replaceAllMapped(new RegExp(r"#\w+"), (Match match) {
+    if (holeMap != null) {
+      String holeName = match[0].substring(1);
+      int index = holeMap[holeName];
+      if (index == null) {
+        throw "Couldn't find hole-position for $holeName $holeMap";
+      }
+      return "{$index}";
+    } else {
+      return "{${seenHoles++}}";
+    }
+  });
+}
+
+/// Emits the messages in analyzer format.
+///
+/// Messages are encoded as instances of `ErrorCode` classes where the
+/// corresponding class is given by the `category` field of the Message.
+///
+/// All instances are stored as top-level const variables.
+///
+/// A sample output looks as follows:
+///
+///     const FooCategoryErrorCode EXAMPLE_MESSAGE = const FooCategoryErrorCode(
+///         "EXAMPLE_MESSAGE",
+///         "Don't use {0} with {1}",
+///         "Just don't do it");
+void emitAnalyzer() {
+  var input = MESSAGES;
+  var outPath = Platform.script.resolve(analyzerPath).toFilePath();
+  print("Emitting analyzer:");
+  print("  Input: ${input.length} entries");
+  print("  Output: $outPath");
+
+  StringBuffer out = new StringBuffer();
+  out.writeln(copyrightHeader);
+  out.writeln(dontEditWarning);
+  out.writeln("import 'package:analyzer/src/generated/error.dart';");
+  out.writeln();
+  input.forEach((name, message) {
+    Category category = message.category;
+    String className = category.name + "Code";
+    out.writeln("const $className $name = const $className(");
+    out.writeln("    '$name',");
+
+    String template = message.template;
+    List holeOrder = message.templateHoleOrder;
+    String analyzerTemplate = convertToAnalyzerTemplate(template, holeOrder);
+    out.write("    ");
+    out.write(escapeString(analyzerTemplate));
+    out.write(",\n    ");
+    out.write(escapeString(message.howToFix));
+    out.writeln(");  // Generated. Don't edit.");
+  });
+
+  new File(outPath).writeAsStringSync(out.toString());
+  print("Emitting analyzer done.");
+}
+
+/// Translates the shared messages in `../lib/shared_messages.dart` to JSON,
+/// dart2js, and analyzer formats.
+///
+/// Emits the json-output to [jsonPath], the dart2js-output to [dart2jsPath],
+/// and the analyzer-output to [analyzerPath].
+void main() {
+  emitJson();
+  emitDart2js();
+  emitAnalyzer();
+}
diff --git a/pkg/dart_messages/lib/generated/shared_messages.json b/pkg/dart_messages/lib/generated/shared_messages.json
new file mode 100644
index 0000000..606bc60
--- /dev/null
+++ b/pkg/dart_messages/lib/generated/shared_messages.json
@@ -0,0 +1 @@
+{"exampleMessage":{"id":"use an Id generated by bin/message_id.dart","category":"AnalysisOptionsError","template":"#use #named #arguments","howToFix":"an explanation on how to fix things"}}
\ No newline at end of file
diff --git a/pkg/dart_messages/lib/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
index bd51f58..896f52a 100644
--- a/pkg/dart_messages/lib/shared_messages.dart
+++ b/pkg/dart_messages/lib/shared_messages.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 // An update to this file must be followed by regenerating the corresponding
-// json file. Use `json_converter.dart` in the bin directory.
+// json, dart2js and analyzer file. Use `publish.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.
@@ -58,5 +58,78 @@
 // 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 Map<String, Map> MESSAGES = {
+import 'dart:convert';
+
+/// Encodes the category of the message.
+///
+/// This is currently only used in the analyzer.
+// TODO(floitsch): encode severity and type in the category, so we can generate
+// the corresponding ErrorCode subclasses.
+class Category {
+  static final analysisOptionsError = new Category("AnalysisOptionsError");
+
+  static final analysisOptionsWarning = new Category("AnalysisOptionsWarning");
+
+  static final checkedModeCompileTimeError = new Category(
+      "CheckedModeCompileTimeError");
+
+  final String name;
+
+  Category(this.name);
+}
+
+
+class Message {
+  final String id;
+  final Category category;
+  final String template;
+  // The analyzer fills holes positionally (and not named). The following field
+  // overrides the order of the holes.
+  // For example the template "The argument #field in #cls is bad", could have
+  // the order `["cls", "field"]', which means that the analyzer would first
+  // provide the class `cls` and then only `field`.
+  // This list is generally `null`, but when it is provided it must contain all
+  // holes.
+  final List templateHoleOrder;
+  final String howToFix;
+  final List<String> options;
+  final List examples;
+
+  Message({this.id, this.category, this.template, this.templateHoleOrder,
+      this.howToFix, this.options, this.examples});
+}
+
+String get messagesAsJson {
+  var jsonified = {};
+  MESSAGES.forEach((String name, Message message) {
+    jsonified[name] =  {
+      'id': message.id,
+      'category': message.category.name,
+      'template': message.template,
+      'howToFix': message.howToFix
+    };
+  });
+  return JSON.encode(jsonified);
+}
+
+final Map<String, Message> MESSAGES = {
+  'exampleMessage': new Message(
+      id: 'use an Id generated by bin/message_id.dart',
+      category: Category.analysisOptionsError,
+      template: "#use #named #arguments",
+      templateHoleOrder: ["arguments", "named", "use"],
+      howToFix: "an explanation on how to fix things",
+      examples: [r'''
+      Some multiline example;
+      That generates the bug.''',
+      {
+      'fileA.dart': '''
+        or a map from file to content.
+        again multiline''',
+      'fileB.dart': '''
+        with possibly multiple files.
+        muliline too'''
+      }
+    ]
+  ),
 };
diff --git a/pkg/dart_messages/lib/shared_messages.json b/pkg/dart_messages/lib/shared_messages.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/pkg/dart_messages/lib/shared_messages.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/pkg/dart_messages/test/dart_messages_test.dart b/pkg/dart_messages/test/dart_messages_test.dart
index 3983773..b0ef4a5 100644
--- a/pkg/dart_messages/test/dart_messages_test.dart
+++ b/pkg/dart_messages/test/dart_messages_test.dart
@@ -2,7 +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.
 
-import 'dart:convert';
 import 'dart:io';
 
 import '../lib/shared_messages.dart';
@@ -12,14 +11,14 @@
   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 jsonUri = Uri.parse(packageRoot).resolve(
+      'dart_messages/generated/shared_messages.json');
   var jsonPath = jsonUri.toFilePath();
   var content = new File(jsonPath).readAsStringSync();
-  if (JSON.encode(MESSAGES) != content) {
+  if (messagesAsJson != 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.");
+    print("Please run bin/publish.dart to update the JSON file.");
     throw "Content is not the same";
   }
 }
@@ -27,7 +26,7 @@
 void testIdsAreUnique() {
   var usedIds = new Set();
   for (var entry in MESSAGES.values) {
-    var id = entry['id'];
+    var id = entry.id;
     if (!usedIds.add(id)) {
       throw "Id appears twice: $id";
     }
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index b6d11aa..07a20f1 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -195,7 +195,9 @@
 
 /// This tag interface has no behaviour but must be implemented by any class
 /// that is to be stored on a [Node] as source information.
-abstract class JavaScriptNodeSourceInformation {}
+abstract class JavaScriptNodeSourceInformation {
+  const JavaScriptNodeSourceInformation();
+}
 
 abstract class Node {
   JavaScriptNodeSourceInformation get sourceInformation => _sourceInformation;
@@ -1075,7 +1077,7 @@
   LiteralNumber(this.value);
 
   int get precedenceLevel => value.startsWith('-') ? UNARY : PRIMARY;
-  
+
   accept(NodeVisitor visitor) => visitor.visitLiteralNumber(this);
   LiteralNumber _clone() => new LiteralNumber(value);
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 8f29f55..4f93259 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -26,6 +26,7 @@
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
 analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
 analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
+analyzer_cli/test/driver_test: Fail # Issue 25471
 
 [ $compiler == dart2js ]
 analyzer_cli/test/*: SkipByDesign # Only meant to run on vm
@@ -44,11 +45,15 @@
 analysis_server/test/services/index/store/codec_test: Pass, Slow
 analysis_server/test/socket_server_test: Pass, Slow # Issue 19756, 21628
 analyzer/test/dart/element/element_test: Pass, Slow # Issue 24914
+analyzer/test/dart/ast/ast_test: Pass, Slow # Issue 19756, 21628
+analyzer/test/dart/ast/utilities_test: Pass, Slow # Issue 19756, 21628
+analyzer/test/dart/ast/visitor_test: Pass, Slow # Issue 19756, 21628
 analyzer/test/enum_test: Slow, Pass, Fail # Issue 21323
 analyzer/test/generated/all_the_rest_test: Pass, Slow # Issue 21628
 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/constant_test.dart: Pass, Slow # Issue 24914
 analyzer/test/generated/declaration_resolver_test: Pass, Slow # Issue 24914
 analyzer/test/generated/element_test: Pass, Slow # Issue 21628
 analyzer/test/generated/engine_test: SkipSlow
@@ -66,9 +71,13 @@
 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 24914
+analyzer/test/src/summary/prelinker_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/resynthesize_strong_test: Pass, Slow
 analyzer/test/src/summary/resynthesize_test: Pass, Slow
 analyzer/test/src/summary/summary_sdk_test: Pass, Slow # Issue 24914
-analyzer/test/src/summary/summary_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/summarize_ast_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/summarize_elements_strong_test: Pass, Slow # Issue 24914
+analyzer/test/src/summary/summarize_elements_test: Pass, Slow # Issue 24914
 analyzer/test/src/task/dart_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/dart_work_manager_test: Pass, Slow # Issue 21628
 analyzer/test/src/task/driver_test: Pass, Slow # Issue 21628
@@ -152,12 +161,13 @@
 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) ]
+[ $runtime == vm && ($arch == simarm64 || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == armv6 || $arch == armv5te) ]
 # Timeout. These are not unit tests. They do not run efficiently on our
 # simulator or low-end devices.
 *: Skip
 
 [ $runtime == vm ]
+analyzer/test/file_system/physical_resource_provider_test: Pass, Fail # Issue 25472
 # Skip tests on the VM if the package depends on dart:html
 mutation_observer: Skip
 
diff --git a/pkg/typed_mock/README.md b/pkg/typed_mock/README.md
index 2414318..2b24907 100644
--- a/pkg/typed_mock/README.md
+++ b/pkg/typed_mock/README.md
@@ -2,6 +2,213 @@
 
 It is inspired by [Mockito](https://code.google.com/p/mockito/).
 
-The existing "mock" package suffers from using method names as strings,
-which makes it impossible to use code-completion, static validation,
-search and refactoring.
+Features of this package:
+- Code-completion, static validation, search and refactoring all work properly with mocks.
+- Much better error messages for unit testing.
+- Works with concrete and abstract classes.
+- Does not use mirrors.
+- No dependent packages.
+
+Other Mock libraries for Dart:
+- https://pub.dartlang.org/packages/mockito
+- https://pub.dartlang.org/packages/mock (deprecated)
+
+## Tutorial
+
+Let's take the simple case of making sure that a method is called. The first step is to create a mock of the object, as shown below. One nice feature of Dart is that all classes automatically define interfaces, so you don't need to separately define the interface.
+
+```dart
+import 'package:typed_mock/typed_mock.dart';
+
+class Dog {
+  String speak() => "Woof!";
+}
+
+class MockDog extends TypedMock implements Dog {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+```
+
+All of the magic happens because of the noSuchMethod() function. None of the functions for Animal are actually defined because we used `implements` instead of `extends`. Therefore, all calls to this object will end up in `noSuchMethod()`.
+
+#### Verify a function is called
+
+Here's the code to verify that the function is called:
+
+```dart
+
+void main() {
+  final dog = new MockDog();
+  verifyZeroInteractions(dog);
+  dog.speak();
+  verify(dog.speak()).once();
+  verifyNoMoreInteractions(dog);
+}
+```
+
+One of the interesting features of typed_mock is that it internally tracks all calls to each mock object, then tracks which calls have been matched with a verify() call and which not. Therefore, typed_mock is able to detect unexpected calls, even if those calls are made to methods that didn't exist when the test was written. This can be a good incentive to update your tests whenever you change a class.
+
+After creating the `MockAnimal` object, we call `verifyZeroInteractions()` to make sure that the object starts in a clean state. Next we call the `speak()` method, then prove that the speak function was actually called with `verify().once()`.
+
+There are several other functions for verifying calls that can be used instead of `once()`:
+- `atLeastOnce()` Ensure the function was called one or more times.
+- `times(n)` Ensure the function was called exactly `n` times.
+- `atLeast(n)` Ensure the function was called `n` or more times.
+- `atMost(n)` Ensure the function was called no more than `n` times.
+- `any()` Mark the function call as verified if it was called, but don't fail if it wasn't called.
+- `never()` Ensure the function was never called. It's often better to use `verifyNoMoreInteractions()` instead.
+
+#### Configure the mock to return a value
+
+Here's how to return a value from `speak()`:
+
+```dart
+void main() {
+  final dog = new MockDog();
+  when(dog.speak()).thenReturn("woof");
+  final s = dog.speak();
+  print("$s");
+  verify(dog.speak()).once();
+  verifyNoMoreInteractions(dog);
+}
+```
+
+What if `speak()` took the name of an animal as a parameter? When typed_mock tracks a function call, the call tracking is based on the function name and the parameters. For example:
+
+
+```dart
+import 'package:typed_mock/typed_mock.dart';
+
+abstract class Animal {
+  String speak();
+}
+
+class MockAnimal extends TypedMock implements Animal {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+void main() {
+  final animal = new MockAnimal();
+  when(animal.speak("dog")).thenReturn("woof");
+  final s = animal.speak();
+  print("$s");
+  verify(animal.speak("dog")).once();
+}
+```
+
+Note that you can reset the call and verify tracking using `resetInteractions()`. However, there is no way to reset the `when()` calls. Create a new mock instead.
+
+You can define different results based on the value of the parameter. Notice that the calls to `verify()` explicitly states the parameter value:
+
+```dart
+void main() {
+  final animal = new MockAnimal();
+  when(animal.speak("cat")).thenReturn("meow");
+  when(animal.speak("dog")).thenReturn("woof");
+  final s = animal.speak("cat"); // Prints: meow
+  verify(animal.speak("cat")).once();
+  verify(animal.speak("dog")).never();
+}
+```
+
+#### Match any value for a parameter
+
+Sometimes you don't care about the exact value of the parameter. That's when `anyString` is used, along with its siblings `anyInt`, `anyBool` and `anyObject`.
+
+The value `anyString` is a matcher that matches any String value. For example, here's how to use `anyString` in a call to `when()`:
+
+```dart
+void main() {
+  final animal = new MockAnimal();
+  when(animal.speak(anyString)).thenReturn("meow");
+  final s1 = animal.speak("cat");
+  final s2 = animal.speak("dog");
+  print("$s1 $s2"); // Prints: meow meow
+  verify(animal.speak(anyString)).times(2);
+}
+```
+
+You can also use `anyString` in `verify()` calls, even if the `when()` calls use exact values. For example:
+
+```dart
+void main() {
+  final animal = new MockAnimal();
+  when(animal.speak("cat")).thenReturn("meow");
+  when(animal.speak("dog")).thenReturn("woof");
+  var s
+  s = animal.speak("cat");
+  s = animal.speak("cat");
+  s = animal.speak("dog");
+  verify(animal.speak(anyString)).times(3);
+}
+```
+
+You can use `anyString` as the parameter for calculated values:
+```dart
+  when(animal.speak(anyString)).thenInvoke((String s) => 'The $s speaks!');
+```
+
+In addition to `thenReturn()` and `thenInvoke()`, typed_mock supports `thenReturnList()` and `thenThrow()`. See the link at the end of this document for examples.
+
+#### Mocking operator[] and operator[]=
+
+The typed_mock package is able to track set and get access with operators `[]=` and `[]`, respectively. There's nothing special about these operators - they are just functions with non-alphanumeric names that takes two or one parameters. As with other functions, typed_mock tracks both the index and the value as needed. Note the syntax to verify that a particular array element was assigned a particular value. The act of assigning true is tracked separately from the act of assigning false. The syntax is straightforward.
+
+```dart
+import 'package:typed_mock/typed_mock.dart';
+
+abstract class Tracker {
+  operator [](int index);
+  operator []=(int index, bool b);
+}
+
+class MockTracker extends TypedMock implements Tracker {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+void main() {
+  final tracker = new MockTracker();
+  tracker[2] = true;
+  when(tracker[3]).thenReturn(false);
+  when(tracker[4]).thenReturn(true);
+  bool x = tracker[3];
+  bool y = tracker[4];
+  print("$x $y");
+  verify(tracker[1] = true).never();
+  verify(tracker[2] = false).never();
+  verify(tracker[2] = true).once();
+  verify(tracker[3]).once();
+  verify(tracker[4]).once();
+  verify(tracker[5]).never();
+}
+```
+
+#### Passing mocks as closures
+
+Passing a mock as a function parameter may not behave as you expect because a hidden function is called in the mock to get the closure. The solution is to wrap the call in a separate closure. For example, the call to `verifyNoMoreInteractions()` fails because the reference to `dog.speak` caused a hidden function to be called in `MockDog`.
+
+```dart
+void doSomething(String myfunc()) {}
+
+void main() {
+  final dog = new MockDog();
+  doSomething(dog.speak);
+  verifyNoMoreInteractions(dog);
+}
+```
+
+The solution is as follows:
+
+```dart
+void doSomething(String myfunc()) {}
+
+void main() {
+  final dog = new MockDog();
+  doSomething(() => dog.speak());
+  verifyNoMoreInteractions(dog);
+}
+```
+
+## More Information
+
+For additional examples, see the [unit tests](https://github.com/dart-lang/sdk/blob/master/pkg/typed_mock/test/typed_mock_test.dart).
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 78c5a58..11f84fc 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -629,10 +629,10 @@
     },
     {
       # dart binary for running precompiled snapshots without the compiler.
-      'target_name': 'dart_precompiled',
+      'target_name': 'dart_precompiled_runtime',
       'type': 'executable',
       'dependencies': [
-        'libdart_precompiled',
+        'libdart_precompiled_runtime',
         'libdart_builtin',
         'libdart_io',
         'build_observatory#host',
diff --git a/runtime/bin/isolate_data.h b/runtime/bin/isolate_data.h
index 29d2884..e8b8d73 100644
--- a/runtime/bin/isolate_data.h
+++ b/runtime/bin/isolate_data.h
@@ -21,9 +21,9 @@
 // when the isolate shuts down.
 class IsolateData {
  public:
-  explicit IsolateData(const char* url,
-                       const char* package_root,
-                       const char* packages_file)
+  IsolateData(const char* url,
+              const char* package_root,
+              const char* packages_file)
       : script_url(strdup(url)),
         package_root(NULL),
         packages_file(NULL),
@@ -36,14 +36,17 @@
       this->packages_file = strdup(packages_file);
     }
   }
-#if 0
+
   ~IsolateData() {
     free(script_url);
+    script_url = NULL;
     free(package_root);
+    package_root = NULL;
     free(packages_file);
+    packages_file = NULL;
     free(udp_receive_buffer);
+    udp_receive_buffer = NULL;
   }
-#endif
 
   char* script_url;
   char* package_root;
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index 707686f..f542dde 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -17,6 +17,7 @@
 
     'libdart_deps': ['libdart_lib_nosnapshot', 'libdart_lib',
                      'libdart_vm_nosnapshot', 'libdart_vm',
+                     'libdart_vm_precompiled_runtime',
                      'libdouble_conversion',],
   },
   'targets': [
@@ -55,11 +56,11 @@
       },
     },
     {
-      'target_name': 'libdart_precompiled',
+      'target_name': 'libdart_precompiled_runtime',
       'type': 'static_library',
       'dependencies': [
         'libdart_lib',
-        'libdart_vm_precompiled',
+        'libdart_vm_precompiled_runtime',
         'libdouble_conversion',
         'generate_version_cc_file#host',
       ],
@@ -81,7 +82,7 @@
       'defines': [
         # The only effect of DART_SHARED_LIB is to export the Dart API entries.
         'DART_SHARED_LIB',
-        'DART_PRECOMPILED',
+        'DART_PRECOMPILED_RUNTIME',
       ],
       'direct_dependent_settings': {
         'include_dirs': [
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index c7a2164..aa985da 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -67,8 +67,8 @@
       String::CheckedHandle(arguments->NativeArgAt(2));
   const String& dst_name = String::CheckedHandle(arguments->NativeArgAt(3));
   const String& error_msg = String::CheckedHandle(arguments->NativeArgAt(4));
-  const String& src_type_name =
-      String::Handle(Type::Handle(src_value.GetType()).UserVisibleName());
+  const String& src_type_name = String::Handle(
+      AbstractType::Handle(src_value.GetType()).UserVisibleName());
   Exceptions::CreateAndThrowTypeError(location, src_type_name,
                                       dst_type_name, dst_name, error_msg);
   UNREACHABLE();
diff --git a/runtime/lib/expando_patch.dart b/runtime/lib/expando_patch.dart
index 0c9427c..df0234d 100644
--- a/runtime/lib/expando_patch.dart
+++ b/runtime/lib/expando_patch.dart
@@ -131,7 +131,8 @@
          (object is bool) ||
          (object is num) ||
          (object is String)) {
-      throw new ArgumentError(object);
+      throw new ArgumentError.value(object,
+          "Expandos are not allowed on strings, numbers, booleans or null");
     }
   }
 
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 607e29e..b7424f5 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -28,21 +28,21 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(FunctionImpl_equals, 2) {
-  const Instance& receiver = Instance::CheckedHandle(
+DEFINE_NATIVE_ENTRY(Closure_equals, 2) {
+  const Closure& receiver = Closure::CheckedHandle(
       zone, arguments->NativeArgAt(0));
-  ASSERT(receiver.IsClosure());
   GET_NATIVE_ARGUMENT(Instance, other, arguments->NativeArgAt(1));
   ASSERT(!other.IsNull());
   if (receiver.raw() == other.raw()) return Bool::True().raw();
   if (other.IsClosure()) {
-    const Function& func_a = Function::Handle(Closure::function(receiver));
-    const Function& func_b = Function::Handle(Closure::function(other));
+    const Function& func_a = Function::Handle(receiver.function());
+    const Function& func_b = Function::Handle(Closure::Cast(other).function());
     if (func_a.raw() == func_b.raw()) {
       ASSERT(!func_a.IsImplicitStaticClosureFunction());
       if (func_a.IsImplicitInstanceClosureFunction()) {
-        const Context& context_a = Context::Handle(Closure::context(receiver));
-        const Context& context_b = Context::Handle(Closure::context(other));
+        const Context& context_a = Context::Handle(receiver.context());
+        const Context& context_b = Context::Handle(
+            Closure::Cast(other).context());
         const Object& receiver_a = Object::Handle(context_a.At(0));
         const Object& receiver_b = Object::Handle(context_b.At(0));
         if (receiver_a.raw() == receiver_b.raw()) return Bool::True().raw();
@@ -53,48 +53,38 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(FunctionImpl_hashCode, 1) {
-  const Instance& receiver = Instance::CheckedHandle(
+DEFINE_NATIVE_ENTRY(Closure_hashCode, 1) {
+  const Closure& receiver = Closure::CheckedHandle(
       zone, arguments->NativeArgAt(0));
-  if (receiver.IsClosure()) {
-    const Function& func = Function::Handle(Closure::function(receiver));
-    // Hash together name, class name and signature.
-    const Class& cls = Class::Handle(func.Owner());
-    intptr_t result = String::Handle(func.name()).Hash();
-    result += String::Handle(func.Signature()).Hash();
-    result += String::Handle(cls.Name()).Hash();
-    // Finalize hash value like for strings so that it fits into a smi.
-    result += result << 3;
-    result ^= result >> 11;
-    result += result << 15;
-    result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1);
-    return Smi::New(result);
-  }
-  UNREACHABLE();
-  return Object::null();
+  const Function& func = Function::Handle(receiver.function());
+  // Hash together name, class name and signature.
+  const Class& cls = Class::Handle(func.Owner());
+  intptr_t result = String::Handle(func.name()).Hash();
+  result += String::Handle(func.Signature()).Hash();
+  result += String::Handle(cls.Name()).Hash();
+  // Finalize hash value like for strings so that it fits into a smi.
+  result += result << 3;
+  result ^= result >> 11;
+  result += result << 15;
+  result &= ((static_cast<intptr_t>(1) << String::kHashBits) - 1);
+  return Smi::New(result);
 }
 
 
-DEFINE_NATIVE_ENTRY(FunctionImpl_clone, 1) {
-  const Instance& receiver = Instance::CheckedHandle(
+DEFINE_NATIVE_ENTRY(Closure_clone, 1) {
+  const Closure& receiver = Closure::CheckedHandle(
       zone, arguments->NativeArgAt(0));
-  ASSERT(receiver.IsClosure());
-  if (receiver.IsClosure()) {
-    const Function& func =
-        Function::Handle(zone, Closure::function(receiver));
-    const Context& ctx =
-        Context::Handle(zone, Closure::context(receiver));
-    Context& cloned_ctx =
-        Context::Handle(zone, Context::New(ctx.num_variables()));
-    cloned_ctx.set_parent(Context::Handle(zone, ctx.parent()));
-    Object& inst = Object::Handle(zone);
-    for (int i = 0; i < ctx.num_variables(); i++) {
-      inst = ctx.At(i);
-      cloned_ctx.SetAt(i, inst);
-    }
-    return Closure::New(func, cloned_ctx);
+  const Function& func = Function::Handle(zone, receiver.function());
+  const Context& ctx = Context::Handle(zone, receiver.context());
+  Context& cloned_ctx =
+      Context::Handle(zone, Context::New(ctx.num_variables()));
+  cloned_ctx.set_parent(Context::Handle(zone, ctx.parent()));
+  Object& inst = Object::Handle(zone);
+  for (int i = 0; i < ctx.num_variables(); i++) {
+    inst = ctx.At(i);
+    cloned_ctx.SetAt(i, inst);
   }
-  return Object::null();
+  return Closure::New(func, cloned_ctx);
 }
 
 
diff --git a/runtime/lib/function.dart b/runtime/lib/function.dart
index d91ce66..6c1d5cc 100644
--- a/runtime/lib/function.dart
+++ b/runtime/lib/function.dart
@@ -2,13 +2,15 @@
 // 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 _FunctionImpl implements Function {
+class _Closure implements Function {
 
-  bool operator ==(other) native "FunctionImpl_equals";
+  bool operator ==(other) native "Closure_equals";
 
-  int get hashCode native "FunctionImpl_hashCode";
+  int get hashCode native "Closure_hashCode";
 
-  _FunctionImpl get call => this;
+  _Closure get call => this;
 
-  _FunctionImpl _clone() native "FunctionImpl_clone";
+  _Closure _clone() native "Closure_clone";
+
+  // The type_arguments_, function_, and context_ fields are not declared here.
 }
diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart
index 2377c8c..b8d0d3c 100644
--- a/runtime/lib/immutable_map.dart
+++ b/runtime/lib/immutable_map.dart
@@ -11,8 +11,9 @@
 
 
   V operator [](Object key) {
-    // TODO(hausner): Since the keys are sorted, we could do a binary
-    // search. But is it worth it?
+    // To preserve the key-value order of the map literal, the keys are
+    // not sorted. Need to do linear search or implement an additional
+    // lookup table.
     for (int i = 0; i < _kvPairs.length - 1; i += 2) {
       if (key == _kvPairs[i]) {
         return _kvPairs[i+1];
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 773bac4..4e1fce8 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -226,11 +226,11 @@
 
   if (closure.IsClosure()) {
     Function& func = Function::Handle();
-    func = Closure::function(closure);
+    func = Closure::Cast(closure).function();
     if (func.IsImplicitClosureFunction() && func.is_static()) {
 #if defined(DEBUG)
       Context& ctx = Context::Handle();
-      ctx = Closure::context(closure);
+      ctx = Closure::Cast(closure).context();
       ASSERT(ctx.num_variables() == 0);
 #endif
       // Get the parent function so that we get the right function name.
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 05453f8..564db22 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -139,12 +139,18 @@
     // This covers the default constructor and forwarding constructors.
     has_extra_parameter_info = false;
   }
+  if (func.IsSignatureFunction() &&
+      (func.token_pos() == Token::kNoSourcePos)) {
+    // Signature functions (except those describing typedefs) get canonicalized,
+    // hence do not have a token position, and therefore cannot be reparsed.
+    has_extra_parameter_info = false;
+  }
 
   Array& param_descriptor = Array::Handle();
   if (has_extra_parameter_info) {
     // Reparse the function for the following information:
     // * The default value of a parameter.
-    // * Whether a parameters has been deflared as final.
+    // * Whether a parameters has been declared as final.
     // * Any metadata associated with the parameter.
     const Object& result =
         Object::Handle(Parser::ParseFunctionParameters(func));
@@ -237,18 +243,21 @@
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
   args.SetAt(1, type);
   args.SetAt(2, String::Handle(cls.Name()));
-  args.SetAt(3, Bool::Get(cls.NumTypeParameters() != 0));
-  args.SetAt(4, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
+  args.SetAt(3, Bool::Get(cls.IsGeneric()));
+  args.SetAt(4, cls.IsGeneric() ? is_declaration : Bool::False());
   args.SetAt(5, owner_mirror);
   return CreateMirror(Symbols::_LocalTypedefMirror(), args);
 }
 
 
-static RawInstance* CreateFunctionTypeMirror(const Class& cls,
-                                             const AbstractType& type) {
-  const Array& args = Array::Handle(Array::New(2));
+static RawInstance* CreateFunctionTypeMirror(const AbstractType& type) {
+  ASSERT(type.IsFunctionType());
+  const Class& cls = Class::Handle(FunctionType::Cast(type).scope_class());
+  const Function& func = Function::Handle(FunctionType::Cast(type).signature());
+  const Array& args = Array::Handle(Array::New(3));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
-  args.SetAt(1, type);
+  args.SetAt(1, MirrorReference::Handle(MirrorReference::New(func)));
+  args.SetAt(2, type);
   return CreateMirror(Symbols::_LocalFunctionTypeMirror(), args);
 }
 
@@ -304,22 +313,6 @@
   return CreateMirror(Symbols::_LocalVariableMirror(), args);
 }
 
-static RawFunction* CallMethod(const Class& cls) {
-  if (cls.IsSignatureClass()) {
-    return cls.signature_function();
-  }
-
-  Class& lookup_cls = Class::Handle(cls.raw());
-  Function& call_function = Function::Handle();
-  do {
-    call_function = lookup_cls.LookupDynamicFunction(Symbols::Call());
-    if (!call_function.IsNull()) {
-      return call_function.raw();
-    }
-    lookup_cls = lookup_cls.SuperClass();
-  } while (!lookup_cls.IsNull());
-  return Function::null();
-}
 
 static RawInstance* CreateClassMirror(const Class& cls,
                                       const AbstractType& type,
@@ -335,14 +328,8 @@
   ASSERT(!type.IsNull());
   ASSERT(type.IsFinalized());
 
-  if (cls.IsSignatureClass()) {
-    if (cls.IsCanonicalSignatureClass()) {
-      // We represent function types as canonical signature classes.
-      return CreateFunctionTypeMirror(cls, type);
-    } else {
-      // We represent typedefs as non-canonical signature classes.
-      return CreateTypedefMirror(cls, type, is_declaration, owner_mirror);
-    }
+  if (cls.IsTypedefClass()) {
+    return CreateTypedefMirror(cls, type, is_declaration, owner_mirror);
   }
 
   const Error& error = Error::Handle(cls.EnsureIsFinalized(Thread::Current()));
@@ -554,6 +541,16 @@
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsCanonical() || type.IsTypeParameter() || type.IsBoundedType());
 
+  if (type.IsFunctionType()) {
+    const Class& scope_class =
+        Class::Handle(FunctionType::Cast(type).scope_class());
+    if (scope_class.IsTypedefClass()) {
+      return CreateTypedefMirror(scope_class,
+                                 type, Bool::False(), Object::null_instance());
+    } else {
+      return CreateFunctionTypeMirror(type);
+    }
+  }
   if (type.HasResolvedTypeClass()) {
     const Class& cls = Class::Handle(type.type_class());
     // Handle void and dynamic types.
@@ -785,8 +782,8 @@
   const TypeArguments& type_args =
       TypeArguments::Handle(instantiator.arguments());
   Error& bound_error = Error::Handle();
-  AbstractType& result =
-      AbstractType::Handle(type.InstantiateFrom(type_args, &bound_error));
+  AbstractType& result = AbstractType::Handle(
+      type.InstantiateFrom(type_args, &bound_error, NULL, Heap::kOld));
   if (!bound_error.IsNull()) {
     Exceptions::PropagateError(bound_error);
     UNREACHABLE();
@@ -828,12 +825,10 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  ASSERT(type.HasResolvedTypeClass());
+  ASSERT(type.IsFunctionType() || type.HasResolvedTypeClass());
   const Class& cls = Class::Handle(type.type_class());
   ASSERT(!cls.IsNull());
-  if (cls.IsDynamicClass() ||
-      cls.IsVoidClass() ||
-      (cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass())) {
+  if (cls.IsDynamicClass() || cls.IsVoidClass() || cls.IsTypedefClass()) {
     Exceptions::ThrowArgumentError(type);
     UNREACHABLE();
   }
@@ -911,8 +906,9 @@
                                owner_mirror,
                                arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
-  const Class& cls = Class::Handle(ref.GetClassReferent());
-  const Function& func = Function::Handle(CallMethod(cls));
+  // TODO(rmacnak): Return get:call() method on class _Closure instead?
+  // This now returns the result of invoking that call getter.
+  const Function& func = Function::Handle(ref.GetFunctionReferent());
   ASSERT(!func.IsNull());
   return CreateMethodMirror(func, owner_mirror, AbstractType::Handle());
 }
@@ -921,8 +917,7 @@
 DEFINE_NATIVE_ENTRY(FunctionTypeMirror_parameters, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, owner, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1));
-  const Class& cls = Class::Handle(ref.GetClassReferent());
-  const Function& func = Function::Handle(cls.signature_function());
+  const Function& func = Function::Handle(ref.GetFunctionReferent());
   return CreateParameterMirrorList(func, owner);
 }
 
@@ -932,8 +927,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType,
                                instantiator,
                                arguments->NativeArgAt(1));
-  const Class& cls = Class::Handle(ref.GetClassReferent());
-  const Function& func = Function::Handle(CallMethod(cls));
+  const Function& func = Function::Handle(ref.GetFunctionReferent());
   ASSERT(!func.IsNull());
   AbstractType& type = AbstractType::Handle(func.result_type());
   return InstantiateType(type, instantiator);
@@ -953,10 +947,6 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const AbstractType& super_type = AbstractType::Handle(cls.super_type());
   ASSERT(super_type.IsNull() || super_type.IsFinalized());
@@ -968,10 +958,6 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const AbstractType& super_type = AbstractType::Handle(cls.super_type());
   return InstantiateType(super_type, type);
@@ -982,10 +968,6 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
   if (!error.IsNull()) {
@@ -999,10 +981,6 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const Error& error = Error::Handle(cls.EnsureIsFinalized(thread));
   if (!error.IsNull()) {
@@ -1027,10 +1005,6 @@
   GET_NON_NULL_NATIVE_ARGUMENT(AbstractType, type, arguments->NativeArgAt(0));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
   ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized());
@@ -1045,10 +1019,6 @@
                                arguments->NativeArgAt(1));
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
-  if (!type.HasResolvedTypeClass()) {
-    Exceptions::ThrowArgumentError(type);
-    UNREACHABLE();
-  }
   const Class& cls = Class::Handle(type.type_class());
   const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
   if (mixin_type.IsNull()) {
@@ -1166,13 +1136,11 @@
     entry = entries.GetNext();
     if (entry.IsClass()) {
       const Class& klass = Class::Cast(entry);
-      // We filter out function signature classes and dynamic.
+      // We filter out mixin application classes and dynamic.
       // TODO(12478): Should not need to filter out dynamic.
       // Note that the VM does not consider mixin application aliases to be
       // mixin applications.
-      if (!klass.IsCanonicalSignatureClass() &&
-          !klass.IsDynamicClass() &&
-          !klass.IsMixinApplication()) {
+      if (!klass.IsDynamicClass() && !klass.IsMixinApplication()) {
         type = klass.DeclarationType();
         member_mirror = CreateClassMirror(klass,
                                           type,
@@ -1307,9 +1275,8 @@
   // setters, assume the result is a closure and mark its function as invisible,
   // so it will not appear in stack traces. Whenever we support
   // ObjectMirror.evaluate this will need to be separated.
-  ASSERT(Instance::Cast(result).IsClosure());
-  const Function& func =
-      Function::Handle(Closure::function(Instance::Cast(result)));
+  ASSERT(result.IsClosure());
+  const Function& func = Function::Handle(Closure::Cast(result).function());
   func.set_is_visible(false);
   func.set_is_debuggable(false);
 
@@ -1317,10 +1284,9 @@
 }
 
 DEFINE_NATIVE_ENTRY(TypedefMirror_declaration, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
-  const Class& cls = Class::Handle(type.type_class());
-  // We represent typedefs as non-canonical signature classes.
-  ASSERT(cls.IsSignatureClass() && !cls.IsCanonicalSignatureClass());
+  GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0));
+  const Class& cls = Class::Handle(type.scope_class());
+  ASSERT(cls.IsTypedefClass());
   return CreateTypedefMirror(cls,
                              AbstractType::Handle(cls.DeclarationType()),
                              Bool::True(),  // is_declaration
@@ -1454,7 +1420,7 @@
 
 DEFINE_NATIVE_ENTRY(InstanceMirror_computeType, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, instance, arguments->NativeArgAt(0));
-  const Type& type = Type::Handle(instance.GetType());
+  const AbstractType& type = AbstractType::Handle(instance.GetType());
   // The static type of null is specified to be the bottom type, however, the
   // runtime type of null is the Null type, which we correctly return here.
   return type.Canonicalize();
@@ -1479,10 +1445,10 @@
     Type& instantiator = Type::Handle();
     if (closure.IsClosure()) {
       const TypeArguments& arguments =
-          TypeArguments::Handle(Closure::GetTypeArguments(closure));
+          TypeArguments::Handle(closure.GetTypeArguments());
       const Class& cls =
           Class::Handle(Isolate::Current()->object_store()->object_class());
-      instantiator = Type::New(cls, arguments, Scanner::kNoSourcePos);
+      instantiator = Type::New(cls, arguments, Token::kNoSourcePos);
       instantiator.SetIsFinalized();
     }
     return CreateMethodMirror(function,
@@ -1708,8 +1674,8 @@
       // The type arguments of the redirection type are instantiated from the
       // type arguments of the type reflected by the class mirror.
       Error& bound_error = Error::Handle();
-      redirect_type ^= redirect_type.InstantiateFrom(type_arguments,
-                                                     &bound_error);
+      redirect_type ^= redirect_type.InstantiateFrom(
+          type_arguments, &bound_error, NULL, Heap::kOld);
       if (!bound_error.IsNull()) {
         Exceptions::PropagateError(bound_error);
         UNREACHABLE();
@@ -2003,7 +1969,7 @@
   }
 
   Script& script = Script::Handle();
-  intptr_t token_pos = Scanner::kNoSourcePos;
+  intptr_t token_pos = Token::kNoSourcePos;
 
   if (decl.IsFunction()) {
     const Function& func = Function::Cast(decl);
@@ -2015,8 +1981,7 @@
     token_pos = func.token_pos();
   } else if (decl.IsClass()) {
     const Class& cls = Class::Cast(decl);
-    const bool is_typedef = cls.IsSignatureClass() &&
-                            !cls.IsCanonicalSignatureClass();
+    const bool is_typedef = cls.IsTypedefClass();
     if (cls.is_synthesized_class() &&
         !is_typedef &&
         !cls.is_mixin_app_alias() &&
@@ -2058,7 +2023,7 @@
   }
 
   ASSERT(!script.IsNull());
-  ASSERT(token_pos != Scanner::kNoSourcePos);
+  ASSERT(token_pos != Token::kNoSourcePos);
 
   const String& uri = String::Handle(script.url());
   intptr_t from_line = 0;
@@ -2077,15 +2042,25 @@
 
 
 DEFINE_NATIVE_ENTRY(TypedefMirror_referent, 1) {
-  GET_NON_NULL_NATIVE_ARGUMENT(Type, type, arguments->NativeArgAt(0));
-  const Class& cls = Class::Handle(type.type_class());
+  GET_NON_NULL_NATIVE_ARGUMENT(FunctionType, type, arguments->NativeArgAt(0));
+  const Class& cls = Class::Handle(type.scope_class());
+  ASSERT(cls.IsTypedefClass());
   const Function& sig_func = Function::Handle(cls.signature_function());
-  const Class& sig_cls = Class::Handle(sig_func.signature_class());
-
-  AbstractType& referent_type = AbstractType::Handle(sig_cls.DeclarationType());
-  referent_type = InstantiateType(referent_type, type);
-
-  return CreateFunctionTypeMirror(sig_cls, referent_type);
+  FunctionType& referent_type = FunctionType::Handle(sig_func.SignatureType());
+  // If the scope class of the function type is not generic, replace it with
+  // Closure class (Function::SignatureType() keeps it).
+  ASSERT(cls.raw() == referent_type.scope_class());
+  if (!cls.IsGeneric()) {
+    referent_type = FunctionType::New(
+        Class::Handle(Isolate::Current()->object_store()->closure_class()),
+        TypeArguments::Handle(referent_type.arguments()),
+        sig_func,
+        referent_type.token_pos());
+    referent_type ^= ClassFinalizer::FinalizeType(
+        cls, referent_type, ClassFinalizer::kCanonicalize);
+  }
+  referent_type ^= InstantiateType(referent_type, type);
+  return CreateFunctionTypeMirror(referent_type);
 }
 
 
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 0a839fb..78835a4 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -945,7 +945,8 @@
 
 class _LocalFunctionTypeMirror extends _LocalClassMirror
     implements FunctionTypeMirror {
-  _LocalFunctionTypeMirror(reflectee, reflectedType)
+  final _functionReflectee;
+  _LocalFunctionTypeMirror(reflectee, this._functionReflectee, reflectedType)
       : super(reflectee, reflectedType, null, null, false, false, false, false, false);
 
   bool get _isAnonymousMixinApplication => false;
@@ -962,7 +963,7 @@
   MethodMirror _callMethod;
   MethodMirror get callMethod {
     if (_callMethod == null) {
-      _callMethod = this._FunctionTypeMirror_call_method(_reflectee);
+      _callMethod = _FunctionTypeMirror_call_method(_functionReflectee);
     }
     return _callMethod;
   }
@@ -971,7 +972,7 @@
   TypeMirror get returnType {
     if (_returnType == null) {
       _returnType = reflectType(
-          _FunctionTypeMirror_return_type(_reflectee, _instantiator));
+          _FunctionTypeMirror_return_type(_functionReflectee, _instantiator));
     }
     return _returnType;
   }
@@ -979,7 +980,7 @@
   List<ParameterMirror> _parameters = null;
   List<ParameterMirror> get parameters {
     if (_parameters == null) {
-      _parameters = _FunctionTypeMirror_parameters(_reflectee);
+      _parameters = _FunctionTypeMirror_parameters(_functionReflectee);
       _parameters = new UnmodifiableListView(_parameters);
     }
     return _parameters;
@@ -990,16 +991,17 @@
   get typeVariables => emptyList;
   get typeArguments => emptyList;
   get metadata => emptyList;
+  get location => null;
 
   String toString() => "FunctionTypeMirror on '${_n(simpleName)}'";
 
-  MethodMirror _FunctionTypeMirror_call_method(reflectee)
+  MethodMirror _FunctionTypeMirror_call_method(functionReflectee)
       native "FunctionTypeMirror_call_method";
 
-  static Type _FunctionTypeMirror_return_type(reflectee, instantiator)
+  static Type _FunctionTypeMirror_return_type(functionReflectee, instantiator)
       native "FunctionTypeMirror_return_type";
 
-  List<ParameterMirror> _FunctionTypeMirror_parameters(reflectee)
+  List<ParameterMirror> _FunctionTypeMirror_parameters(functionReflectee)
       native "FunctionTypeMirror_parameters";
 }
 
@@ -1648,7 +1650,7 @@
       native "Mirrors_makeLocalTypeMirror";
 
   static Expando<ClassMirror> _declarationCache = new Expando("ClassMirror");
-  static Expando<TypeMirror> _instanitationCache = new Expando("TypeMirror");
+  static Expando<TypeMirror> _instantiationCache = new Expando("TypeMirror");
 
   static ClassMirror reflectClass(Type key) {
     var classMirror = _declarationCache[key];
@@ -1656,17 +1658,17 @@
       classMirror = makeLocalClassMirror(key);
       _declarationCache[key] = classMirror;
       if (!classMirror._isGeneric) {
-        _instanitationCache[key] = classMirror;
+        _instantiationCache[key] = classMirror;
       }
     }
     return classMirror;
   }
 
   static TypeMirror reflectType(Type key) {
-    var typeMirror = _instanitationCache[key];
+    var typeMirror = _instantiationCache[key];
     if (typeMirror == null) {
       typeMirror = makeLocalTypeMirror(key);
-      _instanitationCache[key] = typeMirror;
+      _instantiationCache[key] = typeMirror;
       if (typeMirror is ClassMirror && !typeMirror._isGeneric) {
         _declarationCache[key] = typeMirror;
       }
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 72fcc3e..d0eb27c 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -88,7 +88,7 @@
     // found.
     Function& function = Function::Handle();
     if (instance.IsClosure()) {
-      function = Closure::function(instance);
+      function = Closure::Cast(instance).function();
     } else {
       Class& instance_class = Class::Handle(instance.clazz());
       function = instance_class.LookupDynamicFunction(member_name);
@@ -179,7 +179,8 @@
   if (FLAG_trace_type_checks) {
     const char* result_str = is_instance_of ? "true" : "false";
     OS::Print("Native Object.instanceOf: result %s\n", result_str);
-    const Type& instance_type = Type::Handle(instance.GetType());
+    const AbstractType& instance_type =
+        AbstractType::Handle(instance.GetType());
     OS::Print("  instance type: %s\n",
               String::Handle(instance_type.Name()).ToCString());
     OS::Print("  test type: %s\n", String::Handle(type.Name()).ToCString());
@@ -289,7 +290,8 @@
   if (FLAG_trace_type_checks) {
     const char* result_str = is_instance_of ? "true" : "false";
     OS::Print("Object.as: result %s\n", result_str);
-    const Type& instance_type = Type::Handle(instance.GetType());
+    const AbstractType& instance_type =
+        AbstractType::Handle(instance.GetType());
     OS::Print("  instance type: %s\n",
               String::Handle(instance_type.Name()).ToCString());
     OS::Print("  cast type: %s\n", String::Handle(type.Name()).ToCString());
diff --git a/runtime/lib/type_patch.dart b/runtime/lib/type_patch.dart
index 67d7db5..5d0f305 100644
--- a/runtime/lib/type_patch.dart
+++ b/runtime/lib/type_patch.dart
@@ -13,6 +13,10 @@
 class _Type extends _AbstractType {
 }
 
+// Equivalent of RawFunctionType.
+class _FunctionType extends _AbstractType {
+}
+
 // Equivalent of RawTypeRef.
 class _TypeRef extends _AbstractType {
 }
diff --git a/runtime/observatory/lib/src/debugger/debugger_location.dart b/runtime/observatory/lib/src/debugger/debugger_location.dart
index caf5f57..7688712 100644
--- a/runtime/observatory/lib/src/debugger/debugger_location.dart
+++ b/runtime/observatory/lib/src/debugger/debugger_location.dart
@@ -401,13 +401,14 @@
         // Complete the line.
         var sharedPrefix = '${script.name}:';
         List completions = [];
-        for (var line in script.lines) {
-          if (line.possibleBpt) {
-            var currentLineStr = line.line.toString();
-            if (currentLineStr.startsWith(lineStr)) {
-              completions.add('${sharedPrefix}${currentLineStr} ');
-              completions.add('${sharedPrefix}${currentLineStr}:');
-            }
+        var report = await script.isolate.getSourceReport(
+            [Isolate.kPossibleBreakpointsReport], script);
+        Set<int> possibleBpts = getPossibleBreakpointLines(report, script);
+        for (var line in possibleBpts) {
+          var currentLineStr = line.toString();
+          if (currentLineStr.startsWith(lineStr)) {
+            completions.add('${sharedPrefix}${currentLineStr} ');
+            completions.add('${sharedPrefix}${currentLineStr}:');
           }
         }
         return completions;
@@ -416,9 +417,6 @@
         // Complete the column.
         int lineNum = int.parse(lineStr);
         var scriptLine = script.getLine(lineNum);
-        if (!scriptLine.possibleBpt) {
-          return [];
-        }
         var sharedPrefix = '${script.name}:${lineStr}:';
         List completions = [];
         int maxCol = scriptLine.text.trimRight().runes.length;
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index 8c67ebc..d50b092 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -88,10 +88,6 @@
     return Future.wait(loads);
   }
 
-  Future refreshCoverage() {
-    return cls.refreshCoverage();
-  }
-
   onSampleBufferChange(CpuProfile sampleBuffer) {
     stackTraceTreeConfigElement.show = sampleBuffer.sampleCount > 0;
     cpuProfileTreeElement.show = sampleBuffer.sampleCount > 0;
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 6e59887..60e8ee0 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -24,7 +24,6 @@
       <library-nav-menu library="{{ cls.library }}"></library-nav-menu>
       <class-nav-menu cls="{{ cls }}" last="{{ true }}"></class-nav-menu>
       <nav-refresh callback="{{ refreshAllocationProfile }}" label="Refresh Allocation Profile"></nav-refresh>
-      <nav-refresh callback="{{ refreshCoverage }}" label="Refresh Coverage"></nav-refresh>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
     </nav-bar>
 
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index cf78a26..06f91e7 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -8,6 +8,7 @@
 import 'dart:html';
 import 'dart:math';
 import 'observatory_element.dart';
+import 'nav_bar.dart';
 import 'package:observatory/app.dart';
 import 'package:observatory/cli.dart';
 import 'package:observatory/debugger.dart';
@@ -1067,28 +1068,6 @@
       'Syntax: info <subcommand>\n';
 }
 
-class RefreshCoverageCommand extends DebuggerCommand {
-  RefreshCoverageCommand(Debugger debugger) : super(debugger, 'coverage', []);
-
-  Future run(List<String> args) {
-    Set<Script> scripts = debugger.stackElement.activeScripts();
-    List pending = [];
-    for (var script in scripts) {
-      pending.add(script.refreshCoverage().then((_) {
-          debugger.console.print('Refreshed coverage for ${script.name}');
-        }));
-    }
-    return Future.wait(pending);
-  }
-
-  String helpShort = 'Refresh code coverage information for current frames';
-
-  String helpLong =
-      'Refresh code coverage information for current frames.\n'
-      '\n'
-      'Syntax: refresh coverage\n\n';
-}
-
 class RefreshStackCommand extends DebuggerCommand {
   RefreshStackCommand(Debugger debugger) : super(debugger, 'stack', []);
 
@@ -1106,7 +1085,6 @@
 
 class RefreshCommand extends DebuggerCommand {
   RefreshCommand(Debugger debugger) : super(debugger, 'refresh', [
-      new RefreshCoverageCommand(debugger),
       new RefreshStackCommand(debugger),
   ]);
 
@@ -1400,7 +1378,6 @@
       if ((breakOnException != iso.exceptionsPauseInfo) &&
           (iso.exceptionsPauseInfo != null)) {
         breakOnException = iso.exceptionsPauseInfo;
-        console.print("Now pausing for exceptions: $breakOnException");
       }
 
       _isolate.reload().then((response) {
@@ -1515,6 +1492,25 @@
     warnOutOfDate();
   }
 
+  void _reportIsolateError(Isolate isolate) {
+    if (isolate == null) {
+      return;
+    }
+    DartError error = isolate.error;
+    if (error == null) {
+      return;
+    }
+    console.newline();
+    console.printBold('Isolate exited due to an unhandled exception:');
+    console.print(error.message);
+    console.newline();
+    console.printBold("Type 'set break-on-exception Unhandled' to pause the"
+                      " isolate when an unhandled exception occurs.");
+    console.newline();
+    console.printBold("You can make this the default by running with "
+                      "--pause-isolates-on-unhandled-exceptions");
+  }
+
   void _reportPause(ServiceEvent event) {
     if (event.kind == ServiceEvent.kPauseStart) {
       console.print(
@@ -1524,6 +1520,7 @@
       console.print(
           "Paused at isolate exit "
           "(type 'continue' or [F7] to exit the isolate')");
+      _reportIsolateError(isolate);
     } else if (stack['frames'].length > 0) {
       Frame frame = stack['frames'][0];
       var script = frame.location.script;
@@ -1640,8 +1637,11 @@
       case ServiceEvent.kPauseInterrupted:
       case ServiceEvent.kPauseException:
         if (event.owner == isolate) {
-          _refreshStack(event).then((_) {
+          _refreshStack(event).then((_) async {
             flushStdio();
+            if (isolate != null) {
+              await isolate.reload();
+            }
             _reportPause(event);
           });
         }
@@ -1896,6 +1896,7 @@
     var stackElement = $['stackElement'];
     debugger.stackElement = stackElement;
     stackElement.debugger = debugger;
+    stackElement.scroller = $['stackDiv'];
     debugger.console = $['console'];
     debugger.input = $['commandline'];
     debugger.input.debugger = debugger;
@@ -1952,7 +1953,8 @@
     var splitterDiv = $['splitterDiv'];
     var cmdDiv = $['commandDiv'];
 
-    int navbarHeight = navbarDiv.clientHeight;
+    // For now, force navbar height to 40px in the debugger.
+    int navbarHeight = NavBarElement.height;
     int splitterHeight = splitterDiv.clientHeight;
     int cmdHeight = cmdDiv.clientHeight;
 
@@ -1960,6 +1962,7 @@
     int fixedHeight = navbarHeight + splitterHeight + cmdHeight;
     int available = windowHeight - fixedHeight;
     int stackHeight = available ~/ 1.6;
+    navbarDiv.style.setProperty('height', '${navbarHeight}px');
     stackDiv.style.setProperty('height', '${stackHeight}px');
   }
 
@@ -1987,6 +1990,7 @@
 @CustomTag('debugger-stack')
 class DebuggerStackElement extends ObservatoryElement {
   @published Isolate isolate;
+  @published Element scroller;
   @observable bool hasStack = false;
   @observable bool hasMessages = false;
   @observable bool isSampled = false;
@@ -1996,6 +2000,7 @@
   _addFrame(List frameList, Frame frameInfo) {
     DebuggerFrameElement frameElement = new Element.tag('debugger-frame');
     frameElement.frame = frameInfo;
+    frameElement.scroller = scroller;
 
     if (frameInfo.index == currentFrame) {
       frameElement.setCurrent(true);
@@ -2122,15 +2127,6 @@
     }
   }
 
-  Set<Script> activeScripts() {
-    var s = new Set<Script>();
-    List frameElements = $['frameList'].children;
-    for (var frameElement in frameElements) {
-      s.add(frameElement.children[0].script);
-    }
-    return s;
-  }
-
   Future doPauseIsolate() {
     if (debugger != null) {
       return debugger.isolate.pause();
@@ -2153,6 +2149,7 @@
 @CustomTag('debugger-frame')
 class DebuggerFrameElement extends ObservatoryElement {
   @published Frame frame;
+  @published Element scroller;
 
   // Is this the current frame?
   bool _current = false;
@@ -2167,17 +2164,14 @@
       var frameOuter = $['frameOuter'];
       if (_current) {
         frameOuter.classes.add('current');
-        expanded = true;
-        frameOuter.classes.add('shadow');
+        _expand();
         scrollIntoView();
       } else {
         frameOuter.classes.remove('current');
         if (_pinned) {
-          expanded = true;
-          frameOuter.classes.add('shadow');
+          _expand();
         } else {
-          expanded = false;
-          frameOuter.classes.remove('shadow');
+          _unexpand();
         }
       }
       busy = false;
@@ -2190,7 +2184,6 @@
 
   DebuggerFrameElement.created() : super.created();
 
-
   String makeExpandKey(String key) {
     return '${frame.function.qualifiedName}/${key}';
   }
@@ -2206,11 +2199,87 @@
 
   Script get script => frame.location.script;
 
+  int _varsTop(varsDiv) {
+    const minTop = 5;
+    if (varsDiv == null) {
+      return minTop;
+    }
+    const navbarHeight = NavBarElement.height;
+    const bottomPad = 6;
+    var parent = varsDiv.parent.getBoundingClientRect();
+    var varsHeight = varsDiv.clientHeight;
+    var maxTop = parent.height - (varsHeight + bottomPad);
+    var adjustedTop = navbarHeight - parent.top;
+    return (max(minTop, min(maxTop, adjustedTop)));
+  }
+
+  void _onScroll(event) {
+    if (!expanded) {
+      return;
+    }
+    var varsDiv = shadowRoot.querySelector('#vars');
+    if (varsDiv == null) {
+      return;
+    }
+    var currentTop = varsDiv.style.top;
+    var newTop = _varsTop(varsDiv);
+    if (currentTop != newTop) {
+      varsDiv.style.top = '${newTop}px';
+    }
+  }
+
+  void _expand() {
+    var frameOuter = $['frameOuter'];
+    expanded = true;
+    frameOuter.classes.add('shadow');
+    _subscribeToScroll();
+  }
+
+  void _unexpand() {
+    var frameOuter = $['frameOuter'];
+    expanded = false;
+    _unsubscribeToScroll();
+    frameOuter.classes.remove('shadow');
+  }
+
+  StreamSubscription _scrollSubscription;
+  StreamSubscription _resizeSubscription;
+
+  void _subscribeToScroll() {
+    if (scroller != null) {
+      if (_scrollSubscription == null) {
+        _scrollSubscription = scroller.onScroll.listen(_onScroll);
+      }
+      if (_resizeSubscription == null) {
+        _resizeSubscription = window.onResize.listen(_onScroll);
+      }
+    }
+  }
+
+  void _unsubscribeToScroll() {
+    if (_scrollSubscription != null) {
+      _scrollSubscription.cancel();
+      _scrollSubscription = null;
+    }
+    if (_resizeSubscription != null) {
+      _resizeSubscription.cancel();
+      _resizeSubscription = null;
+    }
+  }
+
   @override
   void attached() {
     super.attached();
     int windowHeight = window.innerHeight;
     scriptHeight = '${windowHeight ~/ 1.6}px';
+    if (expanded) {
+      _subscribeToScroll();
+    }
+  }
+
+  void detached() {
+    _unsubscribeToScroll();
+    super.detached();
   }
 
   void toggleExpand(var a, var b, var c) {
@@ -2220,13 +2289,10 @@
     busy = true;
     frame.function.load().then((func) {
         _pinned = !_pinned;
-        var frameOuter = $['frameOuter'];
         if (_pinned) {
-          expanded = true;
-          frameOuter.classes.add('shadow');
+          _expand();
         } else {
-          expanded = false;
-          frameOuter.classes.remove('shadow');
+          _unexpand();
         }
         busy = false;
       });
diff --git a/runtime/observatory/lib/src/elements/debugger.html b/runtime/observatory/lib/src/elements/debugger.html
index 981f260..20e2e4d 100644
--- a/runtime/observatory/lib/src/elements/debugger.html
+++ b/runtime/observatory/lib/src/elements/debugger.html
@@ -238,6 +238,12 @@
         flex-basis: 250px;
         overflow-x: hidden;
       }
+      #vars {
+        position: relative;
+        top: 5px;
+        padding-left:2em;
+        padding-bottom: 5px;
+      }
     </style>
     <div id="frameOuter" class="frameOuter">
       <a on-click="{{ toggleExpand }}">
@@ -263,11 +269,12 @@
                             location="{{ frame.function.location }}"
                             currentPos="{{ frame.location.tokenPos }}"
                             inDebuggerContext="{{ true }}"
+                            scroller="{{ scroller }}"
                             variables="{{ frame.variables }}">
               </source-inset>
             </div>
             <div class="flex-item-vars">
-              <div style="padding-left:2em;" class="memberList">
+              <div id="vars" class="memberList">
                 <template repeat="{{ v in properLocals }}">
                   {{ v['name']}}&nbsp;:&nbsp;
                   <any-service-ref ref="{{ v['value'] }}"
diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart
index 5b0d8ec..58f206b 100644
--- a/runtime/observatory/lib/src/elements/function_view.dart
+++ b/runtime/observatory/lib/src/elements/function_view.dart
@@ -18,8 +18,4 @@
   Future refresh() {
     return function.reload();
   }
-
-  Future refreshCoverage() {
-    return function.refreshCoverage();
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index 57e2c8c..a087382 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -21,7 +21,6 @@
         <class-nav-menu cls="{{ function.dartOwner }}"></class-nav-menu>
       </template>
       <nav-menu link="{{ makeLink('/inspect', function) }}" anchor="{{ function.name }}" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refreshCoverage }}" label="Refresh Coverage"></nav-refresh>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
     </nav-bar>
 
diff --git a/runtime/observatory/lib/src/elements/isolate_view.dart b/runtime/observatory/lib/src/elements/isolate_view.dart
index fe4fd95..40738a1 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.dart
+++ b/runtime/observatory/lib/src/elements/isolate_view.dart
@@ -33,8 +33,4 @@
       await isolate.topFrame.function.load();
     }
   }
-
-  Future refreshCoverage() {
-    return isolate.refreshCoverage();
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_view.html b/runtime/observatory/lib/src/elements/isolate_view.html
index 915930fc..b090fdd 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.html
+++ b/runtime/observatory/lib/src/elements/isolate_view.html
@@ -28,7 +28,6 @@
       <top-nav-menu></top-nav-menu>
       <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
       <isolate-nav-menu isolate="{{ isolate }}" last="{{ true }}"></isolate-nav-menu>
-      <nav-refresh callback="{{ refreshCoverage }}" label="Refresh Coverage"></nav-refresh>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
     </nav-bar>
 
diff --git a/runtime/observatory/lib/src/elements/library_view.dart b/runtime/observatory/lib/src/elements/library_view.dart
index 6b43ae3..3c9a256 100644
--- a/runtime/observatory/lib/src/elements/library_view.dart
+++ b/runtime/observatory/lib/src/elements/library_view.dart
@@ -30,8 +30,4 @@
     library.variables.forEach((variable) => loads.add(variable.reload()));
     return Future.wait(loads);
   }
-
-  Future refreshCoverage() {
-    return library.refreshCoverage();
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/library_view.html b/runtime/observatory/lib/src/elements/library_view.html
index d43fe3e..51d2da8 100644
--- a/runtime/observatory/lib/src/elements/library_view.html
+++ b/runtime/observatory/lib/src/elements/library_view.html
@@ -20,7 +20,6 @@
       <vm-nav-menu vm="{{ library.isolate.vm }}"></vm-nav-menu>
       <isolate-nav-menu isolate="{{ library.isolate }}"></isolate-nav-menu>
       <library-nav-menu library="{{ library }}" last="{{ true }}"></library-nav-menu>
-      <nav-refresh callback="{{ refreshCoverage }}" label="Refresh Coverage"></nav-refresh>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
     </nav-bar>
 
diff --git a/runtime/observatory/lib/src/elements/nav_bar.dart b/runtime/observatory/lib/src/elements/nav_bar.dart
index db77700..3999db87 100644
--- a/runtime/observatory/lib/src/elements/nav_bar.dart
+++ b/runtime/observatory/lib/src/elements/nav_bar.dart
@@ -17,6 +17,9 @@
   @published bool notifyOnPause = true;
   @published bool pad = true;
 
+  // Desired nav var height in pixels.
+  static const height = 40;
+
   NavBarElement.created() : super.created();
 }
 
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 47bbff7..aa3c0a8 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -6,7 +6,9 @@
 
 import 'dart:async';
 import 'dart:html';
+import 'dart:math';
 import 'observatory_element.dart';
+import 'nav_bar.dart';
 import 'service_ref.dart';
 import 'package:observatory/service.dart';
 import 'package:observatory/utils.dart';
@@ -244,7 +246,7 @@
 
         for (var entry in callSite.entries) {
           var r = row();
-          r.append(cell(serviceRef(entry.receiverContainer)));
+          r.append(cell(serviceRef(entry.receiver)));
           r.append(cell(entry.count.toString()));
           r.append(cell(serviceRef(entry.target)));
           details.append(r);
@@ -374,16 +376,24 @@
   @published bool inDebuggerContext = false;
   @published ObservableList variables;
 
+  @published Element scroller;
+  RefreshButtonElement _refreshButton;
+
   int _currentLine;
   int _currentCol;
   int _startLine;
   int _endLine;
 
+  Map<int, List<ServiceMap>> _rangeMap = {};
+  Set _callSites = new Set<CallSite>();
+  Set _possibleBreakpointLines = new Set<int>();
+
   var annotations = [];
   var annotationsCursor;
 
   StreamSubscription _scriptChangeSubscription;
   Future<StreamSubscription> _debugSubscriptionFuture;
+  StreamSubscription _scrollSubscription;
 
   bool hasLoadedLibraryDeclarations = false;
 
@@ -402,11 +412,20 @@
     super.attached();
     _debugSubscriptionFuture =
         app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
+    if (scroller != null) {
+      _scrollSubscription = scroller.onScroll.listen(_onScroll);
+    } else {
+      _scrollSubscription = window.onScroll.listen(_onScroll);
+    }
   }
 
   void detached() {
     cancelFutureSubscription(_debugSubscriptionFuture);
     _debugSubscriptionFuture = null;
+    if (_scrollSubscription != null) {
+      _scrollSubscription.cancel();
+      _scrollSubscription = null;
+    }
     if (_scriptChangeSubscription != null) {
       // Don't leak. If only Dart and Javascript exposed weak references...
       _scriptChangeSubscription.cancel();
@@ -415,6 +434,17 @@
     super.detached();
   }
 
+  void _onScroll(event) {
+    if (_refreshButton == null) {
+      return;
+    }
+    var currentTop = _refreshButton.style.top;
+    var newTop = _refreshButtonTop();
+    if (currentTop != newTop) {
+      _refreshButton.style.top = '${newTop}px';
+    }
+  }
+
   void _onDebugEvent(event) {
     if (script == null) {
       return;
@@ -486,11 +516,55 @@
     element.title = "Line did execute";
     return element;
   }
+  Element hitsCompiled(Element element) {
+    element.classes.add('hitsCompiled');
+    element.title = "Line in compiled function";
+    return element;
+  }
+  Element hitsNotCompiled(Element element) {
+    element.classes.add('hitsNotCompiled');
+    element.title = "Line in uncompiled function";
+    return element;
+  }
 
   Element container;
 
+  Future _refresh() async {
+    await update();
+  }
+
+  // Build _rangeMap and _callSites from a source report.
+  Future _refreshSourceReport() async {
+    var sourceReport = await script.isolate.getSourceReport(
+        [Isolate.kCallSitesReport, Isolate.kPossibleBreakpointsReport],
+        script, startPos, endPos);
+    _possibleBreakpointLines = getPossibleBreakpointLines(sourceReport, script);
+    _rangeMap.clear();
+    _callSites.clear();
+    for (var range in sourceReport['ranges']) {
+      int startLine = script.tokenToLine(range['startPos']);
+      int endLine = script.tokenToLine(range['endPos']);
+      for (var line = startLine; line <= endLine; line++) {
+        var rangeList = _rangeMap[line];
+        if (rangeList == null) {
+          _rangeMap[line] = [range];
+        } else {
+          rangeList.add(range);
+        }
+      }
+      if (range['compiled']) {
+        var rangeCallSites = range['callSites'];
+        if (rangeCallSites != null) {
+          for (var callSiteMap in rangeCallSites) {
+            _callSites.add(new CallSite.fromMap(callSiteMap, script));
+          }
+        }
+      }
+    }
+  }
+
   Task _updateTask;
-  void update() {
+  Future update() async {
     assert(_updateTask != null);
     if (script == null) {
       // We may have previously had a script.
@@ -500,13 +574,12 @@
       return;
     }
     if (!script.loaded) {
-      script.load().then((_) => update());
-      return;
+      await script.load();
     }
-
     if (_scriptChangeSubscription == null) {
       _scriptChangeSubscription = script.changes.listen((_) => update());
     }
+    await _refreshSourceReport();
 
     computeAnnotations();
 
@@ -803,7 +876,7 @@
   }
 
   void addCallSiteAnnotations() {
-    for (var callSite in script.callSites) {
+    for (var callSite in _callSites) {
       annotations.add(new CallSiteAnnotation(callSite));
     }
   }
@@ -828,10 +901,35 @@
     }
   }
 
+  int _refreshButtonTop() {
+    if (_refreshButton == null) {
+      return 5;
+    }
+    const padding = 5;
+    const navbarHeight = NavBarElement.height;
+    var rect = getBoundingClientRect();
+    var buttonHeight = _refreshButton.clientHeight;
+    return min(max(0, navbarHeight - rect.top) + padding,
+               rect.height - (buttonHeight + padding));
+  }
+
+  RefreshButtonElement _newRefreshButton() {
+    var button = new Element.tag('refresh-button');
+    button.style.position = 'absolute';
+    button.style.display = 'inline-block';
+    button.style.top = '${_refreshButtonTop()}px';
+    button.style.right = '5px';
+    button.callback = _refresh;
+    return button;
+  }
+
   Element linesTable() {
     var table = new DivElement();
     table.classes.add("sourceTable");
 
+    _refreshButton = _newRefreshButton();
+    table.append(_refreshButton);
+
     if (_startLine == null || _endLine == null) {
       return table;
     }
@@ -904,35 +1002,38 @@
 
   Element lineBreakpointElement(ScriptLine line) {
     var e = new DivElement();
-    var busy = false;
-    if (line == null || !line.possibleBpt) {
-      e.classes.add("emptyBreakpoint");
+    if (line == null || !_possibleBreakpointLines.contains(line.line)) {
       e.classes.add('noCopy');
+      e.classes.add("emptyBreakpoint");
       e.text = nbsp;
       return e;
     }
+
     e.text = 'B';
-    update() {
+    var busy = false;
+    void update() {
       e.classes.clear();
       e.classes.add('noCopy');
-
-      if (!line.possibleBpt) {
-        e.classes.add("emptyBreakpoint");
-        e.text = nbsp;
-      } else if (busy) {
+      if (busy) {
         e.classes.add("busyBreakpoint");
-      } else {
-        if (line.breakpoints != null) {
-          if (line.breakpointResolved) {
-            e.classes.add("resolvedBreakpoint");
-          } else {
-            e.classes.add("unresolvedBreakpoint");
+      } else if (line.breakpoints != null) {
+        bool resolved = false;
+        for (var bpt in line.breakpoints) {
+          if (bpt.resolved) {
+            resolved = true;
+            break;
           }
-        } else {
-          e.classes.add("possibleBreakpoint");
         }
+        if (resolved) {
+          e.classes.add("resolvedBreakpoint");
+        } else {
+          e.classes.add("unresolvedBreakpoint");
+        }
+      } else {
+        e.classes.add("possibleBreakpoint");
       }
     }
+
     line.changes.listen((_) => update());
     e.onClick.listen((event) {
       if (busy) {
@@ -973,17 +1074,51 @@
     var lineNumber = line == null ? "..." : line.line;
     var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
     e.classes.add('noCopy');
-
     if (lineNumber == _currentLine) {
       hitsCurrent(e);
-    } else if ((line == null) || (line.hits == null)) {
-      hitsUnknown(e);
-    } else if (line.hits == 0) {
-      hitsNotExecuted(e);
-    } else {
-      hitsExecuted(e);
+      return e;
     }
-
+    var ranges = _rangeMap[lineNumber];
+    if ((ranges == null) || ranges.isEmpty) {
+      // This line is not code.
+      hitsUnknown(e);
+      return e;
+    }
+    bool compiled = true;
+    bool hasCallInfo = false;
+    bool executed = false;
+    for (var range in ranges) {
+      if (range['compiled']) {
+        for (var callSite in range['callSites']) {
+          var callLine = line.script.tokenToLine(callSite['tokenPos']);
+          if (lineNumber == callLine) {
+            // The call site is on the current line.
+            hasCallInfo = true;
+            for (var cacheEntry in callSite['cacheEntries']) {
+              if (cacheEntry['count'] > 0) {
+                // If any call site on the line has been executed, we
+                // mark the line as executed.
+                executed = true;
+                break;
+              }
+            }
+          }
+        }
+      } else {
+        // If any range isn't compiled, show the line as not compiled.
+        // This is necessary so that nested functions appear to be uncompiled.
+        compiled = false;
+      }
+    }
+    if (executed) {
+      hitsExecuted(e);
+    } else if (hasCallInfo) {
+      hitsNotExecuted(e);
+    } else if (compiled) {
+      hitsCompiled(e);
+    } else {
+      hitsNotCompiled(e);
+    }
     return e;
   }
 
@@ -1036,6 +1171,26 @@
   }
 }
 
+@CustomTag('refresh-button')
+class RefreshButtonElement extends PolymerElement {
+  RefreshButtonElement.created() : super.created();
+
+  @published var callback = null;
+  bool busy = false;
+
+  Future buttonClick(var event, var b, var c) async {
+    if (busy) {
+      return;
+    }
+    busy = true;
+    if (callback != null) {
+      await callback();
+    }
+    busy = false;
+  }
+}
+
+
 @CustomTag('source-inset')
 class SourceInsetElement extends PolymerElement {
   SourceInsetElement.created() : super.created();
@@ -1045,4 +1200,5 @@
   @published int currentPos;
   @published bool inDebuggerContext = false;
   @published ObservableList variables;
+  @published Element scroller;
 }
diff --git a/runtime/observatory/lib/src/elements/script_inset.html b/runtime/observatory/lib/src/elements/script_inset.html
index a76ae42..92d2940 100644
--- a/runtime/observatory/lib/src/elements/script_inset.html
+++ b/runtime/observatory/lib/src/elements/script_inset.html
@@ -1,6 +1,19 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="observatory_element.html">
 
+<polymer-element name="icon-refresh" noscript>
+  <template>
+    <style>
+      svg {
+        fill: currentColor
+      }
+    </style>
+    <svg width="24" height="24">
+      <path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>
+    </svg>
+  </template>
+</polymer-element>
+
 <polymer-element name="script-inset" extends="observatory-element">
   <template>
     <style>
@@ -14,6 +27,7 @@
       .sourceInset {
       }
       .sourceTable {
+        position: relative;
         background-color: #f5f5f5;
         border: 1px solid #ccc;
         padding: 10px;
@@ -39,7 +53,7 @@
       .currentCol {
         background-color: #6cf;
       }
-      .hitsCurrent, .hitsNone, .hitsNotExecuted, .hitsExecuted {
+      .hitsCurrent, .hitsNone, .hitsNotExecuted, .hitsExecuted, .hitsCompiled, .hitsNotCompiled {
         display: table-cell;
         vertical-align: top;
         font: 400 14px consolas, courier, monospace;
@@ -58,6 +72,13 @@
       .hitsExecuted {
         background-color: #aea;
       }
+      .hitsCompiled {
+        background-color: #e0e0e0;
+      }
+      .hitsNotCompiled {
+        background-color: #f0c5c5;
+      }
+
       .noCopy {}
       .emptyBreakpoint, .possibleBreakpoint, .busyBreakpoint, .unresolvedBreakpoint, .resolvedBreakpoint  {
         display: table-cell;
@@ -99,12 +120,40 @@
   </template>
 </polymer-element>
 
+<polymer-element name="refresh-button">
+  <template>
+    <style>
+      .refreshButton {
+        color: rgba(0,0,0,.3);
+      }
+      .refreshButton:hover {
+        color: black;
+      }
+      .refreshButtonDisabled {
+        color: white;
+        cursor: wait;
+      }
+    </style>
+    <template if="{{ callback != null }}">
+      <template if="{{ busy }}">
+        <icon-refresh id="refreshIcon" class="refreshButtonDisabled">
+        </icon-refresh>
+      </template>
+      <template if="{{ !busy }}">
+        <a on-click="{{ buttonClick }}">
+          <icon-refresh id="refreshIcon" class="refreshButton"></icon-refresh>
+        </a>
+      </template>
+    </template>
+  </template>
+</polymer-element>
 
 <polymer-element name="source-inset">
 <template>
   <template if="{{ location != null }}">
     <script-inset script="{{ location.script }}"
                   startPos="{{ location.tokenPos }}"
+                  scroller="{{ scroller }}"
                   endPos="{{ location.endTokenPos }}"
                   height="{{ height }}"
                   currentPos="{{ currentPos }}"
diff --git a/runtime/observatory/lib/src/elements/script_view.dart b/runtime/observatory/lib/src/elements/script_view.dart
index ff07a80..c896b8d 100644
--- a/runtime/observatory/lib/src/elements/script_view.dart
+++ b/runtime/observatory/lib/src/elements/script_view.dart
@@ -20,8 +20,4 @@
   Future refresh() {
     return script.reload();
   }
-
-  Future refreshCoverage() {
-    return script.refreshCoverage();
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/script_view.html b/runtime/observatory/lib/src/elements/script_view.html
index 1dc23b4..c65fa49 100644
--- a/runtime/observatory/lib/src/elements/script_view.html
+++ b/runtime/observatory/lib/src/elements/script_view.html
@@ -13,7 +13,6 @@
     <isolate-nav-menu isolate="{{ script.isolate }}"></isolate-nav-menu>
     <library-nav-menu library="{{ script.library }}"></library-nav-menu>
     <nav-menu link="{{ makeLink('/inspect', script) }}" anchor="{{ script.name }}" last="{{ true }}"></nav-menu>
-    <nav-refresh callback="{{ refreshCoverage }}" label="Refresh Coverage"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
   </nav-bar>
 
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index e45cb8d..abc1ea4 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -395,40 +395,6 @@
   }
 }
 
-abstract class Coverage {
-  // Following getters and functions will be provided by [ServiceObject].
-  String get id;
-  Isolate get isolate;
-
-  Future refreshCoverage() {
-    return refreshCallSiteData();
-  }
-
-  /// Default handler for coverage data.
-  void processCallSiteData(List coverageData) {
-    coverageData.forEach((scriptCoverage) {
-      assert(scriptCoverage['script'] != null);
-      scriptCoverage['script']._processCallSites(scriptCoverage['callSites']);
-    });
-  }
-
-  Future refreshCallSiteData() {
-    Map params = {};
-    if (this is! Isolate) {
-      params['targetId'] = id;
-    }
-    return isolate.invokeRpcNoUpgrade('_getCallSiteData', params).then(
-        (ObservableMap map) {
-          var coverage = new ServiceObject._fromMap(isolate, map);
-          assert(coverage.type == 'CodeCoverage');
-          var coverageList = coverage['coverage'];
-          assert(coverageList != null);
-          processCallSiteData(coverageList);
-          return this;
-        });
-  }
-}
-
 abstract class ServiceObjectOwner extends ServiceObject {
   /// Creates an empty [ServiceObjectOwner].
   ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -1135,7 +1101,7 @@
 }
 
 /// State for a running isolate.
-class Isolate extends ServiceObjectOwner with Coverage {
+class Isolate extends ServiceObjectOwner {
   static const kLoggingStream = '_Logging';
   static const kExtensionStream = 'Extension';
 
@@ -1194,6 +1160,26 @@
     });
   }
 
+  static const kCallSitesReport = '_CallSites';
+  static const kPossibleBreakpointsReport = 'PossibleBreakpoints';
+
+  Future<ServiceMap> getSourceReport(List<String> report_kinds,
+                                     [Script script,
+                                      int startPos,
+                                      int endPos]) {
+    var params = { 'reports' : report_kinds };
+    if (script != null) {
+      params['scriptId'] = script.id;
+    }
+    if (startPos != null) {
+      params['tokenPos'] = startPos;
+    }
+    if (endPos != null) {
+      params['endTokenPos'] = endPos;
+    }
+    return invokeRpc('_getSourceReport', params);
+  }
+
   /// Fetches and builds the class hierarchy for this isolate. Returns the
   /// Object class object.
   Future<Class> getClassHierarchy() {
@@ -1536,34 +1522,15 @@
     }
   }
 
-  Future<ServiceObject> addBreakpoint(
-      Script script, int line, [int col]) async {
-    // TODO(turnidge): Pass line as an int instead of a string.
-    try {
-      Map params = {
-        'scriptId': script.id,
-        'line': line.toString(),
-      };
-      if (col != null) {
-        params['column'] = col.toString();
-      }
-      Breakpoint bpt = await invokeRpc('addBreakpoint', params);
-      if (bpt.resolved && script.loaded) {
-        SourceLocation loc = bpt.location;
-        if (script.tokenToLine(loc.tokenPos) != line) {
-          script.getLine(line).possibleBpt = false;
-        }
-      }
-      return bpt;
-    } on ServerRpcException catch(e) {
-      if (e.code == ServerRpcException.kCannotAddBreakpoint) {
-        // Unable to set a breakpoint at the desired line.
-        if (script.loaded) {
-          script.getLine(line).possibleBpt = false;
-        }
-      }
-      rethrow;
+  Future<ServiceObject> addBreakpoint(Script script, int line, [int col]) {
+    Map params = {
+      'scriptId': script.id,
+      'line': line,
+    };
+    if (col != null) {
+      params['column'] = col;
     }
+    return invokeRpc('addBreakpoint', params);
   }
 
   Future<ServiceObject> addBreakpointByScriptUri(
@@ -2115,7 +2082,7 @@
 }
 
 
-class Library extends HeapObject with Coverage {
+class Library extends HeapObject {
   @observable String uri;
   @reflectable final dependencies = new ObservableList<LibraryDependency>();
   @reflectable final scripts = new ObservableList<Script>();
@@ -2213,7 +2180,7 @@
   bool get empty => accumulated.empty && current.empty;
 }
 
-class Class extends HeapObject with Coverage {
+class Class extends HeapObject {
   @observable Library library;
 
   @observable bool isAbstract;
@@ -2592,7 +2559,7 @@
   static FunctionKind kUNKNOWN = new FunctionKind._internal('UNKNOWN');
 }
 
-class ServiceFunction extends HeapObject with Coverage {
+class ServiceFunction extends HeapObject {
   // owner is a Library, Class, or ServiceFunction.
   @observable ServiceObject dartOwner;
   @observable Library library;
@@ -2738,21 +2705,21 @@
   final Script script;
   final int line;
   final String text;
-  @observable int hits;
-  @observable bool possibleBpt = true;
-  @observable bool breakpointResolved = false;
   @observable Set<Breakpoint> breakpoints;
 
-  bool get isBlank {
-    // Compute isBlank on demand.
-    if (_isBlank == null) {
-      _isBlank = text.trim().isEmpty;
-    }
-    return _isBlank;
-  }
-  bool _isBlank;
+  ScriptLine(this.script, this.line, this.text);
 
-  bool get isTrivialLine => !possibleBpt;
+  bool get isBlank {
+    return text.isEmpty || text.trim().isEmpty;
+  }
+
+  bool _isTrivial = null;
+  bool get isTrivial {
+    if (_isTrivial == null) {
+      _isTrivial = _isTrivialLine(text);
+    }
+    return _isTrivial;
+  }
 
   static bool _isTrivialToken(String token) {
     if (token == 'else') {
@@ -2789,16 +2756,11 @@
     return true;
   }
 
-  ScriptLine(this.script, this.line, this.text) {
-    possibleBpt = !_isTrivialLine(text);
-  }
-
   void addBreakpoint(Breakpoint bpt) {
     if (breakpoints == null) {
       breakpoints = new Set<Breakpoint>();
     }
     breakpoints.add(bpt);
-    breakpointResolved = breakpointResolved || bpt.resolved;
   }
 
   void removeBreakpoint(Breakpoint bpt) {
@@ -2806,7 +2768,6 @@
     breakpoints.remove(bpt);
     if (breakpoints.isEmpty) {
       breakpoints = null;
-      breakpointResolved = false;
     }
   }
 }
@@ -2850,19 +2811,19 @@
 }
 
 class CallSiteEntry {
-  final /* Class | Library */ receiverContainer;
+  final /* Class | Library */ receiver;
   final int count;
   final ServiceFunction target;
 
-  CallSiteEntry(this.receiverContainer, this.count, this.target);
+  CallSiteEntry(this.receiver, this.count, this.target);
 
   factory CallSiteEntry.fromMap(Map entryMap) {
-    return new CallSiteEntry(entryMap['receiverContainer'],
+    return new CallSiteEntry(entryMap['receiver'],
                              entryMap['count'],
                              entryMap['target']);
   }
 
-  String toString() => "CallSiteEntry(${receiverContainer.name}, $count)";
+  String toString() => "CallSiteEntry(${receiver.name}, $count)";
 }
 
 /// The location of a local variable reference in a script.
@@ -2873,10 +2834,8 @@
   LocalVarLocation(this.line, this.column, this.endColumn);
 }
 
-class Script extends HeapObject with Coverage {
-  Set<CallSite> callSites = new Set<CallSite>();
+class Script extends HeapObject {
   final lines = new ObservableList<ScriptLine>();
-  final _hits = new Map<int, int>();
   @observable String uri;
   @observable String kind;
   @observable int firstTokenPos;
@@ -3021,36 +2980,6 @@
         _tokenToCol[tokenOffset] = colNumber;
       }
     }
-
-    for (var line in lines) {
-      // Remove possible breakpoints on lines with no tokens.
-      if (!lineSet.contains(line.line)) {
-        line.possibleBpt = false;
-      }
-    }
-  }
-
-  void _processCallSites(List newCallSiteMaps) {
-    var mergedCallSites = new Set<CallSite>();
-    for (var callSiteMap in newCallSiteMaps) {
-      var newSite = new CallSite.fromMap(callSiteMap, this);
-      mergedCallSites.add(newSite);
-
-      var line = newSite.line;
-      var hit = newSite.aggregateCount;
-      assert(line >= 1); // Lines start at 1.
-      var oldHits = _hits[line];
-      if (oldHits != null) {
-        hit += oldHits;
-      }
-      _hits[line] = hit;
-    }
-
-    mergedCallSites.addAll(callSites);
-    callSites = mergedCallSites;
-    _applyHitsToLines();
-    // Notify any Observers that this Script's state has changed.
-    notifyChange(null);
   }
 
   void _processSource(String source) {
@@ -3072,18 +3001,10 @@
       }
     }
 
-    _applyHitsToLines();
     // Notify any Observers that this Script's state has changed.
     notifyChange(null);
   }
 
-  void _applyHitsToLines() {
-    for (var line in lines) {
-      var hits = _hits[line.line];
-      line.hits = hits;
-    }
-  }
-
   void _addBreakpoint(Breakpoint bpt) {
     var line;
     if (bpt.location.tokenPos != null) {
@@ -3174,7 +3095,7 @@
 
     if (line == lastLine) {
       // Only one line.
-      if (!getLine(line).isTrivialLine) {
+      if (!getLine(line).isTrivial) {
         // TODO(johnmccutchan): end token pos -> column can lie for snapshotted
         // code. e.g.:
         // io_sink.dart source line 23 ends at column 39
@@ -3190,7 +3111,7 @@
     }
 
     // Scan first line.
-    if (!getLine(line).isTrivialLine) {
+    if (!getLine(line).isTrivial) {
       lineContents = getLine(line).text.substring(column);
       r.addAll(scanLineForLocalVariableLocations(pattern,
                                                   name,
@@ -3201,7 +3122,7 @@
 
     // Scan middle lines.
     while (line < (lastLine - 1)) {
-      if (getLine(line).isTrivialLine) {
+      if (getLine(line).isTrivial) {
         line++;
         continue;
       }
@@ -3215,7 +3136,7 @@
     }
 
     // Scan last line.
-    if (!getLine(line).isTrivialLine) {
+    if (!getLine(line).isTrivial) {
       // TODO(johnmccutchan): end token pos -> column can lie for snapshotted
       // code. e.g.:
       // io_sink.dart source line 23 ends at column 39
@@ -4025,6 +3946,48 @@
 }
 
 
+// Helper function to extract possible breakpoint locations from a
+// SourceReport for some script.
+Set<int> getPossibleBreakpointLines(ServiceMap report, Script script) {
+  var result = new Set<int>();
+  int scriptIndex;
+  int numScripts = report['scripts'].length;
+  for (scriptIndex = 0; scriptIndex < numScripts; scriptIndex++) {
+    if (report['scripts'][scriptIndex].id == script.id) {
+      break;
+    }
+  }
+  if (scriptIndex == numScripts) {
+    return result;
+  }
+  var ranges = report['ranges'];
+  if (ranges != null) {
+    for (var range in ranges) {
+      if (range['scriptIndex'] != scriptIndex) {
+        continue;
+      }
+      if (range['compiled']) {
+        var possibleBpts = range['possibleBreakpoints'];
+        if (possibleBpts != null) {
+          for (var tokenPos in possibleBpts) {
+            result.add(script.tokenToLine(tokenPos));
+          }
+        }
+      } else {
+        int startLine = script.tokenToLine(range['startPos']);
+        int endLine = script.tokenToLine(range['endPos']);
+        for (int line = startLine; line <= endLine; line++) {
+          if (!script.getLine(line).isTrivial) {
+            result.add(line);
+          }
+        }
+      }
+    }
+  }
+  return result;
+}
+
+
 // Returns true if [map] is a service map. i.e. it has the following keys:
 // 'id' and a 'type'.
 bool _isServiceMap(ObservableMap m) {
diff --git a/runtime/observatory/tests/service/caching_test.dart b/runtime/observatory/tests/service/caching_test.dart
index 8a72447..6194ba6 100644
--- a/runtime/observatory/tests/service/caching_test.dart
+++ b/runtime/observatory/tests/service/caching_test.dart
@@ -13,27 +13,14 @@
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
 
-script() {
-  print("This executed");
-}
-
-hasSomeCoverageData(Script script) {
-  for (var line in script.lines) {
-    if (line.hits != null) return true;
-  }
-  return false;
-}
-
 var tests = [
 (Isolate isolate) async {
   Library lib = await isolate.rootLibrary.load();
   Script script = await lib.scripts.single.load();
-  expect(hasSomeCoverageData(script), isFalse);
-  Script script2 = await script.refreshCoverage();
+  Script script2 = await isolate.getObject(script.id);
   expect(identical(script, script2), isTrue);
-  expect(hasSomeCoverageData(script), isTrue);
 },
 
 ];
 
-main(args) => runIsolateTests(args, tests, testeeBefore: script);
+main(args) => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index 0255687..d1c71eb 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -69,7 +69,7 @@
   expect(coverage['coverage'].length, equals(1));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0]));
+                 24, 1, 25, 1, 27, 0, 13, 0]));
 
   // Library
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
@@ -78,7 +78,7 @@
   expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0]));
+                 24, 1, 25, 1, 27, 0, 13, 0]));
   expect(coverage['coverage'][1]['hits'],
          equals([33, 1, 34, 1, 105, 2]));
 
@@ -90,7 +90,7 @@
   expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
          equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0]));
+                 24, 1, 25, 1, 27, 0, 13, 0]));
   expect(coverage['coverage'][1]['hits'],
          equals([33, 1, 34, 1, 105, 2]));
 
@@ -102,4 +102,6 @@
 
 ];
 
-main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
+main(args) => runIsolateTests(args, tests,
+                              testeeConcurrent: testFunction,
+                              trace_service: true);
diff --git a/runtime/observatory/tests/service/debugger_location_test.dart b/runtime/observatory/tests/service/debugger_location_test.dart
index 7825ae6..ab50f4d 100644
--- a/runtime/observatory/tests/service/debugger_location_test.dart
+++ b/runtime/observatory/tests/service/debugger_location_test.dart
@@ -236,9 +236,7 @@
       await DebuggerLocation.complete(debugger,
                                       'debugger_location_test.dart:11');
   expect(completions.toString(), equals(
-      '[debugger_location_test.dart:11 ,'
-      ' debugger_location_test.dart:11:,'
-      ' debugger_location_test.dart:110 ,'
+      '[debugger_location_test.dart:110 ,'
       ' debugger_location_test.dart:110:,'
       ' debugger_location_test.dart:111 ,'
       ' debugger_location_test.dart:111:,'
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index 698fce5..a21ed9c 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -67,7 +67,7 @@
     var tree = cpuProfile.loadCodeTree('exclusive');
     var node = tree.root;
     var expected =
-        ['Root', 'test', 'test', '_FunctionImpl.call', 'runIsolateTests'];
+        ['Root', 'test', 'test', '_Closure.call', 'runIsolateTests'];
     for (var i = 0; i < expected.length; i++) {
       expect(node.profileCode.code.name, equals(expected[i]));
       // Depth first traversal.
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index 71345ee..d306bca 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -110,7 +110,7 @@
   expect(coverage['scripts'].length, greaterThan(1));
 
   // Multiple reports (make sure enum list parameter parsing works).
-  params = { 'reports' : ['CallSites', 'Coverage'],
+  params = { 'reports' : ['_CallSites', 'Coverage', 'PossibleBreakpoints'],
              'scriptId' : func.location.script.id,
              'tokenPos' : func.location.tokenPos,
              'endTokenPos' : func.location.endTokenPos };
@@ -120,6 +120,7 @@
   var range = coverage['ranges'][0];
   expect(range.containsKey('callSites'), isTrue);
   expect(range.containsKey('coverage'), isTrue);
+  expect(range.containsKey('possibleBreakpoints'), isTrue);
 
   // missing scriptId with tokenPos.
   bool caughtException = false;
diff --git a/runtime/observatory/tests/service/graph_test.dart b/runtime/observatory/tests/service/graph_test.dart
index 3cf8c46..fe31d16 100644
--- a/runtime/observatory/tests/service/graph_test.dart
+++ b/runtime/observatory/tests/service/graph_test.dart
@@ -71,9 +71,15 @@
                                       bVertex.shallowSize +
                                       rVertex.shallowSize));
 
-  const int fixedSizeListCid = 62;
+  Library corelib =
+      isolate.libraries.singleWhere((lib) => lib.uri == 'dart:core');
+  await corelib.load();
+  Class _List =
+      corelib.classes.singleWhere((cls) => cls.vmName.startsWith('_List'));
+  int kArrayCid = _List.vmCid;
+  // startsWith to ignore the private mangling
   List<ObjectVertex> lists = new List.from(graph.vertices.where(
-      (ObjectVertex obj) => obj.vmCid == fixedSizeListCid));
+      (ObjectVertex obj) => obj.vmCid == kArrayCid));
   expect(lists.length >= 2, isTrue);
   // Order by decreasing retained size.
   lists.sort((u, v) => v.retainedSize - u.retainedSize);
diff --git a/runtime/observatory/tests/service/issue_25465_test.dart b/runtime/observatory/tests/service/issue_25465_test.dart
new file mode 100644
index 0000000..3a739f0
--- /dev/null
+++ b/runtime/observatory/tests/service/issue_25465_test.dart
@@ -0,0 +1,71 @@
+// 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';
+import 'dart:async';
+
+testMain() {
+  var foo;      // line 11
+  foo = 42;     // line 12
+  print(foo);
+}
+
+var tests = [
+  hasPausedAtStart,
+
+  // Add breakpoints at line 11 and line 12.
+  (Isolate isolate) async {
+    var rootLib = isolate.rootLibrary;
+    await rootLib.load();
+    var script = rootLib.scripts[0];
+
+    var bpt1 = await isolate.addBreakpoint(script, 11);
+    var bpt2 = await isolate.addBreakpoint(script, 12);
+    expect(await bpt1.location.getLine(), equals(11));
+    expect(await bpt2.location.getLine(), equals(12));
+
+    var stream = await isolate.vm.getEventStream(VM.kDebugStream);
+    Completer completer = new Completer();
+    var subscription;
+    var breakCount = 0;
+    subscription = stream.listen((ServiceEvent event) async {
+      if (event.kind == ServiceEvent.kPauseBreakpoint) {
+        breakCount++;
+        print('break count is $breakCount');
+        if (breakCount == 1) {
+          // We are stopped at breakpoint 1.
+          expect(event.breakpoint.number, equals(bpt1.number));
+
+          // Remove both breakpoints
+          var result = await isolate.removeBreakpoint(bpt1);
+          expect(result.type, equals("Success"));
+
+          result = await isolate.removeBreakpoint(bpt2);
+          expect(result.type, equals("Success"));
+
+          isolate.stepOver();
+        } else {
+          // No breakpoint.
+          expect(event.breakpoint, isNull);
+
+          // We expect the next step to take us to line 12.
+          var stack = await isolate.getStack();
+          expect(await stack['frames'][0].location.getLine(), equals(12));
+
+          subscription.cancel();
+          completer.complete(null);
+        }
+      }
+    });
+    isolate.resume();
+    await completer.future;
+  },
+];
+
+main(args) => runIsolateTests(args, tests,
+                              testeeConcurrent: testMain,
+                              pause_on_start: true);
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
new file mode 100644
index 0000000..4a6b2dd
--- /dev/null
+++ b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
@@ -0,0 +1,27 @@
+// 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';
+import 'dart:async';
+
+doThrow() {
+  throw "TheException"; // Line 13.
+  return "end of doThrow";
+}
+
+var tests = [
+  hasStoppedWithUnhandledException,
+  (Isolate isolate) async {
+    var stack = await isolate.getStack();
+    expect(stack['frames'][0].function.name, equals('doThrow'));
+  }
+];
+
+main(args) => runIsolateTests(args,
+                              tests,
+                              pause_on_unhandled_exceptions: true,
+                              testeeConcurrent: doThrow);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 7562cf4..8a572de 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -22,4 +22,7 @@
 process_service_test: Pass, Fail # Issue 24344
 
 [ ($noopt || $compiler == precompiler) ]
-*: Skip # Issue 24651
\ No newline at end of file
+*: Skip # Issue 24651
+
+[ $runtime == vm ]
+coverage_test: Pass Slow
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 58de4e6..6e64180 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -26,7 +26,10 @@
                             Platform.script.toFilePath(),
                             _TESTEE_MODE_FLAG] {}
 
-  Future<int> launch(bool pause_on_start, bool pause_on_exit, bool trace_service) {
+  Future<int> launch(bool pause_on_start,
+                     bool pause_on_exit,
+                     bool pause_on_unhandled_exceptions,
+                     bool trace_service) {
     assert(pause_on_start != null);
     assert(pause_on_exit != null);
     assert(trace_service != null);
@@ -41,6 +44,9 @@
     if (pause_on_exit) {
       fullArgs.add('--pause-isolates-on-exit');
     }
+    if (pause_on_unhandled_exceptions) {
+      fullArgs.add('--pause-isolates-on-unhandled-exceptions');
+    }
     fullArgs.addAll(Platform.executableArguments);
     fullArgs.addAll(args);
     print('** Launching $dartExecutable ${fullArgs.join(' ')}');
@@ -110,7 +116,8 @@
                       bool pause_on_start: false,
                       bool pause_on_exit: false,
                       bool trace_service: false,
-                      bool verbose_vm: false}) {
+                      bool verbose_vm: false,
+                      bool pause_on_unhandled_exceptions: false}) {
   assert(!pause_on_start || testeeBefore == null);
   if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
     if (!pause_on_start) {
@@ -128,7 +135,8 @@
     }
   } else {
     var process = new _TestLauncher();
-    process.launch(pause_on_start, pause_on_exit, trace_service).then((port) {
+    process.launch(pause_on_start, pause_on_exit,
+                   pause_on_unhandled_exceptions, trace_service).then((port) {
       if (mainArgs.contains("--gdb")) {
         port = 8181;
       }
@@ -157,15 +165,14 @@
   }
 }
 
-
-Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
+Future<Isolate> hasPausedFor(Isolate isolate, String kind) {
   // Set up a listener to wait for breakpoint events.
   Completer completer = new Completer();
   isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
     var subscription;
     subscription = stream.listen((ServiceEvent event) {
-        if (event.kind == ServiceEvent.kPauseBreakpoint) {
-          print('Breakpoint reached');
+        if (event.kind == kind) {
+          print('Paused with $kind');
           subscription.cancel();
           if (completer != null) {
             // Reload to update isolate.pauseEvent.
@@ -178,9 +185,9 @@
     // Pause may have happened before we subscribed.
     isolate.reload().then((_) {
       if ((isolate.pauseEvent != null) &&
-         (isolate.pauseEvent.kind == ServiceEvent.kPauseBreakpoint)) {
+         (isolate.pauseEvent.kind == kind)) {
         // Already waiting at a breakpoint.
-        print('Breakpoint reached');
+        print('Paused with $kind');
         subscription.cancel();
         if (completer != null) {
           completer.complete(isolate);
@@ -193,6 +200,13 @@
   return completer.future;  // Will complete when breakpoint hit.
 }
 
+Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
+  return hasPausedFor(isolate, ServiceEvent.kPauseBreakpoint);
+}
+
+Future<Isolate> hasStoppedWithUnhandledException(Isolate isolate) {
+  return hasPausedFor(isolate, ServiceEvent.kPauseException);
+}
 
 Future<Isolate> hasPausedAtStart(Isolate isolate) {
   // Set up a listener to wait for breakpoint events.
@@ -255,11 +269,13 @@
 
     Frame top = frames[0];
     Script script = await top.location.script.load();
-    if (script.tokenToLine(top.location.tokenPos) != line) {
+    int actualLine = script.tokenToLine(top.location.tokenPos);
+    if (actualLine != line) {
       var sb = new StringBuffer();
-      sb.write("Expected to be at line $line, but got stack trace:\n");
+      sb.write("Expected to be at line $line but actually at line $actualLine");
+      sb.write("\nFull stack trace:\n");
       for (Frame f in stack['frames']) {
-        sb.write(" $f\n");
+        sb.write(" $f [${await f.location.getLine()}]\n");
       }
       throw sb.toString();
     }
@@ -341,7 +357,8 @@
                    bool pause_on_start: false,
                    bool pause_on_exit: false,
                    bool trace_service: false,
-                   bool verbose_vm: false}) async {
+                   bool verbose_vm: false,
+                   bool pause_on_unhandled_exceptions: false}) async {
   if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
     if (!pause_on_start) {
       if (testeeBefore != null) {
@@ -360,6 +377,7 @@
     var process = new _TestLauncher();
     process.launch(pause_on_start,
                    pause_on_exit,
+                   pause_on_unhandled_exceptions,
                    trace_service).then((port) async {
       if (mainArgs.contains("--gdb")) {
         port = 8181;
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index f5163a0..ade646c 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -21,6 +21,8 @@
 # TODO(koda): Improve support for negative tests.
 cc/VerifyImplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
 cc/VerifyExplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
+# It can take some time for all the isolates to shutdown in a Debug build.
+dart/spawn_shutdown_test: Pass, Slow  # VM Shutdown test
 
 # The following section refers to the dart vm tests which live under
 # runtime/tests/vm/dart.
@@ -31,7 +33,7 @@
 cc/Dart2JSCompilerStats: Skip
 cc/CorelibCompilerStats: Skip
 
-[ $arch == simarm || $arch == simarmv5te || $arch == simarm64 || $arch == simmips ]
+[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $arch == simmips ]
 cc/Service_Profile: Skip
 
 [ $arch == arm ]
diff --git a/runtime/tools/gyp/runtime-configurations.gypi b/runtime/tools/gyp/runtime-configurations.gypi
index 4f88987..0b053c4 100644
--- a/runtime/tools/gyp/runtime-configurations.gypi
+++ b/runtime/tools/gyp/runtime-configurations.gypi
@@ -92,6 +92,20 @@
         },
       },
 
+      'Dart_simarmv6_Base': {
+        'abstract': 1,
+        'xcode_settings': {
+          'ARCHS': [ 'i386' ],
+        },
+      },
+
+      'Dart_simarmv5te_Base': {
+        'abstract': 1,
+        'xcode_settings': {
+          'ARCHS': [ 'i386' ],
+        },
+      },
+
       'Dart_simmips_Base': {
         'abstract': 1,
         'xcode_settings': {
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index 12f470a..1e6e6ef 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -1798,10 +1798,20 @@
 
 ASSEMBLER_TEST_RUN(IntDiv_supported, test) {
   EXPECT(test != NULL);
+#if defined(USING_SIMULATOR)
+  bool orig = TargetCPUFeatures::integer_division_supported();
+  HostCPUFeatures::set_integer_division_supported(true);
   if (TargetCPUFeatures::can_divide()) {
     typedef int (*Tst)() DART_UNUSED;
     EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
   }
+  HostCPUFeatures::set_integer_division_supported(orig);
+#else
+  if (TargetCPUFeatures::can_divide()) {
+    typedef int (*Tst)() DART_UNUSED;
+    EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+  }
+#endif
 }
 
 
@@ -1829,10 +1839,20 @@
 
 ASSEMBLER_TEST_RUN(IntDiv_unsupported, test) {
   EXPECT(test != NULL);
+#if defined(USING_SIMULATOR)
+  bool orig = TargetCPUFeatures::integer_division_supported();
+  HostCPUFeatures::set_integer_division_supported(false);
   if (TargetCPUFeatures::can_divide()) {
     typedef int (*Tst)() DART_UNUSED;
     EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
   }
+  HostCPUFeatures::set_integer_division_supported(orig);
+#else
+  if (TargetCPUFeatures::can_divide()) {
+    typedef int (*Tst)() DART_UNUSED;
+    EXPECT_EQ(3, EXECUTE_TEST_CODE_INT32(Tst, test->entry()));
+  }
+#endif
 }
 
 
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 19542b3..2deefa2 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -121,6 +121,36 @@
   }
 }
 
+bool LetNode::IsPotentiallyConst() const {
+  for (intptr_t i = 0; i < num_temps(); i++) {
+    if (!initializers_[i]->IsPotentiallyConst()) {
+      return false;
+    }
+  }
+  for (intptr_t i = 0; i < nodes_.length(); i++) {
+    if (!nodes_[i]->IsPotentiallyConst()) {
+      return false;
+    }
+  }
+  return true;
+}
+
+const Instance* LetNode::EvalConstExpr() const {
+  for (intptr_t i = 0; i < num_temps(); i++) {
+    if (initializers_[i]->EvalConstExpr() == NULL) {
+      return NULL;
+    }
+  }
+  const Instance* last = NULL;
+  for (intptr_t i = 0; i < nodes_.length(); i++) {
+    last = nodes_[i]->EvalConstExpr();
+    if (last == NULL) {
+      return NULL;
+    }
+  }
+  return last;
+}
+
 
 void ArrayNode::VisitChildren(AstNodeVisitor* visitor) const {
   for (intptr_t i = 0; i < this->length(); i++) {
@@ -329,6 +359,7 @@
     case Token::kBIT_AND:
     case Token::kSHL:
     case Token::kSHR:
+    case Token::kIFNULL:
       return this->left()->IsPotentiallyConst() &&
           this->right()->IsPotentiallyConst();
     default:
@@ -343,7 +374,8 @@
   if (left_val == NULL) {
     return NULL;
   }
-  if (!left_val->IsNumber() && !left_val->IsBool() && !left_val->IsString()) {
+  if (!left_val->IsNumber() && !left_val->IsBool() && !left_val->IsString() &&
+      kind_ != Token::kIFNULL) {
     return NULL;
   }
   const Instance* right_val = this->right()->EvalConstExpr();
@@ -388,6 +420,11 @@
         return left_val;
       }
       return NULL;
+    case Token::kIFNULL:
+      if (left_val->IsNull()) {
+        return right_val;
+      }
+      return left_val;
     default:
       UNREACHABLE();
       return NULL;
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 01ae0cf..494d768 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -99,7 +99,8 @@
  public:
   explicit AstNode(intptr_t token_pos)
       : token_pos_(token_pos) {
-    ASSERT(Scanner::ValidSourcePosition(token_pos_));
+    ASSERT(!Token::IsClassifying(token_pos_) ||
+           (token_pos_ == ClassifyingTokenPositions::kMethodExtractor));
   }
   virtual ~AstNode() { }
 
@@ -327,6 +328,9 @@
   LocalVariable* TempAt(intptr_t i) const { return vars_[i]; }
   AstNode* InitializerAt(intptr_t i) const { return initializers_[i]; }
 
+  virtual bool IsPotentiallyConst() const;
+  virtual const Instance* EvalConstExpr() const;
+
   LocalVariable* AddInitializer(AstNode* node);
 
   const GrowableArray<AstNode*>& nodes() const { return nodes_; }
diff --git a/runtime/vm/ast_printer_test.cc b/runtime/vm/ast_printer_test.cc
index 872d5bb..9ac8d72 100644
--- a/runtime/vm/ast_printer_test.cc
+++ b/runtime/vm/ast_printer_test.cc
@@ -13,7 +13,7 @@
 namespace dart {
 
 TEST_CASE(AstPrinter) {
-  const intptr_t kPos = Scanner::kNoSourcePos;
+  const intptr_t kPos = Token::kNoSourcePos;
   LocalVariable* v =
       new LocalVariable(kPos,
                         String::ZoneHandle(Symbols::New("wurscht")),
diff --git a/runtime/vm/ast_test.cc b/runtime/vm/ast_test.cc
index 83fea1b..afe4bdb 100644
--- a/runtime/vm/ast_test.cc
+++ b/runtime/vm/ast_test.cc
@@ -13,10 +13,10 @@
 namespace dart {
 
 TEST_CASE(Ast) {
-  LocalVariable* v = new LocalVariable(Scanner::kNoSourcePos,
+  LocalVariable* v = new LocalVariable(Token::kNoSourcePos,
                                        String::ZoneHandle(Symbols::New("v")),
                                        Type::ZoneHandle(Type::DynamicType()));
-  AstNode* ll = new LoadLocalNode(Scanner::kNoSourcePos, v);
+  AstNode* ll = new LoadLocalNode(Token::kNoSourcePos, v);
   EXPECT(ll->IsLoadLocalNode());
   EXPECT(!ll->IsLiteralNode());
   LoadLocalNode* lln = ll->AsLoadLocalNode();
@@ -24,7 +24,7 @@
   v->set_index(1);
   EXPECT_EQ(1, v->index());
 
-  LocalVariable* p = new LocalVariable(Scanner::kNoSourcePos,
+  LocalVariable* p = new LocalVariable(Token::kNoSourcePos,
                                        String::ZoneHandle(Symbols::New("p")),
                                        Type::ZoneHandle(Type::DynamicType()));
   EXPECT(!p->HasIndex());
@@ -32,22 +32,22 @@
   EXPECT(p->HasIndex());
   EXPECT_EQ(-1, p->index());
 
-  ReturnNode* r = new ReturnNode(Scanner::kNoSourcePos, lln);
+  ReturnNode* r = new ReturnNode(Token::kNoSourcePos, lln);
   EXPECT_EQ(lln, r->value());
 
   LiteralNode* l =
-      new LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(3)));
+      new LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(3)));
   EXPECT(l->literal().IsSmi());
   EXPECT_EQ(Smi::New(3), l->literal().raw());
 
   BinaryOpNode* b =
-      new BinaryOpNode(Scanner::kNoSourcePos, Token::kADD, l, lln);
+      new BinaryOpNode(Token::kNoSourcePos, Token::kADD, l, lln);
   EXPECT_EQ(Token::kADD, b->kind());
   EXPECT_EQ(l, b->left());
   EXPECT_EQ(lln, b->right());
 
   UnaryOpNode* u =
-      new UnaryOpNode(Scanner::kNoSourcePos, Token::kNEGATE, b);
+      new UnaryOpNode(Token::kNoSourcePos, Token::kNEGATE, b);
   EXPECT_EQ(Token::kNEGATE, u->kind());
   EXPECT_EQ(b, u->operand());
 
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index 32ec3f9..8954f0a 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -13,6 +13,9 @@
 // Quick access to the current zone.
 #define Z (thread()->zone())
 
+// Quick synthetic token position.
+#define ST(token_pos) Token::ToSynthetic(token_pos)
+
 // Nodes that are unreachable from already parsed expressions.
 #define FOR_EACH_UNREACHABLE_NODE(V)                                           \
   V(AwaitMarker)                                                               \
@@ -71,7 +74,7 @@
   if (await_tmp == NULL) {
     // We need a new temp variable; add it to the function's top scope.
     await_tmp = new (Z) LocalVariable(
-        Scanner::kNoSourcePos, symbol, Object::dynamic_type());
+        Token::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.
@@ -89,9 +92,11 @@
 }
 
 
-LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(AstNode* node) {
+LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(AstNode* node,
+                                                         intptr_t token_pos) {
   LocalVariable* tmp_var = EnsureCurrentTempVar();
-  preamble_->Add(new(Z) StoreLocalNode(Scanner::kNoSourcePos, tmp_var, node));
+  ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos));
+  preamble_->Add(new(Z) StoreLocalNode(token_pos, tmp_var, node));
   NextTempVar();
   return tmp_var;
 }
@@ -119,7 +124,7 @@
   //   :saved_try_ctx_var = :await_saved_try_ctx_var_y;
   //   :await_temp_var_(X+1) = :result_param;
 
-  const intptr_t token_pos = node->token_pos();
+  const intptr_t token_pos = ST(node->token_pos());
   LocalVariable* async_op = GetVariableInScope(
       preamble_->scope(), Symbols::AsyncOperation());
   LocalVariable* async_then_callback = GetVariableInScope(
@@ -134,7 +139,8 @@
       preamble_->scope(), Symbols::AsyncOperationStackTraceParam());
 
   AstNode* transformed_expr = Transform(node->expr());
-  LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr);
+  LocalVariable* await_temp = AddToPreambleNewTempVar(transformed_expr,
+                                                      ST(node->token_pos()));
 
   AwaitMarkerNode* await_marker =
       new (Z) AwaitMarkerNode(async_temp_scope_, node->scope(), token_pos);
@@ -146,23 +152,23 @@
   const Function& async_await_helper = Function::ZoneHandle(
       Z, async_lib.LookupFunctionAllowPrivate(Symbols::AsyncAwaitHelper()));
   ASSERT(!async_await_helper.IsNull());
-  ArgumentListNode* async_await_helper_args = new (Z) ArgumentListNode(
-      Scanner::kNoSourcePos);
+  ArgumentListNode* async_await_helper_args =
+      new (Z) ArgumentListNode(token_pos);
   async_await_helper_args->Add(
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, await_temp));
+      new(Z) LoadLocalNode(token_pos, await_temp));
   async_await_helper_args->Add(
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_then_callback));
+      new(Z) LoadLocalNode(token_pos, async_then_callback));
   async_await_helper_args->Add(
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, async_catch_error_callback));
+      new(Z) LoadLocalNode(token_pos, async_catch_error_callback));
   StaticCallNode* await_helper_call = new (Z) StaticCallNode(
       node->token_pos(),
       async_await_helper,
       async_await_helper_args);
 
   preamble_->Add(new(Z) StoreLocalNode(
-      Scanner::kNoSourcePos, result_param, await_helper_call));
+      token_pos, result_param, await_helper_call));
 
-  ReturnNode* continuation_return = new(Z) ReturnNode(Scanner::kNoSourcePos);
+  ReturnNode* continuation_return = new(Z) ReturnNode(token_pos);
   continuation_return->set_return_type(ReturnNode::kContinuationTarget);
   preamble_->Add(continuation_return);
 
@@ -171,15 +177,15 @@
   // saved try context of the outer try block.
   if (node->saved_try_ctx() != NULL) {
     preamble_->Add(new (Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        token_pos,
         node->saved_try_ctx(),
-        new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+        new (Z) LoadLocalNode(token_pos,
                               node->async_saved_try_ctx())));
     if (node->outer_saved_try_ctx() != NULL) {
       preamble_->Add(new (Z) StoreLocalNode(
-          Scanner::kNoSourcePos,
+          token_pos,
           node->outer_saved_try_ctx(),
-          new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+          new (Z) LoadLocalNode(token_pos,
                                 node->outer_async_saved_try_ctx())));
     }
   } else {
@@ -188,34 +194,33 @@
 
   // Load the async_op variable. It is unused, but the observatory uses it
   // to determine if a breakpoint is inside an asynchronous function.
-  LoadLocalNode* load_async_op = new (Z) LoadLocalNode(
-      Scanner::kNoSourcePos, async_op);
+  LoadLocalNode* load_async_op = new (Z) LoadLocalNode(token_pos, async_op);
   preamble_->Add(load_async_op);
 
   LoadLocalNode* load_error_param = new (Z) LoadLocalNode(
-      Scanner::kNoSourcePos, error_param);
+      token_pos, error_param);
   LoadLocalNode* load_stack_trace_param = new (Z) LoadLocalNode(
-      Scanner::kNoSourcePos, stack_trace_param);
+      token_pos, stack_trace_param);
   SequenceNode* error_ne_null_branch = new (Z) SequenceNode(
-      Scanner::kNoSourcePos, ChainNewScope(preamble_->scope()));
+      token_pos, ChainNewScope(preamble_->scope()));
   error_ne_null_branch->Add(new (Z) ThrowNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       load_error_param,
       load_stack_trace_param));
   preamble_->Add(new (Z) IfNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       new (Z) ComparisonNode(
-          Scanner::kNoSourcePos,
+          token_pos,
           Token::kNE,
           load_error_param,
-          new (Z) LiteralNode(Scanner::kNoSourcePos,
+          new (Z) LiteralNode(token_pos,
                               Object::null_instance())),
           error_ne_null_branch,
           NULL));
 
   LocalVariable* result = AddToPreambleNewTempVar(new(Z) LoadLocalNode(
-      Scanner::kNoSourcePos, result_param));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+      token_pos, result_param), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(token_pos, result);
 }
 
 
@@ -242,18 +247,18 @@
   const Token::Kind compare_logical_op = (logical_op == Token::kAND) ?
       Token::kEQ : Token::kNE;
   SequenceNode* eval = new (Z) SequenceNode(
-      Scanner::kNoSourcePos, ChainNewScope(preamble_->scope()));
+      ST(new_left->token_pos()), ChainNewScope(preamble_->scope()));
   SequenceNode* saved_preamble = preamble_;
   preamble_ = eval;
   result = Transform(right);
   preamble_ = saved_preamble;
   IfNode* right_body = new(Z) IfNode(
-      Scanner::kNoSourcePos,
+      ST(new_left->token_pos()),
       new(Z) ComparisonNode(
-          Scanner::kNoSourcePos,
+          ST(new_left->token_pos()),
           compare_logical_op,
           new_left,
-          new(Z) LiteralNode(Scanner::kNoSourcePos, Bool::True())),
+          new(Z) LiteralNode(ST(new_left->token_pos()), Bool::True())),
       eval,
       NULL);
   preamble_->Add(right_body);
@@ -280,8 +285,8 @@
       new(Z) BinaryOpNode(node->token_pos(),
                           node->kind(),
                           new_left,
-                          new_right));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                          new_right), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -295,8 +300,8 @@
                                     node->kind(),
                                     new_left,
                                     new_right,
-                                    node->mask32()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                    node->mask32()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -307,16 +312,17 @@
       new(Z) ComparisonNode(node->token_pos(),
                             node->kind(),
                             new_left,
-                            new_right));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                            new_right), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
 void AwaitTransformer::VisitUnaryOpNode(UnaryOpNode* node) {
   AstNode* new_operand = Transform(node->operand());
   LocalVariable* result = AddToPreambleNewTempVar(
-      new(Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+      new(Z) UnaryOpNode(node->token_pos(), node->kind(), new_operand),
+      ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -325,26 +331,26 @@
 void AwaitTransformer::VisitConditionalExprNode(ConditionalExprNode* node) {
   AstNode* new_condition = Transform(node->condition());
   SequenceNode* new_true = new (Z) SequenceNode(
-      Scanner::kNoSourcePos, ChainNewScope(preamble_->scope()));
+      ST(node->true_expr()->token_pos()), ChainNewScope(preamble_->scope()));
   SequenceNode* saved_preamble = preamble_;
   preamble_ = new_true;
   AstNode* new_true_result = Transform(node->true_expr());
   SequenceNode* new_false = new (Z) SequenceNode(
-      Scanner::kNoSourcePos, ChainNewScope(preamble_->scope()));
+      ST(node->false_expr()->token_pos()), ChainNewScope(preamble_->scope()));
   preamble_ = new_false;
   AstNode* new_false_result = Transform(node->false_expr());
   preamble_ = saved_preamble;
-  IfNode* new_if = new(Z) IfNode(Scanner::kNoSourcePos,
+  IfNode* new_if = new(Z) IfNode(ST(node->token_pos()),
                                  new_condition,
                                  new_true,
                                  new_false);
   preamble_->Add(new_if);
   LocalVariable* result = AddToPreambleNewTempVar(
-      new(Z) ConditionalExprNode(Scanner::kNoSourcePos,
+      new(Z) ConditionalExprNode(ST(node->token_pos()),
                                  new_condition,
                                  new_true_result,
-                                 new_false_result));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                 new_false_result), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -371,8 +377,8 @@
   ArrayNode* new_value = Transform(node->value())->AsArrayNode();
   LocalVariable* result = AddToPreambleNewTempVar(
       new(Z) StringInterpolateNode(node->token_pos(),
-                                   new_value));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                   new_value), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -385,8 +391,8 @@
       new(Z) ClosureNode(node->token_pos(),
                          node->function(),
                          new_receiver,
-                         node->scope()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                         node->scope()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -399,8 +405,8 @@
                               new_receiver,
                               node->function_name(),
                               new_args,
-                              node->is_conditional()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                              node->is_conditional()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -410,8 +416,8 @@
   LocalVariable* result = AddToPreambleNewTempVar(
       new(Z) StaticCallNode(node->token_pos(),
                             node->function(),
-                            new_args));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                            new_args), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -422,8 +428,8 @@
       new(Z) ConstructorCallNode(node->token_pos(),
                                  node->type_arguments(),
                                  node->constructor(),
-                                 new_args));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                 new_args), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -433,8 +439,8 @@
       new(Z) InstanceGetterNode(node->token_pos(),
                                 new_receiver,
                                 node->field_name(),
-                                node->is_conditional()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                node->is_conditional()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -449,8 +455,8 @@
                                 new_receiver,
                                 node->field_name(),
                                 new_value,
-                                node->is_conditional()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                                node->is_conditional()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -465,8 +471,9 @@
                               node->cls(),
                               node->field_name());
   new_getter->set_owner(node->owner());
-  LocalVariable* result = AddToPreambleNewTempVar(new_getter);
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+  LocalVariable* result =
+      AddToPreambleNewTempVar(new_getter, ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -489,8 +496,9 @@
                                 node->function(),
                                 new_value);
 
-  LocalVariable* result = AddToPreambleNewTempVar(new_setter);
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+  LocalVariable* result =
+      AddToPreambleNewTempVar(new_setter, ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -525,8 +533,8 @@
       new(Z) LoadIndexedNode(node->token_pos(),
                              new_array,
                              new_index,
-                             node->super_class()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                             node->super_class()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -539,8 +547,8 @@
                               new_array,
                               new_index,
                               new_value,
-                              node->super_class()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                              node->super_class()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -550,8 +558,8 @@
       new(Z) AssignableNode(node->token_pos(),
                             new_expr,
                             node->type(),
-                            node->dst_name()));
-  result_ = new(Z) LoadLocalNode(Scanner::kNoSourcePos, result);
+                            node->dst_name()), ST(node->token_pos()));
+  result_ = new(Z) LoadLocalNode(ST(node->token_pos()), result);
 }
 
 
@@ -565,8 +573,8 @@
     async_temp_scope_->AddVariable(node->TempAt(i));
     AstNode* new_init_val = Transform(node->InitializerAt(i));
     preamble_->Add(new(Z) StoreLocalNode(node->token_pos(),
-                   node->TempAt(i),
-                   new_init_val));
+                                         node->TempAt(i),
+                                         new_init_val));
   }
 
   // Add all expressions but the last to the preamble. We must do
diff --git a/runtime/vm/ast_transformer.h b/runtime/vm/ast_transformer.h
index e9f6791..d8c01d0 100644
--- a/runtime/vm/ast_transformer.h
+++ b/runtime/vm/ast_transformer.h
@@ -51,7 +51,7 @@
 
  private:
   LocalVariable* EnsureCurrentTempVar();
-  LocalVariable* AddToPreambleNewTempVar(AstNode* node);
+  LocalVariable* AddToPreambleNewTempVar(AstNode* node, intptr_t token_pos);
   ArgumentListNode* TransformArguments(ArgumentListNode* node);
   AstNode* LazyTransform(const Token::Kind kind,
                          AstNode* new_left,
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 7596920..f7bd22d 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -339,13 +339,11 @@
     SetupNativeResolver();
     ClassFinalizer::ProcessPendingClasses();
 
-    Class& cls = Class::Handle(zone);
-    // Eagerly compile the function implementation class as it is the super
-    // class of signature classes. This allows us to just finalize signature
-    // classes without going through the hoops of trying to compile them.
-    const Type& type =
-        Type::Handle(zone, isolate->object_store()->function_impl_type());
-    cls = type.type_class();
+    // Eagerly compile the _Closure class as it is the class of all closure
+    // instances. This allows us to just finalize function types
+    // without going through the hoops of trying to compile their scope class.
+    const Class& cls =
+        Class::Handle(zone, isolate->object_store()->closure_class());
     Compiler::CompileClass(cls);
   }
 
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 8803755..26e4d5d 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -28,9 +28,9 @@
   V(Object_instanceOfString, 2)                                                \
   V(Object_as, 3)                                                              \
   V(Function_apply, 2)                                                         \
-  V(FunctionImpl_equals, 2)                                                    \
-  V(FunctionImpl_hashCode, 1)                                                  \
-  V(FunctionImpl_clone, 1)                                                     \
+  V(Closure_equals, 2)                                                         \
+  V(Closure_hashCode, 1)                                                       \
+  V(Closure_clone, 1)                                                          \
   V(AbstractType_toString, 1)                                                  \
   V(Identical_comparison, 2)                                                   \
   V(Integer_bitAndFromInteger, 2)                                              \
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index 667d598..ed5255e 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -49,8 +49,8 @@
 
 
 bool CHA::IsImplemented(const Class& cls) {
-  // Signature classes have different type checking rules.
-  ASSERT(!cls.IsSignatureClass());
+  // Function type aliases have different type checking rules.
+  ASSERT(!cls.IsTypedefClass());
   // Can't track dependencies for classes on the VM heap since those are
   // read-only.
   // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index a7c998d..7712324 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -98,10 +98,9 @@
   EXPECT(ContainsCid(cha.leaf_classes(), class_c.id()));
   EXPECT(ContainsCid(cha.leaf_classes(), class_d.id()));
 
-  const Class& function_impl_class =
-      Class::Handle(Type::Handle(Isolate::Current()->object_store()->
-          function_impl_type()).type_class());
-  EXPECT(cha.HasSubclasses(function_impl_class.id()));
+  const Class& closure_class =
+      Class::Handle(Isolate::Current()->object_store()->closure_class());
+  EXPECT(!cha.HasSubclasses(closure_class.id()));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 8ef3511..67b3683 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -440,7 +440,8 @@
     if (!target_type.IsInstantiated()) {
       const TypeArguments& type_args = TypeArguments::Handle(type.arguments());
       Error& bound_error = Error::Handle();
-      target_type ^= target_type.InstantiateFrom(type_args, &bound_error);
+      target_type ^= target_type.InstantiateFrom(
+          type_args, &bound_error, NULL, Heap::kOld);
       if (bound_error.IsNull()) {
         target_type ^= FinalizeType(cls, target_type, kCanonicalize);
       } else {
@@ -457,10 +458,10 @@
 }
 
 
-void ClassFinalizer::ResolveTypeClass(const Class& cls,
-                                      const AbstractType& type) {
-  if (type.IsFinalized() || type.HasResolvedTypeClass()) {
-    return;
+RawAbstractType* ClassFinalizer::ResolveTypeClass(const Class& cls,
+                                                  const Type& type) {
+  if (type.IsFinalized()) {
+    return type.raw();
   }
   if (FLAG_trace_type_finalization) {
     THR_Print("Resolve type class of '%s'\n",
@@ -473,55 +474,77 @@
   // that the type parameter appeared in a static scope. Leaving the type as
   // unresolved is the correct thing to do.
 
-  // Lookup the type class.
-  const UnresolvedClass& unresolved_class =
-      UnresolvedClass::Handle(type.unresolved_class());
-  const Class& type_class =
-      Class::Handle(ResolveClass(cls, unresolved_class));
-
-  // Replace unresolved class with resolved type class.
-  const Type& parameterized_type = Type::Cast(type);
-  if (type_class.IsNull()) {
-    // The type class could not be resolved. The type is malformed.
-    FinalizeMalformedType(
-        Error::Handle(),  // No previous error.
-        Script::Handle(cls.script()),
-        parameterized_type,
-        "cannot resolve class '%s' from '%s'",
-        String::Handle(unresolved_class.Name()).ToCString(),
-        String::Handle(cls.Name()).ToCString());
-    return;
+  // Lookup the type class if necessary.
+  Class& type_class = Class::Handle();
+  if (type.HasResolvedTypeClass()) {
+    type_class = type.type_class();
+  } else {
+    const UnresolvedClass& unresolved_class =
+        UnresolvedClass::Handle(type.unresolved_class());
+    type_class = ResolveClass(cls, unresolved_class);
+    if (type_class.IsNull()) {
+      // The type class could not be resolved. The type is malformed.
+      FinalizeMalformedType(
+          Error::Handle(),  // No previous error.
+          Script::Handle(cls.script()),
+          type,
+          "cannot resolve class '%s' from '%s'",
+          String::Handle(unresolved_class.Name()).ToCString(),
+          String::Handle(cls.Name()).ToCString());
+      return type.raw();
+    }
   }
-  parameterized_type.set_type_class(type_class);
+  // Promote the Type to a FunctionType in case its type class is a typedef.
+  if (type_class.IsTypedefClass()) {
+    return FunctionType::New(type_class,
+                             TypeArguments::Handle(type.arguments()),
+                             Function::Handle(type_class.signature_function()),
+                             type.token_pos());
+  }
+  // Replace unresolved class with resolved type class.
+  type.set_type_class(type_class);
+  return type.raw();
 }
 
 
-void ClassFinalizer::ResolveType(const Class& cls, const AbstractType& type) {
+RawAbstractType* ClassFinalizer::ResolveType(const Class& cls,
+                                             const AbstractType& type) {
   if (type.IsResolved()) {
-    return;
+    return type.raw();
   }
-  ASSERT(type.IsType());
   if (FLAG_trace_type_finalization) {
     THR_Print("Resolve type '%s'\n", String::Handle(type.Name()).ToCString());
   }
-  ResolveTypeClass(cls, type);
-  if (type.IsMalformed()) {
-    ASSERT(type.IsResolved());
-    return;
+  AbstractType& resolved_type = AbstractType::Handle();
+  if (type.IsType()) {
+    resolved_type = ResolveTypeClass(cls, Type::Cast(type));
+    if (resolved_type.IsMalformed()) {
+      ASSERT(resolved_type.IsResolved());
+      return resolved_type.raw();
+    }
+  } else {
+    ASSERT(type.IsFunctionType());
+    const Function& signature =
+        Function::Handle(FunctionType::Cast(type).signature());
+    ResolveSignature(cls, signature);
+    resolved_type = type.raw();
   }
   // Mark type as resolved before resolving its type arguments in order to avoid
   // repeating resolution of recursive types.
-  Type::Cast(type).set_is_resolved();
+  resolved_type.SetIsResolved();
   // Resolve type arguments, if any.
-  const TypeArguments& arguments = TypeArguments::Handle(type.arguments());
+  const TypeArguments& arguments =
+      TypeArguments::Handle(resolved_type.arguments());
   if (!arguments.IsNull()) {
     const intptr_t num_arguments = arguments.Length();
     AbstractType& type_argument = AbstractType::Handle();
     for (intptr_t i = 0; i < num_arguments; i++) {
       type_argument = arguments.TypeAt(i);
-      ResolveType(cls, type_argument);
+      type_argument = ResolveType(cls, type_argument);
+      arguments.SetTypeAt(i, type_argument);
     }
   }
+  return resolved_type.raw();
 }
 
 
@@ -564,7 +587,7 @@
 // A non-contractive type can be detected by looking at the queue of types
 // pending finalization that are mutually recursive with the checked type.
 void ClassFinalizer::CheckRecursiveType(const Class& cls,
-                                        const Type& type,
+                                        const AbstractType& type,
                                         PendingTypes* pending_types) {
   Zone* zone = Thread::Current()->zone();
   if (FLAG_trace_type_finalization) {
@@ -620,6 +643,127 @@
 }
 
 
+// Expand the type arguments of the given type and finalize its full type
+// argument vector. Return the number of type arguments (0 for a raw type).
+intptr_t ClassFinalizer::ExpandAndFinalizeTypeArguments(
+    const Class& cls,
+    const AbstractType& type,
+    PendingTypes* pending_types) {
+  Zone* Z = Thread::Current()->zone();
+  // The type class does not need to be finalized in order to finalize the type,
+  // however, it must at least be resolved (this was done as part of resolving
+  // the type itself, a precondition to calling FinalizeType).
+  // Also, the interfaces of the type class must be resolved and the type
+  // parameters of the type class must be finalized.
+  Class& type_class = Class::Handle(Z, type.type_class());
+  if (!type_class.is_type_finalized()) {
+    FinalizeTypeParameters(type_class, pending_types);
+    ResolveUpperBounds(type_class);
+  }
+
+  // The finalized type argument vector needs num_type_arguments types.
+  const intptr_t num_type_arguments = type_class.NumTypeArguments();
+  // The class has num_type_parameters type parameters.
+  const intptr_t num_type_parameters = type_class.NumTypeParameters();
+
+  // Initialize the type argument vector.
+  // Check the number of parsed type arguments, if any.
+  // Specifying no type arguments indicates a raw type, which is not an error.
+  // However, type parameter bounds are checked below, even for a raw type.
+  TypeArguments& arguments = TypeArguments::Handle(Z, type.arguments());
+  if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
+    // Wrong number of type arguments. The type is mapped to the raw type.
+    if (Isolate::Current()->flags().error_on_bad_type()) {
+      const String& type_class_name = String::Handle(Z, type_class.Name());
+      ReportError(cls, type.token_pos(),
+                  "wrong number of type arguments for class '%s'",
+                  type_class_name.ToCString());
+    }
+    // Make the type raw and continue without reporting any error.
+    // A static warning should have been reported.
+    arguments = TypeArguments::null();
+    type.set_arguments(arguments);
+  }
+
+  // Mark the type as being finalized in order to detect self reference and
+  // postpone bound checking until after all types in the graph of
+  // mutually recursive types are finalized.
+  type.SetIsBeingFinalized();
+  pending_types->Add(type);
+
+  // The full type argument vector consists of the type arguments of the
+  // super types of type_class, which are initialized from the parsed
+  // type arguments, followed by the parsed type arguments.
+  TypeArguments& full_arguments = TypeArguments::Handle(Z);
+  if (num_type_arguments > 0) {
+    // If no type arguments were parsed and if the super types do not prepend
+    // type arguments to the vector, we can leave the vector as null.
+    if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) {
+      full_arguments = TypeArguments::New(num_type_arguments);
+      // Copy the parsed type arguments at the correct offset in the full type
+      // argument vector.
+      const intptr_t offset = num_type_arguments - num_type_parameters;
+      AbstractType& type_arg =
+          AbstractType::Handle(Z, Type::DynamicType());
+      // Leave the temporary type arguments at indices [0..offset[ as null.
+      for (intptr_t i = 0; i < num_type_parameters; i++) {
+        // If no type parameters were provided, a raw type is desired, so we
+        // create a vector of dynamic.
+        if (!arguments.IsNull()) {
+          type_arg = arguments.TypeAt(i);
+          // The parsed type_arg may or may not be finalized.
+        }
+        full_arguments.SetTypeAt(offset + i, type_arg);
+      }
+      // Replace the compile-time argument vector (of length zero or
+      // num_type_parameters) of this type being finalized with the still
+      // unfinalized run-time argument vector (of length num_type_arguments).
+      // This type being finalized may be recursively reached via bounds
+      // checking or type arguments of its super type.
+      type.set_arguments(full_arguments);
+      // Finalize the current type arguments of the type, which are still the
+      // parsed type arguments.
+      if (!arguments.IsNull()) {
+        for (intptr_t i = 0; i < num_type_parameters; i++) {
+          type_arg = full_arguments.TypeAt(offset + i);
+          ASSERT(!type_arg.IsBeingFinalized());
+          type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types);
+          if (type_arg.IsMalformed()) {
+            // Malformed type arguments are mapped to dynamic.
+            type_arg = Type::DynamicType();
+          }
+          full_arguments.SetTypeAt(offset + i, type_arg);
+        }
+      }
+      if (offset > 0) {
+        TrailPtr trail = new Trail(Z, 4);
+        Error& bound_error = Error::Handle();
+        FinalizeTypeArguments(type_class, full_arguments, offset,
+                              &bound_error, pending_types, trail);
+      }
+      if (full_arguments.IsRaw(0, num_type_arguments)) {
+        // The parameterized_type is raw. Set its argument vector to null, which
+        // is more efficient in type tests.
+        full_arguments = TypeArguments::null();
+      }
+      type.set_arguments(full_arguments);
+    } else {
+      ASSERT(full_arguments.IsNull());  // Use null vector for raw type.
+    }
+  }
+
+  // Self referencing types may get finalized indirectly.
+  if (!type.IsFinalized()) {
+    ASSERT(full_arguments.IsNull() ||
+           !full_arguments.IsRaw(0, num_type_arguments));
+    // Mark the type as finalized.
+    type.SetIsFinalized();
+    // Do not yet remove the type from the pending_types array.
+  }
+  return full_arguments.IsNull() ? 0 : full_arguments.Length();
+}
+
+
 // Finalize the type argument vector 'arguments' of the type defined by the
 // class 'cls' parameterized with the type arguments 'cls_args'.
 // The vector 'cls_args' is already initialized as a subvector at the correct
@@ -687,8 +831,8 @@
         super_type_arg = super_type_args.TypeAt(i);
         if (!super_type_arg.IsTypeRef()) {
           if (super_type_arg.IsBeingFinalized()) {
-            ASSERT(super_type_arg.IsType());
-            CheckRecursiveType(cls, Type::Cast(super_type_arg), pending_types);
+            ASSERT(super_type_arg.IsType() || super_type_arg.IsFunctionType());
+            CheckRecursiveType(cls, super_type_arg, pending_types);
             if (FLAG_trace_type_finalization) {
               THR_Print("Creating TypeRef '%s': '%s'\n",
                         String::Handle(super_type_arg.Name()).ToCString(),
@@ -737,7 +881,7 @@
             if (super_type_arg.IsTypeRef()) {
               super_type_arg = TypeRef::Cast(super_type_arg).type();
             }
-            Type::Cast(super_type_arg).set_is_being_finalized();
+            Type::Cast(super_type_arg).SetIsBeingFinalized();
             pending_types->Add(super_type_arg);
             const Class& cls = Class::Handle(super_type_arg.type_class());
             FinalizeTypeArguments(
@@ -844,9 +988,10 @@
         if (type_arg.IsTypeParameter()) {
           const Class& type_arg_cls = Class::Handle(
               TypeParameter::Cast(type_arg).parameterized_class());
-          const AbstractType& bound = AbstractType::Handle(
+          AbstractType& bound = AbstractType::Handle(
               TypeParameter::Cast(type_arg).bound());
-          ResolveType(type_arg_cls, bound);
+          bound = ResolveType(type_arg_cls, bound);
+          TypeParameter::Cast(type_arg).set_bound(bound);
         }
         // This may be called only if type needs to be finalized, therefore
         // seems OK to allocate finalized types in old space.
@@ -870,24 +1015,17 @@
 }
 
 
-void ClassFinalizer::CheckTypeBounds(const Class& cls, const Type& type) {
+void ClassFinalizer::CheckTypeBounds(const Class& cls,
+                                     const AbstractType& type) {
+  ASSERT(type.IsType() || type.IsFunctionType());
   ASSERT(type.IsFinalized());
   TypeArguments& arguments = TypeArguments::Handle(type.arguments());
   if (arguments.IsNull()) {
     return;
   }
-  Class& owner_class = Class::Handle();
-  Class& type_class = Class::Handle(type.type_class());
-  if (type_class.IsSignatureClass()) {
-    const Function& signature_fun =
-        Function::Handle(type_class.signature_function());
-    ASSERT(!signature_fun.is_static());
-    owner_class = signature_fun.Owner();
-  } else {
-    owner_class = type_class.raw();
-  }
+  const Class& type_class = Class::Handle(type.type_class());
   Error& bound_error = Error::Handle();
-  CheckTypeArgumentBounds(owner_class, arguments, &bound_error);
+  CheckTypeArgumentBounds(type_class, arguments, &bound_error);
   type.set_arguments(arguments);
   // If a bound error occurred, mark the type as malbounded.
   // The bound error will be ignored in production mode.
@@ -936,22 +1074,23 @@
   // encountered here.
   ASSERT(!type.IsBeingFinalized());
 
+  Zone* Z = Thread::Current()->zone();
+  const AbstractType& resolved_type =
+      AbstractType::Handle(Z, ResolveType(cls, type));
   // A malformed type gets mapped to a finalized type.
-  ResolveType(cls, type);
-  if (type.IsMalformed()) {
-    ASSERT(type.IsFinalized());
-    return type.raw();
+  if (resolved_type.IsMalformed()) {
+    ASSERT(resolved_type.IsFinalized());
+    return resolved_type.raw();
   }
 
-  Zone* Z = Thread::Current()->zone();
   if (FLAG_trace_type_finalization) {
     THR_Print("Finalizing type '%s' for class '%s'\n",
-              String::Handle(Z, type.Name()).ToCString(),
+              String::Handle(Z, resolved_type.Name()).ToCString(),
               cls.ToCString());
   }
 
-  if (type.IsTypeParameter()) {
-    const TypeParameter& type_parameter = TypeParameter::Cast(type);
+  if (resolved_type.IsTypeParameter()) {
+    const TypeParameter& type_parameter = TypeParameter::Cast(resolved_type);
     const Class& parameterized_class =
         Class::Handle(Z, type_parameter.parameterized_class());
     ASSERT(!parameterized_class.IsNull());
@@ -966,7 +1105,7 @@
     // belongs to a mixin application class.
     if (!type_parameter.IsFinalized()) {
       type_parameter.set_index(type_parameter.index() + offset);
-      type_parameter.set_is_finalized();
+      type_parameter.SetIsFinalized();
     } else {
       ASSERT(cls.IsMixinApplication());
     }
@@ -981,8 +1120,8 @@
     return type_parameter.raw();
   }
 
-  // At this point, we can only have a parameterized_type.
-  const Type& parameterized_type = Type::Cast(type);
+  // At this point, we can only have a Type or a FunctionType.
+  ASSERT(resolved_type.IsType() || resolved_type.IsFunctionType());
 
   // This type is the root type of the type graph if no pending types queue is
   // allocated yet.
@@ -991,197 +1130,93 @@
     pending_types = new PendingTypes(Z, 4);
   }
 
-  // The type class does not need to be finalized in order to finalize the type,
-  // however, it must at least be resolved (this was done as part of resolving
-  // the type itself, a precondition to calling FinalizeType).
-  // Also, the interfaces of the type class must be resolved and the type
-  // parameters of the type class must be finalized.
-  Class& type_class = Class::Handle(Z, parameterized_type.type_class());
-  if (!type_class.is_type_finalized()) {
-    FinalizeTypeParameters(type_class, pending_types);
-    ResolveUpperBounds(type_class);
-  }
-
-  // The finalized type argument vector needs num_type_arguments types.
-  const intptr_t num_type_arguments = type_class.NumTypeArguments();
-  // The type class has num_type_parameters type parameters.
-  const intptr_t num_type_parameters = type_class.NumTypeParameters();
-
-  // Initialize the type argument vector.
-  // Check the number of parsed type arguments, if any.
-  // Specifying no type arguments indicates a raw type, which is not an error.
-  // However, type parameter bounds are checked below, even for a raw type.
-  TypeArguments& arguments =
-      TypeArguments::Handle(Z, parameterized_type.arguments());
-  if (!arguments.IsNull() && (arguments.Length() != num_type_parameters)) {
-    // Wrong number of type arguments. The type is mapped to the raw type.
-    if (Isolate::Current()->flags().error_on_bad_type()) {
-      const String& type_class_name =
-          String::Handle(Z, type_class.Name());
-      ReportError(cls, parameterized_type.token_pos(),
-                  "wrong number of type arguments for class '%s'",
-                  type_class_name.ToCString());
-    }
-    // Make the type raw and continue without reporting any error.
-    // A static warning should have been reported.
-    arguments = TypeArguments::null();
-    parameterized_type.set_arguments(arguments);
-  }
-
-  // Mark the type as being finalized in order to detect self reference and
-  // postpone bound checking until after all types in the graph of
-  // mutually recursive types are finalized.
-  parameterized_type.set_is_being_finalized();
-  pending_types->Add(parameterized_type);
-
-  // The full type argument vector consists of the type arguments of the
-  // super types of type_class, which are initialized from the parsed
-  // type arguments, followed by the parsed type arguments.
-  TypeArguments& full_arguments = TypeArguments::Handle(Z);
-  Error& bound_error = Error::Handle(Z);
-  if (num_type_arguments > 0) {
-    // If no type arguments were parsed and if the super types do not prepend
-    // type arguments to the vector, we can leave the vector as null.
-    if (!arguments.IsNull() || (num_type_arguments > num_type_parameters)) {
-      full_arguments = TypeArguments::New(num_type_arguments);
-      // Copy the parsed type arguments at the correct offset in the full type
-      // argument vector.
-      const intptr_t offset = num_type_arguments - num_type_parameters;
-      AbstractType& type_arg =
-          AbstractType::Handle(Z, Type::DynamicType());
-      // Leave the temporary type arguments at indices [0..offset[ as null.
-      for (intptr_t i = 0; i < num_type_parameters; i++) {
-        // If no type parameters were provided, a raw type is desired, so we
-        // create a vector of dynamic.
-        if (!arguments.IsNull()) {
-          type_arg = arguments.TypeAt(i);
-          // The parsed type_arg may or may not be finalized.
-        }
-        full_arguments.SetTypeAt(offset + i, type_arg);
-      }
-      // Replace the compile-time argument vector (of length zero or
-      // num_type_parameters) of this type being finalized with the still
-      // unfinalized run-time argument vector (of length num_type_arguments).
-      // This type being finalized may be recursively reached via bounds
-      // checking or type arguments of its super type.
-      parameterized_type.set_arguments(full_arguments);
-      // Finalize the current type arguments of the type, which are still the
-      // parsed type arguments.
-      if (!arguments.IsNull()) {
-        for (intptr_t i = 0; i < num_type_parameters; i++) {
-          type_arg = full_arguments.TypeAt(offset + i);
-          ASSERT(!type_arg.IsBeingFinalized());
-          type_arg = FinalizeType(cls, type_arg, kFinalize, pending_types);
-          if (type_arg.IsMalformed()) {
-            // Malformed type arguments are mapped to dynamic.
-            type_arg = Type::DynamicType();
-          }
-          full_arguments.SetTypeAt(offset + i, type_arg);
-        }
-      }
-      // If the type class is a signature class, the full argument vector
-      // must include the argument vector of the super type.
-      // If the signature class is a function type alias, it is also the owner
-      // of its signature function and no super type is involved.
-      // If the signature class is canonical (not an alias), the owner of its
-      // signature function may either be an alias or the enclosing class of a
-      // local function, in which case the super type of the enclosing class is
-      // also considered when filling up the argument vector.
-      Class& owner_class = Class::Handle(Z);
-      if (type_class.IsSignatureClass()) {
-        const Function& signature_fun =
-            Function::Handle(Z, type_class.signature_function());
-        ASSERT(!signature_fun.is_static());
-        owner_class = signature_fun.Owner();
-      } else {
-        owner_class = type_class.raw();
-      }
-      if (offset > 0) {
-        TrailPtr trail = new Trail(Z, 4);
-        FinalizeTypeArguments(owner_class, full_arguments, offset,
-                              &bound_error, pending_types, trail);
-      }
-      if (full_arguments.IsRaw(0, num_type_arguments)) {
-        // The parameterized_type is raw. Set its argument vector to null, which
-        // is more efficient in type tests.
-        full_arguments = TypeArguments::null();
-      }
-      parameterized_type.set_arguments(full_arguments);
-    } else {
-      ASSERT(full_arguments.IsNull());  // Use null vector for raw type.
-    }
-  }
-
-  // Self referencing types may get finalized indirectly.
-  if (!parameterized_type.IsFinalized()) {
-    ASSERT(full_arguments.IsNull() ||
-           !full_arguments.IsRaw(0, num_type_arguments));
-    // Mark the type as finalized.
-    parameterized_type.SetIsFinalized();
-    // Do not yet remove the type from the pending_types array.
-  }
+  const intptr_t num_expanded_type_arguments =
+      ExpandAndFinalizeTypeArguments(cls, resolved_type, pending_types);
 
   // If we are done finalizing a graph of mutually recursive types, check their
   // bounds.
   if (is_root_type) {
     for (intptr_t i = pending_types->length() - 1; i >= 0; i--) {
-      CheckTypeBounds(cls, Type::Cast(pending_types->At(i)));
-      if (FLAG_trace_type_finalization && type.IsRecursive()) {
+      CheckTypeBounds(cls, pending_types->At(i));
+      if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) {
         THR_Print("Done finalizing recursive type '%s': %s\n",
-                  String::Handle(Z, type.Name()).ToCString(),
-                  type.ToCString());
+                  String::Handle(Z, resolved_type.Name()).ToCString(),
+                  resolved_type.ToCString());
       }
     }
   }
 
-  // If the type class is a signature class, we are currently finalizing a
-  // signature type, i.e. finalizing the result type and parameter types of the
-  // signature function of this signature type.
+  // If the type is a FunctionType, we also need to finalize the types in its
+  // signature, i.e. finalize the result type and parameter types of the
+  // signature function of this function type.
   // We do this after marking this type as finalized in order to allow a
   // function type to refer to itself via its parameter types and result type.
-  if (type_class.IsSignatureClass()) {
-    // The class may be created while parsing a function body, after all
-    // pending classes have already been finalized.
-    FinalizeTypesInClass(type_class);
+  // Note that we do not instantiate these types according to the type
+  // arguments. This will happen on demand when executing a type test.
+  if (resolved_type.IsFunctionType()) {
+    const Function& signature =
+        Function::Handle(Z, FunctionType::Cast(resolved_type).signature());
+    FinalizeSignature(cls, signature);
   }
 
   if (FLAG_trace_type_finalization) {
     THR_Print("Done finalizing type '%s' with %" Pd " type args: %s\n",
-              String::Handle(Z, parameterized_type.Name()).ToCString(),
-              parameterized_type.arguments() == TypeArguments::null() ?
-                  0 : num_type_arguments,
-              parameterized_type.ToCString());
+              String::Handle(Z, resolved_type.Name()).ToCString(),
+              num_expanded_type_arguments,
+              resolved_type.ToCString());
   }
 
   if (finalization >= kCanonicalize) {
-    if (FLAG_trace_type_finalization && parameterized_type.IsRecursive()) {
-      AbstractType& type = Type::Handle(Z);
-      type = parameterized_type.Canonicalize();
+    if (FLAG_trace_type_finalization && resolved_type.IsRecursive()) {
+      AbstractType& recursive_type =
+          AbstractType::Handle(Z, resolved_type.Canonicalize());
       THR_Print("Done canonicalizing recursive type '%s': %s\n",
-                String::Handle(Z, type.Name()).ToCString(),
-                type.ToCString());
-      return type.raw();
+                String::Handle(Z, recursive_type.Name()).ToCString(),
+                recursive_type.ToCString());
+      return recursive_type.raw();
     }
-    return parameterized_type.Canonicalize();
+    return resolved_type.Canonicalize();
   } else {
-    return parameterized_type.raw();
+    return resolved_type.raw();
   }
 }
 
 
-void ClassFinalizer::ResolveAndFinalizeSignature(const Class& cls,
-                                                 const Function& function) {
+void ClassFinalizer::ResolveSignature(const Class& cls,
+                                      const Function& function) {
   // Resolve result type.
   AbstractType& type = AbstractType::Handle(function.result_type());
   // It is not a compile time error if this name does not resolve to a class or
   // interface.
+  AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type));
+  if (resolved_type.raw() != type.raw()) {
+    function.set_result_type(resolved_type);
+  }
+  // Resolve formal parameter types.
+  const intptr_t num_parameters = function.NumParameters();
+  for (intptr_t i = 0; i < num_parameters; i++) {
+    type = function.ParameterTypeAt(i);
+    resolved_type = ResolveType(cls, type);
+    if (resolved_type.raw() != type.raw()) {
+      function.SetParameterTypeAt(i, resolved_type);
+    }
+  }
+}
+
+
+void ClassFinalizer::FinalizeSignature(const Class& cls,
+                                       const Function& function) {
+  // Finalize result type.
+  AbstractType& type = AbstractType::Handle(function.result_type());
+  // It is not a compile time error if this name does not resolve to a class or
+  // interface.
   AbstractType& finalized_type =
       AbstractType::Handle(FinalizeType(cls, type, kCanonicalize));
   // The result type may be malformed or malbounded.
-  if (type.raw() != finalized_type.raw()) {
+  if (finalized_type.raw() != type.raw()) {
     function.set_result_type(finalized_type);
   }
-  // Resolve formal parameter types.
+  // Finalize formal parameter types.
   const intptr_t num_parameters = function.NumParameters();
   for (intptr_t i = 0; i < num_parameters; i++) {
     type = function.ParameterTypeAt(i);
@@ -1255,7 +1290,8 @@
   for (intptr_t i = 0; i < num_type_params; i++) {
     type_param ^= type_params.TypeAt(i);
     bound = type_param.bound();
-    ResolveType(cls, bound);
+    bound = ResolveType(cls, bound);
+    type_param.set_bound(bound);
   }
 }
 
@@ -1445,7 +1481,7 @@
   Error& error = Error::Handle(Z);
   for (intptr_t i = 0; i < num_functions; i++) {
     function ^= array.At(i);
-    ResolveAndFinalizeSignature(cls, function);
+    FinalizeSignature(cls, function);
     name = function.name();
     // Report signature conflicts only.
     if (Isolate::Current()->flags().error_on_bad_override() &&
@@ -1718,8 +1754,8 @@
                   FinalizeType(mixin_app_class, param_bound, kCanonicalize);
               param.set_bound(param_bound);  // In case part of recursive type.
             }
-            param_bound = param_bound.InstantiateFrom(instantiator,
-                                                      &bound_error);
+            param_bound = param_bound.InstantiateFrom(
+                instantiator, &bound_error, NULL, Heap::kOld);
             // The instantiator contains only TypeParameter objects and no
             // BoundedType objects, so no bound error may occur.
             ASSERT(!param_bound.IsBoundedType());
@@ -1947,19 +1983,21 @@
         // the BoundedType in another BoundedType.
         if (type.IsBoundedType()) {
           bounded_type = BoundedType::Cast(type).type();
-          bounded_type = bounded_type.InstantiateFrom(instantiator,
-                                                      &bound_error);
+          bounded_type = bounded_type.InstantiateFrom(
+              instantiator, &bound_error, NULL, Heap::kOld);
           // The instantiator contains only TypeParameter objects and no
           // BoundedType objects, so no bound error may occur.
           ASSERT(bound_error.IsNull());
           upper_bound = BoundedType::Cast(type).bound();
-          upper_bound = upper_bound.InstantiateFrom(instantiator, &bound_error);
+          upper_bound = upper_bound.InstantiateFrom(
+              instantiator, &bound_error, NULL, Heap::kOld);
           ASSERT(bound_error.IsNull());
           type_parameter = BoundedType::Cast(type).type_parameter();
           // The type parameter that declared the bound does not change.
           type = BoundedType::New(bounded_type, upper_bound, type_parameter);
         } else {
-          type = type.InstantiateFrom(instantiator, &bound_error);
+          type = type.InstantiateFrom(
+              instantiator, &bound_error, NULL, Heap::kOld);
           ASSERT(bound_error.IsNull());
         }
       }
@@ -2172,12 +2210,23 @@
   const intptr_t num_functions = functions.Length();
   for (intptr_t i = 0; i < num_functions; i++) {
     func ^= functions.At(i);
-    if (func.IsGenerativeConstructor()) {
+    if (func.IsFactory() || func.IsGenerativeConstructor()) {
       // A mixin class must not have explicit constructors.
       if (!func.IsImplicitConstructor()) {
-        ReportError(cls, cls.token_pos(),
-                    "mixin class '%s' must not have constructors\n",
-                    String::Handle(zone, mixin_cls.Name()).ToCString());
+        const char* ctr_kind = func.IsFactory() ? "factory" : "constructor";
+        const Script& script = Script::Handle(cls.script());
+        const Error& error = Error::Handle(
+            LanguageError::NewFormatted(Error::Handle(),
+                script, func.token_pos(), Report::AtLocation,
+                Report::kError, Heap::kNew,
+                "%s '%s' is illegal in mixin class %s",
+                ctr_kind,
+                String::Handle(func.PrettyName()).ToCString(),
+                String::Handle(zone, mixin_cls.Name()).ToCString()));
+
+        ReportErrors(error, cls, cls.token_pos(),
+                     "mixin class '%s' must not have constructors",
+                     String::Handle(zone, mixin_cls.Name()).ToCString());
       }
       continue;  // Skip the implicit constructor.
     }
@@ -2245,6 +2294,8 @@
   // Only resolving rather than finalizing the upper bounds here would result in
   // instantiated type parameters of the super type to temporarily have
   // unfinalized bounds. It is more efficient to finalize them early.
+  // Finalize bounds even if running in production mode, so that a snapshot
+  // contains them.
   FinalizeUpperBounds(cls);
   // Finalize super type.
   AbstractType& super_type = AbstractType::Handle(cls.super_type());
@@ -2265,10 +2316,13 @@
     mixin_type ^= FinalizeType(cls, mixin_type, kCanonicalizeWellFormed);
     cls.set_mixin(mixin_type);
   }
-  if (cls.IsSignatureClass()) {
+  if (cls.IsTypedefClass()) {
+    const Function& signature = Function::Handle(cls.signature_function());
+    FunctionType& type = FunctionType::Handle(signature.SignatureType());
+
     // Check for illegal self references.
     GrowableArray<intptr_t> visited_aliases;
-    if (!IsAliasCycleFree(cls, &visited_aliases)) {
+    if (!IsTypedefCycleFree(cls, type, &visited_aliases)) {
       const String& name = String::Handle(cls.Name());
       ReportError(cls, cls.token_pos(),
                   "typedef '%s' illegally refers to itself",
@@ -2276,26 +2330,22 @@
     }
     cls.set_is_type_finalized();
 
-    // The type parameters of signature classes may have bounds.
-    FinalizeUpperBounds(cls);
-
     // Resolve and finalize the result and parameter types of the signature
-    // function of this signature class.
-    const Function& sig_function = Function::Handle(cls.signature_function());
-    ResolveAndFinalizeSignature(cls, sig_function);
+    // function of this typedef class.
+    FinalizeSignature(cls, signature);  // Does not modify signature type.
+    ASSERT(signature.SignatureType() == type.raw());
 
-    // Resolve and finalize the signature type of this signature class.
-    const Type& sig_type = Type::Handle(cls.SignatureType());
-    FinalizeType(cls, sig_type, kCanonicalizeWellFormed);
+    // Resolve and finalize the signature type of this typedef.
+    type ^= FinalizeType(cls, type, kCanonicalizeWellFormed);
+    signature.SetSignatureType(type);
 
-    // Add this class to the subclasses of the superclass (_FunctionImpl).
-    if (!super_type.IsNull()) {
-      ASSERT(!super_type.IsObjectType());
-      ASSERT(!super_class.IsNull());
-      super_class.AddDirectSubclass(cls);
-    }
+    // Closure instances do not refer to this typedef as their class, so there
+    // is no need to add this typedef class to the subclasses of _Closure.
+    ASSERT(super_type.IsNull() || super_type.IsObjectType());
+
     return;
   }
+
   // Finalize interface types (but not necessarily interface classes).
   Array& interface_types = Array::Handle(cls.interfaces());
   AbstractType& interface_type = AbstractType::Handle();
@@ -2332,9 +2382,6 @@
   // Mark as type finalized before resolving type parameter upper bounds
   // in order to break cycles.
   cls.set_is_type_finalized();
-  // Finalize bounds even if running in production mode, so that a snapshot
-  // contains them.
-  FinalizeUpperBounds(cls);
   // Add this class to the direct subclasses of the superclass, unless the
   // superclass is Object.
   if (!super_type.IsNull() && !super_type.IsObjectType()) {
@@ -2401,9 +2448,9 @@
     cls.SetFunctions(functions);
   }
   // Every class should have at least a constructor, unless it is a top level
-  // class or a signature class.
+  // class or a typedef class.
   ASSERT(cls.IsTopLevel() ||
-         cls.IsSignatureClass() ||
+         cls.IsTypedefClass() ||
          (Array::Handle(cls.functions()).Length() > 0));
   // Resolve and finalize all member types.
   ResolveAndFinalizeMemberTypes(cls);
@@ -2494,82 +2541,74 @@
 }
 
 
-// Helper function called by IsAliasCycleFree.
-bool ClassFinalizer::IsTypeCycleFree(
-    const Class& cls,
-    const AbstractType& type,
-    GrowableArray<intptr_t>* visited) {
+// Returns false if a function type alias illegally refers to itself.
+bool ClassFinalizer::IsTypedefCycleFree(const Class& cls,
+                                        const AbstractType& type,
+                                        GrowableArray<intptr_t>* visited) {
   ASSERT(visited != NULL);
-  ResolveType(cls, type);
-  if (type.IsType() && !type.IsMalformed()) {
-    const Class& type_class = Class::Handle(type.type_class());
-    if (!type_class.is_type_finalized() &&
-        type_class.IsSignatureClass() &&
-        !IsAliasCycleFree(type_class, visited)) {
-      return false;
-    }
-    const TypeArguments& type_args = TypeArguments::Handle(type.arguments());
-    if (!type_args.IsNull()) {
-      AbstractType& type_arg = AbstractType::Handle();
-      for (intptr_t i = 0; i < type_args.Length(); i++) {
-        type_arg = type_args.TypeAt(i);
-        if (!IsTypeCycleFree(cls, type_arg, visited)) {
+  AbstractType& resolved_type = AbstractType::Handle(ResolveType(cls, type));
+  bool checking_typedef = false;
+  if ((resolved_type.IsType() || resolved_type.IsFunctionType()) &&
+      !resolved_type.IsMalformed()) {
+    AbstractType& other_type = AbstractType::Handle();
+    if (resolved_type.IsFunctionType()) {
+      const Class& scope_class = Class::Handle(resolved_type.type_class());
+      if (!scope_class.is_type_finalized() && scope_class.IsTypedefClass()) {
+        checking_typedef = true;
+        const intptr_t scope_class_id = scope_class.id();
+        ASSERT(visited != NULL);
+        for (intptr_t i = 0; i < visited->length(); i++) {
+          if ((*visited)[i] == scope_class_id) {
+            // We have already visited alias 'scope_class'. We found a cycle.
+            return false;
+          }
+        }
+        visited->Add(scope_class_id);
+      }
+      // Check the bounds of this function type.
+      const intptr_t num_type_params = scope_class.NumTypeParameters();
+      TypeParameter& type_param = TypeParameter::Handle();
+      const TypeArguments& type_params =
+          TypeArguments::Handle(scope_class.type_parameters());
+      ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
+             (type_params.Length() == num_type_params));
+      for (intptr_t i = 0; i < num_type_params; i++) {
+        type_param ^= type_params.TypeAt(i);
+        other_type = type_param.bound();
+        if (!IsTypedefCycleFree(cls, other_type, visited)) {
+          return false;
+        }
+      }
+      // Check the result type of the signature of this function type.
+      const Function& function =
+          Function::Handle(FunctionType::Cast(resolved_type).signature());
+      other_type = function.result_type();
+      if (!IsTypedefCycleFree(cls, other_type, visited)) {
+        return false;
+      }
+      // Check the parameter types of the signature of this function type.
+      const intptr_t num_parameters = function.NumParameters();
+      for (intptr_t i = 0; i < num_parameters; i++) {
+        other_type = function.ParameterTypeAt(i);
+        if (!IsTypedefCycleFree(cls, other_type, visited)) {
           return false;
         }
       }
     }
-  }
-  return true;
-}
-
-
-// Returns false if the function type alias illegally refers to itself.
-bool ClassFinalizer::IsAliasCycleFree(const Class& cls,
-                                      GrowableArray<intptr_t>* visited) {
-  ASSERT(cls.IsSignatureClass());
-  ASSERT(!cls.is_type_finalized());
-  ASSERT(visited != NULL);
-  const intptr_t cls_index = cls.id();
-  for (intptr_t i = 0; i < visited->length(); i++) {
-    if ((*visited)[i] == cls_index) {
-      // We have already visited alias 'cls'. We found a cycle.
-      return false;
+    const TypeArguments& type_args =
+        TypeArguments::Handle(resolved_type.arguments());
+    if (!type_args.IsNull()) {
+      for (intptr_t i = 0; i < type_args.Length(); i++) {
+        other_type = type_args.TypeAt(i);
+        if (!IsTypedefCycleFree(cls, other_type, visited)) {
+          return false;
+        }
+      }
+    }
+    if (checking_typedef) {
+      visited->RemoveLast();
     }
   }
-
-  // Visit the bounds, result type, and parameter types of this signature type.
-  visited->Add(cls.id());
-  AbstractType& type = AbstractType::Handle();
-
-  // Check the bounds of this signature type.
-  const intptr_t num_type_params = cls.NumTypeParameters();
-  TypeParameter& type_param = TypeParameter::Handle();
-  const TypeArguments& type_params =
-      TypeArguments::Handle(cls.type_parameters());
-  ASSERT((type_params.IsNull() && (num_type_params == 0)) ||
-         (type_params.Length() == num_type_params));
-  for (intptr_t i = 0; i < num_type_params; i++) {
-    type_param ^= type_params.TypeAt(i);
-    type = type_param.bound();
-    if (!IsTypeCycleFree(cls, type, visited)) {
-      return false;
-    }
-  }
-  // Check the result type of the function of this signature type.
-  const Function& function = Function::Handle(cls.signature_function());
-  type = function.result_type();
-  if (!IsTypeCycleFree(cls, type, visited)) {
-    return false;
-  }
-  // Check the formal parameter types of the function of this signature type.
-  const intptr_t num_parameters = function.NumParameters();
-  for (intptr_t i = 0; i < num_parameters; i++) {
-    type = function.ParameterTypeAt(i);
-    if (!IsTypeCycleFree(cls, type, visited)) {
-      return false;
-    }
-  }
-  visited->RemoveLast();
   return true;
 }
 
@@ -2657,8 +2696,16 @@
       GrowableObjectArray::Handle(zone, GrowableObjectArray::New());
   AbstractType& mixin_super_type =
       AbstractType::Handle(zone, mixin_app_type.super_type());
-  ResolveType(cls, mixin_super_type);
+  mixin_super_type = ResolveType(cls, mixin_super_type);
   ASSERT(mixin_super_type.HasResolvedTypeClass());  // Even if malformed.
+  if (mixin_super_type.IsMalformedOrMalbounded()) {
+    ReportError(Error::Handle(zone, mixin_super_type.error()));
+  }
+  if (mixin_super_type.IsDynamicType()) {
+    ReportError(cls, cls.token_pos(),
+                "class '%s' may not extend 'dynamic'",
+                String::Handle(zone, cls.Name()).ToCString());
+  }
   // The super type may have a BoundedType as type argument, but cannot be
   // a BoundedType itself.
   CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
@@ -2673,7 +2720,7 @@
   for (intptr_t i = 0; i < depth; i++) {
     mixin_type = mixin_app_type.MixinTypeAt(i);
     ASSERT(!mixin_type.IsNull());
-    ResolveType(cls, mixin_type);
+    mixin_type = ResolveType(cls, mixin_type);
     ASSERT(mixin_type.HasResolvedTypeClass());  // Even if malformed.
     ASSERT(mixin_type.IsType());
     const intptr_t num_super_type_args = type_args.Length();
@@ -2834,7 +2881,7 @@
   Class& interface_class = Class::Handle(zone);
 
   // Resolve super type. Failures lead to a longjmp.
-  ResolveType(cls, super_type);
+  super_type = ResolveType(cls, super_type);
   if (super_type.IsMalformedOrMalbounded()) {
     ReportError(Error::Handle(zone, super_type.error()));
   }
@@ -2844,7 +2891,7 @@
                 String::Handle(zone, cls.Name()).ToCString());
   }
   interface_class = super_type.type_class();
-  if (interface_class.IsSignatureClass()) {
+  if (interface_class.IsTypedefClass()) {
     ReportError(cls, cls.token_pos(),
                 "class '%s' may not extend function type alias '%s'",
                 String::Handle(zone, cls.Name()).ToCString(),
@@ -2914,7 +2961,7 @@
   // Resolve interfaces. Failures lead to a longjmp.
   for (intptr_t i = 0; i < super_interfaces.Length(); i++) {
     interface ^= super_interfaces.At(i);
-    ResolveType(cls, interface);
+    interface = ResolveType(cls, interface);
     ASSERT(!interface.IsTypeParameter());  // Should be detected by parser.
     // A malbounded interface is only reported when involved in a type test.
     if (interface.IsMalformed()) {
@@ -2925,7 +2972,7 @@
                   "'dynamic' may not be used as interface");
     }
     interface_class = interface.type_class();
-    if (interface_class.IsSignatureClass()) {
+    if (interface_class.IsTypedefClass()) {
       const String& interface_name = String::Handle(zone,
                                                     interface_class.Name());
       ReportError(cls, cls.token_pos(),
@@ -3048,7 +3095,7 @@
                                        va_list args) {
   LanguageError& error = LanguageError::Handle(
       LanguageError::NewFormattedV(
-          prev_error, script, type.token_pos(),
+          prev_error, script, type.token_pos(), Report::AtLocation,
           Report::kMalformedType, Heap::kOld,
           format, args));
   if (Isolate::Current()->flags().error_on_bad_type()) {
@@ -3061,7 +3108,7 @@
   type.set_arguments(Object::null_type_arguments());
   if (!type.IsFinalized()) {
     type.SetIsFinalized();
-    // Do not canonicalize malformed types, since they may not be resolved.
+    // Do not canonicalize malformed types, since they contain an error field.
   } else {
     // The only case where the malformed type was already finalized is when its
     // type arguments are not within bounds. In that case, we have a prev_error.
@@ -3103,13 +3150,13 @@
 
 void ClassFinalizer::FinalizeMalboundedType(const Error& prev_error,
                                             const Script& script,
-                                            const Type& type,
+                                            const AbstractType& type,
                                             const char* format, ...) {
   va_list args;
   va_start(args, format);
   LanguageError& error = LanguageError::Handle(
       LanguageError::NewFormattedV(
-          prev_error, script, type.token_pos(),
+          prev_error, script, type.token_pos(), Report::AtLocation,
           Report::kMalboundedType, Heap::kOld,
           format, args));
   va_end(args);
@@ -3149,7 +3196,8 @@
   va_list args;
   va_start(args, format);
   const Script& script = Script::Handle(cls.script());
-  Report::MessageV(Report::kError, script, token_pos, format, args);
+  Report::MessageV(Report::kError,
+                   script, token_pos, Report::AtLocation, format, args);
   va_end(args);
   UNREACHABLE();
 }
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index 3aa7c2c..a8c59a2 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -60,7 +60,7 @@
   // string and its arguments.
   static void FinalizeMalboundedType(const Error& prev_error,
                                      const Script& script,
-                                     const Type& type,
+                                     const AbstractType& type,
                                      const char* format, ...)
        PRINTF_ATTRIBUTE(4, 5);
 
@@ -89,7 +89,8 @@
 #endif  // defined(DART_NO_SNAPSHOT).
 
   // Resolve the class of the type, but not the type's type arguments.
-  static void ResolveTypeClass(const Class& cls, const AbstractType& type);
+  // May promote the type from Type to FunctionType.
+  static RawAbstractType* ResolveTypeClass(const Class& cls, const Type& type);
 
   // Resolve the type and target of the redirecting factory.
   static void ResolveRedirectingFactory(const Class& cls,
@@ -102,17 +103,16 @@
  private:
   static void AllocateEnumValues(const Class& enum_cls);
   static bool IsSuperCycleFree(const Class& cls);
-  static bool IsTypeCycleFree(const Class& cls,
-                              const AbstractType& type,
-                              GrowableArray<intptr_t>* visited);
-  static bool IsAliasCycleFree(const Class& cls,
-                               GrowableArray<intptr_t>* visited);
+  static bool IsTypedefCycleFree(const Class& cls,
+                                 const AbstractType& type,
+                                 GrowableArray<intptr_t>* visited);
   static bool IsMixinCycleFree(const Class& cls,
                                GrowableArray<intptr_t>* visited);
   static void CheckForLegalConstClass(const Class& cls);
   static RawClass* ResolveClass(const Class& cls,
                                 const UnresolvedClass& unresolved_class);
-  static void ResolveType(const Class& cls, const AbstractType& type);
+  static RawAbstractType* ResolveType(const Class& cls,
+                                      const AbstractType& type);
   static void ResolveRedirectingFactoryTarget(
       const Class& cls,
       const Function& factory,
@@ -134,6 +134,9 @@
                                             GrowableArray<intptr_t>* visited);
   static void FinalizeTypeParameters(const Class& cls,
                                      PendingTypes* pending_types = NULL);
+  static intptr_t ExpandAndFinalizeTypeArguments(const Class& cls,
+                                                 const AbstractType& type,
+                                                 PendingTypes* pending_types);
   static void FinalizeTypeArguments(const Class& cls,
                                     const TypeArguments& arguments,
                                     intptr_t num_uninitialized_arguments,
@@ -141,16 +144,16 @@
                                     PendingTypes* pending_types,
                                     TrailPtr trail);
   static void CheckRecursiveType(const Class& cls,
-                                 const Type& type,
+                                 const AbstractType& type,
                                  PendingTypes* pending_types);
-  static void CheckTypeBounds(const Class& cls, const Type& type);
+  static void CheckTypeBounds(const Class& cls, const AbstractType& type);
   static void CheckTypeArgumentBounds(const Class& cls,
                                       const TypeArguments& arguments,
                                       Error* bound_error);
   static void ResolveUpperBounds(const Class& cls);
   static void FinalizeUpperBounds(const Class& cls);
-  static void ResolveAndFinalizeSignature(const Class& cls,
-                                          const Function& function);
+  static void ResolveSignature(const Class& cls, const Function& function);
+  static void FinalizeSignature(const Class& cls, const Function& function);
   static void ResolveAndFinalizeMemberTypes(const Class& cls);
   static void PrintClassInformation(const Class& cls);
   static void CollectInterfaces(
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 828ecac..2c87c9c 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -14,7 +14,7 @@
   const String& class_name = String::Handle(Symbols::New(name));
   const Script& script = Script::Handle();
   const Class& cls =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   cls.set_interfaces(Object::empty_array());
   cls.SetFunctions(Object::empty_array());
   cls.SetFields(Object::empty_array());
@@ -96,12 +96,12 @@
   const UnresolvedClass& unresolved = UnresolvedClass::Handle(
       UnresolvedClass::New(LibraryPrefix::Handle(),
                            superclass_name,
-                           Scanner::kNoSourcePos));
+                           Token::kNoSourcePos));
   const TypeArguments& type_arguments = TypeArguments::Handle();
   rhb.set_super_type(Type::Handle(
       Type::New(Object::Handle(unresolved.raw()),
                 type_arguments,
-                Scanner::kNoSourcePos)));
+                Token::kNoSourcePos)));
   EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index adc7853..ac4cb24 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/code_descriptors.h"
+#include "vm/compiler.h"
 
 namespace dart {
 
@@ -15,25 +16,47 @@
          (kind == RawPcDescriptors::kOther) ||
          (deopt_id != Thread::kNoDeoptId));
 
-  intptr_t merged_kind_try =
-      RawPcDescriptors::MergedKindTry::Encode(kind, try_index);
+  // When precompiling, we only use pc descriptors for exceptions.
+  if (Compiler::allow_recompilation() || try_index != -1) {
+    intptr_t merged_kind_try =
+        RawPcDescriptors::MergedKindTry::Encode(kind, try_index);
 
-  PcDescriptors::EncodeInteger(&encoded_data_, merged_kind_try);
-  PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
-  PcDescriptors::EncodeInteger(&encoded_data_, deopt_id - prev_deopt_id);
-  PcDescriptors::EncodeInteger(&encoded_data_, token_pos - prev_token_pos);
+    PcDescriptors::EncodeInteger(&encoded_data_, merged_kind_try);
+    PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
+    PcDescriptors::EncodeInteger(&encoded_data_, deopt_id - prev_deopt_id);
+    PcDescriptors::EncodeInteger(&encoded_data_, token_pos - prev_token_pos);
 
-  prev_pc_offset = pc_offset;
-  prev_deopt_id = deopt_id;
-  prev_token_pos = token_pos;
+    prev_pc_offset = pc_offset;
+    prev_deopt_id = deopt_id;
+    prev_token_pos = token_pos;
+  }
 }
 
 
 RawPcDescriptors* DescriptorList::FinalizePcDescriptors(uword entry_point) {
+  if (encoded_data_.length() == 0) {
+    return Object::empty_descriptors().raw();
+  }
   return PcDescriptors::New(&encoded_data_);
 }
 
 
+
+void CodeSourceMapBuilder::AddEntry(intptr_t pc_offset,
+                                    intptr_t token_pos) {
+  CodeSourceMap::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
+  CodeSourceMap::EncodeInteger(&encoded_data_, token_pos - prev_token_pos);
+
+  prev_pc_offset = pc_offset;
+  prev_token_pos = token_pos;
+}
+
+
+RawCodeSourceMap* CodeSourceMapBuilder::Finalize() {
+  return CodeSourceMap::New(&encoded_data_);
+}
+
+
 void StackmapTableBuilder::AddEntry(intptr_t pc_offset,
                                     BitmapBuilder* bitmap,
                                     intptr_t register_bit_count) {
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index e24e186..11e3437 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -42,6 +42,29 @@
 };
 
 
+class CodeSourceMapBuilder : public ZoneAllocated {
+ public:
+  explicit CodeSourceMapBuilder(intptr_t initial_capacity = 64)
+    : encoded_data_(initial_capacity),
+      prev_pc_offset(0),
+      prev_token_pos(0) {}
+
+  ~CodeSourceMapBuilder() { }
+
+  void AddEntry(intptr_t pc_offset, intptr_t token_pos);
+
+  RawCodeSourceMap* Finalize();
+
+ private:
+  GrowableArray<uint8_t> encoded_data_;
+
+  intptr_t prev_pc_offset;
+  intptr_t prev_token_pos;
+
+  DISALLOW_COPY_AND_ASSIGN(CodeSourceMapBuilder);
+};
+
+
 class StackmapTableBuilder : public ZoneAllocated {
  public:
   StackmapTableBuilder()
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 2586a97..30cedd4 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -18,7 +18,7 @@
 
 namespace dart {
 
-static const intptr_t kPos = Scanner::kNoSourcePos;
+static const intptr_t kPos = Token::kNoSourcePos;
 
 
 CODEGEN_TEST_GENERATE(StackmapCodegen, test) {
@@ -268,4 +268,100 @@
   EXPECT(!result.IsError());
 }
 
+
+TEST_CASE(DescriptorList_TokenPositions) {
+  DescriptorList* descriptors = new DescriptorList(64);
+  ASSERT(descriptors != NULL);
+  const intptr_t token_positions[] = {
+    kMinInt32,
+    5,
+    13,
+    13,
+    13,
+    13,
+    31,
+    23,
+    23,
+    23,
+    33,
+    33,
+    5,
+    5,
+    Token::kMinSourcePos,
+    Token::kMaxSourcePos,
+  };
+  const intptr_t num_token_positions =
+      sizeof(token_positions) / sizeof(token_positions[0]);
+
+  for (intptr_t i = 0; i < num_token_positions; i++) {
+    descriptors->AddDescriptor(RawPcDescriptors::kRuntimeCall, 0, 0,
+                               token_positions[i], 0);
+  }
+
+  const PcDescriptors& finalized_descriptors =
+      PcDescriptors::Handle(descriptors->FinalizePcDescriptors(0));
+
+  ASSERT(!finalized_descriptors.IsNull());
+  PcDescriptors::Iterator it(finalized_descriptors,
+                             RawPcDescriptors::kRuntimeCall);
+
+  intptr_t i = 0;
+  while (it.MoveNext()) {
+    if (token_positions[i] != it.TokenPos()) {
+      OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
+                i, token_positions[i], it.TokenPos());
+    }
+    EXPECT(token_positions[i] == it.TokenPos());
+    i++;
+  }
+}
+
+
+TEST_CASE(CodeSourceMap_TokenPositions) {
+  const intptr_t token_positions[] = {
+    kMinInt32,
+    5,
+    13,
+    13,
+    13,
+    13,
+    31,
+    23,
+    23,
+    23,
+    33,
+    33,
+    5,
+    5,
+    Token::kMinSourcePos,
+    Token::kMaxSourcePos,
+  };
+  const intptr_t num_token_positions =
+      sizeof(token_positions) / sizeof(token_positions[0]);
+
+  CodeSourceMapBuilder* builder = new CodeSourceMapBuilder();
+  ASSERT(builder != NULL);
+
+  for (intptr_t i = 0; i < num_token_positions; i++) {
+    builder->AddEntry(i, token_positions[i]);
+  }
+
+  const CodeSourceMap& code_Source_map =
+      CodeSourceMap::Handle(builder->Finalize());
+
+  ASSERT(!code_Source_map.IsNull());
+  CodeSourceMap::Iterator it(code_Source_map);
+
+  uintptr_t i = 0;
+  while (it.MoveNext()) {
+    EXPECT(it.PcOffset() == i);
+    if (token_positions[i] != it.TokenPos()) {
+      OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
+                i, token_positions[i], it.TokenPos());
+    }
+    EXPECT(token_positions[i] == it.TokenPos());
+    i++;
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index d7c92d7..d0cdd74e 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -204,7 +204,7 @@
   ASSERT(!type.IsNull() && !type.IsInstantiated());
   ASSERT(instantiator.IsNull() || instantiator.IsInstantiated());
   Error& bound_error = Error::Handle();
-  type = type.InstantiateFrom(instantiator, &bound_error);
+  type = type.InstantiateFrom(instantiator, &bound_error, NULL, Heap::kOld);
   if (!bound_error.IsNull()) {
     // Throw a dynamic type error.
     const intptr_t location = GetCallerLocation();
@@ -300,7 +300,7 @@
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
 
-  const Type& instance_type = Type::Handle(instance.GetType());
+  const AbstractType& instance_type = AbstractType::Handle(instance.GetType());
   ASSERT(instance_type.IsInstantiated());
   if (type.IsInstantiated()) {
     OS::PrintErr("%s: '%s' %" Pd " %s '%s' %" Pd " (pc: %#" Px ").\n",
@@ -334,10 +334,10 @@
 
 
 // This updates the type test cache, an array containing 4-value elements
-// (instance class, instance type arguments, instantiator type arguments and
-// test_result). It can be applied to classes with type arguments in which
-// case it contains just the result of the class subtype test, not including
-// the evaluation of type arguments.
+// (instance class (or function if the instance is a closure), instance type
+// arguments, instantiator type arguments and test_result). It can be applied to
+// classes with type arguments in which case it contains just the result of the
+// class subtype test, not including the evaluation of type arguments.
 // This operation is currently very slow (lookup of code is not efficient yet).
 static void UpdateTypeTestCache(
     const Instance& instance,
@@ -360,11 +360,16 @@
     }
     return;
   }
-  TypeArguments& instance_type_arguments =
-      TypeArguments::Handle();
   const Class& instance_class = Class::Handle(instance.clazz());
-
-  if (instance_class.NumTypeArguments() > 0) {
+  Object& instance_class_id_or_function = Object::Handle();
+  if (instance_class.IsClosureClass()) {
+    instance_class_id_or_function = Closure::Cast(instance).function();
+  } else {
+    instance_class_id_or_function = Smi::New(instance_class.id());
+  }
+  TypeArguments& instance_type_arguments = TypeArguments::Handle();
+  if (instance_class.IsClosureClass() ||
+      (instance_class.NumTypeArguments() > 0)) {
     instance_type_arguments = instance.GetTypeArguments();
   }
 
@@ -377,20 +382,19 @@
          instance_type_arguments.IsCanonical());
   ASSERT(instantiator_type_arguments.IsNull() ||
          instantiator_type_arguments.IsCanonical());
-  intptr_t last_instance_class_id = -1;
-  TypeArguments& last_instance_type_arguments =
-      TypeArguments::Handle();
-  TypeArguments& last_instantiator_type_arguments =
-      TypeArguments::Handle();
+  Object& last_instance_class_id_or_function = Object::Handle();
+  TypeArguments& last_instance_type_arguments = TypeArguments::Handle();
+  TypeArguments& last_instantiator_type_arguments = TypeArguments::Handle();
   Bool& last_result = Bool::Handle();
   for (intptr_t i = 0; i < len; ++i) {
     new_cache.GetCheck(
         i,
-        &last_instance_class_id,
+        &last_instance_class_id_or_function,
         &last_instance_type_arguments,
         &last_instantiator_type_arguments,
         &last_result);
-    if ((last_instance_class_id == instance_class.id()) &&
+    if ((last_instance_class_id_or_function.raw() ==
+         instance_class_id_or_function.raw()) &&
         (last_instance_type_arguments.raw() == instance_type_arguments.raw()) &&
         (last_instantiator_type_arguments.raw() ==
          instantiator_type_arguments.raw())) {
@@ -402,7 +406,7 @@
     }
   }
 #endif
-  new_cache.AddCheck(instance_class.id(),
+  new_cache.AddCheck(instance_class_id_or_function,
                      instance_type_arguments,
                      instantiator_type_arguments,
                      result);
@@ -415,13 +419,13 @@
       ASSERT(bound_error.IsNull());  // Malbounded types are not optimized.
     }
     OS::PrintErr("  Updated test cache %p ix: %" Pd " with "
-        "(cid: %" Pd ", type-args: %p, instantiator: %p, result: %s)\n"
+        "(cid-or-fun: %p, type-args: %p, instantiator: %p, result: %s)\n"
         "    instance  [class: (%p '%s' cid: %" Pd "),    type-args: %p %s]\n"
         "    test-type [class: (%p '%s' cid: %" Pd "), in-type-args: %p %s]\n",
         new_cache.raw(),
         len,
 
-        instance_class.id(),
+        instance_class_id_or_function.raw(),
         instance_type_arguments.raw(),
         instantiator_type_arguments.raw(),
         result.ToCString(),
@@ -745,15 +749,8 @@
   if (getter.IsNull() || getter.IsMethodExtractor()) {
     return false;
   }
-  const Class& cache_class = Class::Handle(receiver_class.IsSignatureClass()
-      ? receiver_class.SuperClass()
-      : receiver_class.raw());
-  ASSERT(
-      !receiver_class.IsSignatureClass() ||
-      (receiver_class.SuperClass() == Type::Handle(
-       Isolate::Current()->object_store()->function_impl_type()).type_class()));
   const Function& target_function =
-      Function::Handle(cache_class.GetInvocationDispatcher(
+      Function::Handle(receiver_class.GetInvocationDispatcher(
           target_name,
           arguments_descriptor,
           RawFunction::kInvokeFieldDispatcher,
@@ -1223,15 +1220,14 @@
 // Arg1: arguments descriptor array.
 // Arg2: arguments array.
 DEFINE_RUNTIME_ENTRY(InvokeClosureNoSuchMethod, 3) {
-  const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0));
+  const Closure& receiver = Closure::CheckedHandle(arguments.ArgAt(0));
   const Array& orig_arguments_desc = Array::CheckedHandle(arguments.ArgAt(1));
   const Array& orig_arguments = Array::CheckedHandle(arguments.ArgAt(2));
 
   // For closure the function name is always 'call'. Replace it with the
   // name of the closurized function so that exception contains more
   // relevant information.
-  ASSERT(receiver.IsClosure());
-  const Function& function = Function::Handle(Closure::function(receiver));
+  const Function& function = Function::Handle(receiver.function());
   const String& original_function_name =
       String::Handle(function.QualifiedUserVisibleName());
   const Object& result = Object::Handle(
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index bb7008a..bd569fc 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -24,7 +24,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index f9a3f42..f7d741f 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -24,7 +24,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index a9c62f4..a8184bf 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -24,7 +24,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/code_patcher_mips_test.cc b/runtime/vm/code_patcher_mips_test.cc
index 78e698b..676a1b0 100644
--- a/runtime/vm/code_patcher_mips_test.cc
+++ b/runtime/vm/code_patcher_mips_test.cc
@@ -24,7 +24,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index ca98231..7d1f31d 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -24,7 +24,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 70d1ac6..7479506 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -80,7 +80,7 @@
 bool Compiler::always_optimize_ = false;
 bool Compiler::allow_recompilation_ = true;
 
-#ifndef DART_PRECOMPILED
+#ifndef DART_PRECOMPILED_RUNTIME
 
 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
 // separate helpers functions & `optimizing` args.
@@ -282,14 +282,13 @@
   if (cls.is_marked_for_parsing()) {
     return Error::null();
   }
-  // If the class is a signature class there is no need to try and
+  // If the class is a typedef class there is no need to try and
   // compile it. Just finalize it directly.
-  if (cls.IsSignatureClass()) {
+  if (cls.IsTypedefClass()) {
 #if defined(DEBUG)
-    const Type& type = Type::Handle(
-        Isolate::Current()->object_store()->function_impl_type());
-    const Class& type_cls = Class::Handle(type.type_class());
-    ASSERT(type_cls.is_finalized());
+    const Class& closure_cls = Class::Handle(
+        Isolate::Current()->object_store()->closure_class());
+    ASSERT(closure_cls.is_finalized());
 #endif
     LongJumpScope jump;
     if (setjmp(*jump.Set()) == 0) {
@@ -1341,8 +1340,7 @@
     CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id);
     const bool success = helper.Compile(pipeline);
     if (!success) {
-      if (optimized) {
-        ASSERT(!Compiler::always_optimize());  // Optimized is the only code.
+      if (optimized && !Compiler::always_optimize()) {
         // Optimizer bailed out. Disable optimizations and never try again.
         if (trace_compiler) {
           THR_Print("--> disabling optimizations for '%s'\n",
@@ -1359,6 +1357,8 @@
         // We got an error during compilation.
         error = isolate->object_store()->sticky_error();
         isolate->object_store()->clear_sticky_error();
+        ASSERT(error.IsLanguageError() &&
+               LanguageError::Cast(error).kind() != Report::kBailout);
         return error.raw();
       }
     }
@@ -1941,7 +1941,7 @@
 }
 
 
-#else  // DART_PRECOMPILED
+#else  // DART_PRECOMPILED_RUNTIME
 
 
 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
@@ -2046,6 +2046,6 @@
   UNREACHABLE();
 }
 
-#endif  // DART_PRECOMPILED
+#endif  // DART_PRECOMPILED_RUNTIME
 
 }  // namespace dart
diff --git a/runtime/vm/cpu_arm.cc b/runtime/vm/cpu_arm.cc
index 491468a..edaea94 100644
--- a/runtime/vm/cpu_arm.cc
+++ b/runtime/vm/cpu_arm.cc
@@ -56,12 +56,16 @@
 
 namespace dart {
 
-// TODO(zra): Add a target for ARMv6.
 #if defined(TARGET_ARCH_ARM_5TE)
 DEFINE_FLAG(bool, use_vfp, false, "Use vfp instructions if supported");
 DEFINE_FLAG(bool, use_neon, false, "Use neon instructions if supported");
 DEFINE_FLAG(bool, use_integer_division, false,
             "Use integer division instruction if supported");
+#elif defined(TARGET_ARCH_ARM_6)
+DEFINE_FLAG(bool, use_vfp, true, "Use vfp instructions if supported");
+DEFINE_FLAG(bool, use_neon, false, "Use neon instructions if supported");
+DEFINE_FLAG(bool, use_integer_division, false,
+            "Use integer division instruction if supported");
 #else
 DEFINE_FLAG(bool, use_vfp, true, "Use vfp instructions if supported");
 DEFINE_FLAG(bool, use_neon, true, "Use neon instructions if supported");
@@ -242,6 +246,8 @@
 
 #if defined(TARGET_ARCH_ARM_5TE)
   arm_version_ = ARMv5TE;
+#elif defined(TARGET_ARCH_ARM_6)
+  arm_version_ = ARMv6;
 #else
   arm_version_ = ARMv7;
 #endif
diff --git a/runtime/vm/cpuinfo.h b/runtime/vm/cpuinfo.h
index 3ccf2d4..cd1247e 100644
--- a/runtime/vm/cpuinfo.h
+++ b/runtime/vm/cpuinfo.h
@@ -61,7 +61,7 @@
     if (HasField(FieldName(kCpuInfoHardware))) {
       return ExtractField(kCpuInfoHardware);
     } else {
-      return "";
+      return strdup("Unknown");
     }
   }
 
diff --git a/runtime/vm/cpuinfo_linux.cc b/runtime/vm/cpuinfo_linux.cc
index 0341530..e58bac1 100644
--- a/runtime/vm/cpuinfo_linux.cc
+++ b/runtime/vm/cpuinfo_linux.cc
@@ -28,14 +28,20 @@
   fields_[kCpuInfoFeatures] = "flags";
   method_ = kCpuInfoCpuId;
   CpuId::InitOnce();
-#elif defined(HOST_ARCH_ARM) || defined(HOST_ARCH_ARM64)
-  // TODO(zra): Verify that these field names are correct for arm64.
+#elif defined(HOST_ARCH_ARM)
   fields_[kCpuInfoProcessor] = "Processor";
   fields_[kCpuInfoModel] = "model name";
   fields_[kCpuInfoHardware] = "Hardware";
   fields_[kCpuInfoFeatures] = "Features";
   method_ = kCpuInfoSystem;
   ProcCpuInfo::InitOnce();
+#elif defined(HOST_ARCH_ARM64)
+  fields_[kCpuInfoProcessor] = "Processor";
+  fields_[kCpuInfoModel] = "CPU implementer";
+  fields_[kCpuInfoHardware] = "CPU implementer";
+  fields_[kCpuInfoFeatures] = "Features";
+  method_ = kCpuInfoSystem;
+  ProcCpuInfo::InitOnce();
 #elif defined(HOST_ARCH_MIPS)
   fields_[kCpuInfoProcessor] = "system type";
   fields_[kCpuInfoModel] = "cpu model";
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 796aaca..d316138 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -77,7 +77,6 @@
   }
 }
 
-#if 0
 #define API_TIMELINE_DURATION                                                  \
   TimelineDurationScope tds(Thread::Current(),                                 \
                             Timeline::GetVMApiStream(),                        \
@@ -87,10 +86,7 @@
   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
@@ -111,7 +107,7 @@
       // Verify that the result type of a function is canonical or a
       // TypeParameter.
       typeHandle_ ^= funcHandle_.result_type();
-      ASSERT(typeHandle_.IsNull() ||
+      ASSERT(typeHandle_.IsMalformed() ||
              !typeHandle_.IsResolved() ||
              typeHandle_.IsTypeParameter() ||
              typeHandle_.IsCanonical());
@@ -120,8 +116,9 @@
       const intptr_t num_parameters = funcHandle_.NumParameters();
       for (intptr_t i = 0; i < num_parameters; i++) {
         typeHandle_ = funcHandle_.ParameterTypeAt(i);
-        ASSERT(typeHandle_.IsTypeParameter() ||
+        ASSERT(typeHandle_.IsMalformed() ||
                !typeHandle_.IsResolved() ||
+               typeHandle_.IsTypeParameter() ||
                typeHandle_.IsCanonical());
       }
     }
@@ -1858,14 +1855,7 @@
 
 
 DART_EXPORT bool Dart_IsClosure(Dart_Handle object) {
-  // We can't use a fast class index check here because there are many
-  // different signature classes for closures.
-  Thread* thread = Thread::Current();
-  CHECK_ISOLATE(thread->isolate());
-  ReusableObjectHandleScope reused_obj_handle(thread);
-  const Instance& closure_obj =
-      Api::UnwrapInstanceHandle(reused_obj_handle, object);
-  return (!closure_obj.IsNull() && closure_obj.IsClosure());
+  return Api::ClassId(object) == kClosureCid;
 }
 
 
@@ -1917,7 +1907,8 @@
   if (!obj.IsInstance()) {
     RETURN_TYPE_ERROR(Z, instance, Instance);
   }
-  const Type& type = Type::Handle(Instance::Cast(obj).GetType());
+  const AbstractType& type =
+      AbstractType::Handle(Instance::Cast(obj).GetType());
   return Api::NewHandle(T, type.Canonicalize());
 }
 
@@ -3888,7 +3879,7 @@
 
   // Construct name of the constructor to invoke.
   const String& constructor_name = Api::UnwrapStringHandle(Z, name);
-  const Type& type_obj = Type::Handle(Z, instance.GetType());
+  const AbstractType& type_obj = AbstractType::Handle(Z, instance.GetType());
   const Class& cls = Class::Handle(Z, type_obj.type_class());
   const String& class_name = String::Handle(Z, cls.Name());
   const Array& strings = Array::Handle(Z, Array::New(3));
@@ -5135,7 +5126,7 @@
 
   // Construct the type object, canonicalize it and return.
   Type& instantiated_type = Type::Handle(
-      Type::New(cls, type_args_obj, Scanner::kNoSourcePos));
+      Type::New(cls, type_args_obj, Token::kNoSourcePos));
   instantiated_type ^= ClassFinalizer::FinalizeType(
       cls, instantiated_type, ClassFinalizer::kCanonicalize);
   return Api::NewHandle(T, instantiated_type.raw());
@@ -5882,7 +5873,7 @@
 }
 
 
-#if defined(DART_PRECOMPILED)
+#if defined(DART_PRECOMPILED_RUNTIME)
 
 DART_EXPORT Dart_Handle Dart_Precompile(
     Dart_QualifiedFunctionName entry_points[],
@@ -5903,7 +5894,7 @@
   return 0;
 }
 
-#else  // DART_PRECOMPILED
+#else  // DART_PRECOMPILED_RUNTIME
 
 DART_EXPORT Dart_Handle Dart_Precompile(
     Dart_QualifiedFunctionName entry_points[],
@@ -5977,7 +5968,7 @@
 
   return Api::Success();
 }
-#endif  // DART_PRECOMPILED
+#endif  // DART_PRECOMPILED_RUNTIME
 
 
 DART_EXPORT bool Dart_IsRunningPrecompiledCode() {
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index a2cf1d3..8a40a7a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6762,9 +6762,9 @@
 TEST_CASE(SetNativeResolver) {
   const char* kScriptChars =
       "class Test {"
-      "  static foo() native \"SomeNativeFunction\";"
-      "  static bar() native \"SomeNativeFunction2\";"
-      "  static baz() native \"SomeNativeFunction3\";"
+      "  static foo() native \"SomeNativeFunction\";\n"
+      "  static bar() native \"SomeNativeFunction2\";\n"
+      "  static baz() native \"SomeNativeFunction3\";\n"
       "}";
   Dart_Handle error = Dart_NewApiError("incoming error");
   Dart_Handle result;
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index abb3e5d..3a53dcc 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -192,7 +192,12 @@
         ASSERT(getter_result.IsNull() || getter_result.IsInstance());
 
         arguments.SetAt(0, getter_result);
-        return InvokeClosure(arguments, arguments_descriptor);
+        // This otherwise unnecessary handle is used to prevent clang from
+        // doing tail call elimination, which would make the stack overflow
+        // check above ineffective.
+        Object& result = Object::Handle(InvokeClosure(arguments,
+                                                      arguments_descriptor));
+        return result.raw();
       }
       cls = cls.SuperClass();
     }
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index c533e3b..1b3d84a 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -84,7 +84,7 @@
       line_number_(-1),
       column_number_(-1) {
   ASSERT(!script.IsNull());
-  ASSERT(token_pos_ >= 0);
+  ASSERT(Token::IsReal(token_pos_));
 }
 
 // Create a latent breakpoint at given url and line number.
@@ -93,8 +93,8 @@
                                        intptr_t requested_column_number)
     : script_(Script::null()),
       url_(url.raw()),
-      token_pos_(Scanner::kNoSourcePos),
-      end_token_pos_(Scanner::kNoSourcePos),
+      token_pos_(Token::kNoSourcePos),
+      end_token_pos_(Token::kNoSourcePos),
       is_resolved_(false),
       next_(NULL),
       conditions_(NULL),
@@ -239,7 +239,7 @@
       code_(Code::ZoneHandle(code.raw())),
       function_(Function::ZoneHandle(code.function())),
       token_pos_initialized_(false),
-      token_pos_(Scanner::kNoSourcePos),
+      token_pos_(Token::kNoSourcePos),
       try_index_(-1),
       line_number_(-1),
       column_number_(-1),
@@ -566,7 +566,7 @@
 intptr_t ActivationFrame::TokenPos() {
   if (!token_pos_initialized_) {
     token_pos_initialized_ = true;
-    token_pos_ = Scanner::kNoSourcePos;
+    token_pos_ = Token::kNoSourcePos;
     GetPcDescriptors();
     PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
     uword pc_offset = pc_ - code().EntryPoint();
@@ -592,9 +592,10 @@
 
 intptr_t ActivationFrame::LineNumber() {
   // Compute line number lazily since it causes scanning of the script.
-  if ((line_number_ < 0) && (TokenPos() >= 0)) {
+  if ((line_number_ < 0) && Token::IsReal(TokenPos())) {
+    const intptr_t token_pos = TokenPos();
     const Script& script = Script::Handle(SourceScript());
-    script.GetTokenLocation(TokenPos(), &line_number_, NULL);
+    script.GetTokenLocation(token_pos, &line_number_, NULL);
   }
   return line_number_;
 }
@@ -602,10 +603,11 @@
 
 intptr_t ActivationFrame::ColumnNumber() {
   // Compute column number lazily since it causes scanning of the script.
-  if ((column_number_ < 0) && (TokenPos() >= 0)) {
+  if ((column_number_ < 0) && Token::IsReal(TokenPos())) {
+    const intptr_t token_pos = TokenPos();
     const Script& script = Script::Handle(SourceScript());
     if (script.HasSource()) {
-      script.GetTokenLocation(TokenPos(), &line_number_, &column_number_);
+      script.GetTokenLocation(token_pos, &line_number_, &column_number_);
     } else {
       column_number_ = -1;
     }
@@ -654,7 +656,7 @@
     ASSERT(!pc_desc_.IsNull());
     intptr_t innermost_begin_pos = 0;
     intptr_t activation_token_pos = TokenPos();
-    ASSERT(activation_token_pos >= 0);
+    ASSERT(Token::IsReal(activation_token_pos));
     GetVarDescriptors();
     intptr_t var_desc_len = var_descriptors_.Length();
     for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
@@ -767,7 +769,7 @@
   GetVarDescriptors();
 
   intptr_t activation_token_pos = TokenPos();
-  if (activation_token_pos < 0) {
+  if (!Token::IsDebugPause(activation_token_pos)) {
     // We don't have a token position for this frame, so can't determine
     // which variables are visible.
     vars_initialized_ = true;
@@ -1256,6 +1258,7 @@
       obj_cache_(NULL),
       stack_trace_(NULL),
       stepping_fp_(0),
+      skip_next_step_(false),
       exc_pause_info_(kNoPauseOnExceptions) {
 }
 
@@ -1626,7 +1629,6 @@
   // interested in exception events.
   if (ignore_breakpoints_ ||
       IsPaused() ||
-      (!HasDebugEventHandler()) ||
       (exc_pause_info_ == kNoPauseOnExceptions)) {
     return;
   }
@@ -1675,8 +1677,8 @@
 // and:
 //   - has the lowest token position number which satisfies the above.
 //
-// When we consider a column number, we look for the closed token
-// which intersects the desired column.  For example:
+// When we consider a column number, we look for the token which
+// intersects the desired column.  For example:
 //
 //          1         2         3
 // 12345678901234567890         0
@@ -1740,7 +1742,7 @@
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
     const intptr_t pos = iter.TokenPos();
-    if ((pos < 0) ||
+    if ((!Token::IsReal(pos)) ||
         (pos < requested_token_pos) ||
         (pos > last_token_pos)) {
       // Token is not in the target range.
@@ -1786,7 +1788,7 @@
     PcDescriptors::Iterator iter(desc, kSafepointKind);
     while (iter.MoveNext()) {
       const intptr_t pos = iter.TokenPos();
-      if ((pos < 0) ||
+      if ((!Token::IsReal(pos)) ||
           (pos < begin_pos) ||
           (pos > end_of_line_pos)) {
         // Token is not on same line as best fit.
@@ -1821,13 +1823,13 @@
     return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(),
                                 -1 /* no column */);
   }
-  return -1;
+  return Token::kNoSourcePos;
 }
 
 
 void Debugger::MakeCodeBreakpointAt(const Function& func,
                                     BreakpointLocation* loc) {
-  ASSERT(loc->token_pos_ >= 0);
+  ASSERT(Token::IsReal(loc->token_pos_));
   ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
   Code& code = Code::Handle(func.unoptimized_code());
@@ -2144,7 +2146,7 @@
   if (!closure.IsClosure()) {
     return NULL;
   }
-  const Function& func = Function::Handle(Closure::function(closure));
+  const Function& func = Function::Handle(Closure::Cast(closure).function());
   const Script& script = Script::Handle(func.script());
   BreakpointLocation* bpt_location = SetBreakpoint(script,
                                                    func.token_pos(),
@@ -2242,14 +2244,14 @@
   script ^= scripts.At(0);
   intptr_t first_token_idx, last_token_idx;
   script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx);
-  if (first_token_idx < 0) {
+  if (!Token::IsReal(first_token_idx)) {
     // Script does not contain the given line number.
     if (FLAG_verbose_debug) {
       OS::Print("Script '%s' does not contain line number %" Pd "\n",
                 script_url.ToCString(), line_number);
     }
     return NULL;
-  } else if (last_token_idx < 0) {
+  } else if (!Token::IsReal(last_token_idx)) {
     // Line does not contain any tokens.
     if (FLAG_verbose_debug) {
       OS::Print("No executable code at line %" Pd " in '%s'\n",
@@ -2531,7 +2533,8 @@
 }
 
 
-void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) {
+void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
+                                     bool skip_next_step) {
   stepping_fp_ = 0;
   if (resume_action_ == kSingleStep) {
     // When single stepping, we need to deoptimize because we might be
@@ -2541,11 +2544,19 @@
     // to call an optimized function.
     DeoptimizeWorld();
     isolate_->set_single_step(true);
+    skip_next_step_ = skip_next_step;
+    if (FLAG_verbose_debug) {
+      OS::Print("HandleSteppingRequest- kSingleStep\n");
+    }
   } else if (resume_action_ == kStepOver) {
     DeoptimizeWorld();
     isolate_->set_single_step(true);
+    skip_next_step_ = skip_next_step;
     ASSERT(stack_trace->Length() > 0);
     stepping_fp_ = stack_trace->FrameAt(0)->fp();
+    if (FLAG_verbose_debug) {
+      OS::Print("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
+    }
   } else if (resume_action_ == kStepOut) {
     DeoptimizeWorld();
     isolate_->set_single_step(true);
@@ -2557,6 +2568,9 @@
         break;
       }
     }
+    if (FLAG_verbose_debug) {
+      OS::Print("HandleSteppingRequest- kStepOut %" Px "\n", stepping_fp_);
+    }
   }
 }
 
@@ -2614,6 +2628,10 @@
   if (IsPaused()) {
     return Error::null();
   }
+  if (skip_next_step_) {
+    skip_next_step_ = false;
+    return Error::null();
+  }
 
   // Check whether we are in a Dart function that the user is
   // interested in. If we saved the frame pointer of a stack frame
@@ -2627,7 +2645,7 @@
     // There is an "interesting frame" set. Only pause at appropriate
     // locations in this frame.
     if (stepping_fp_ > frame->fp()) {
-      // We are in a callee of the frame we're interested in.
+      // We are i n a callee of the frame we're interested in.
       // Ignore this stepping break.
       return Error::null();
     } else if (frame->fp() > stepping_fp_) {
@@ -2641,15 +2659,14 @@
   if (!frame->IsDebuggable()) {
     return Error::null();
   }
-  if (frame->TokenPos() < 0) {
+  if (!Token::IsDebugPause(frame->TokenPos())) {
     return Error::null();
   }
 
-  // Don't pause for a single step if there is a breakpoint set
-  // at this location.
-  if (HasActiveBreakpoint(frame->pc())) {
-    return Error::null();
-  }
+  // If there is an active breakpoint at this pc, then we should have
+  // already bailed out of this function in the skip_next_step_ test
+  // above.
+  ASSERT(!HasActiveBreakpoint(frame->pc()));
 
   if (FLAG_verbose_debug) {
     OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
@@ -2748,7 +2765,9 @@
   ASSERT(stack_trace_ == NULL);
   stack_trace_ = stack_trace;
   SignalPausedEvent(top_frame, bpt_hit);
-  HandleSteppingRequest(stack_trace_);
+  // When we single step from a user breakpoint, our next stepping
+  // point will be at the exact same pc.  Skip it.
+  HandleSteppingRequest(stack_trace_, true /* skip next step */);
   stack_trace_ = NULL;
   if (cbpt->IsInternal()) {
     RemoveInternalBreakpoints();
@@ -2886,7 +2905,7 @@
         intptr_t bp_pos =
             ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(),
                                  loc->requested_column_number());
-        if (bp_pos < 0) {
+        if (!Token::IsDebugPause(bp_pos)) {
           if (FLAG_verbose_debug) {
             OS::Print("Failed resolving breakpoint for function '%s'\n",
                       String::Handle(func.name()).ToCString());
@@ -2974,8 +2993,8 @@
         ASSERT(line_number >= 0);
         intptr_t first_token_pos, last_token_pos;
         script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos);
-        if ((first_token_pos < 0) ||
-            (last_token_pos < 0)) {
+        if (!Token::IsDebugPause(first_token_pos) ||
+            !Token::IsDebugPause(last_token_pos)) {
           // Script does not contain the given line number or there are no
           // tokens on the line. Drop the breakpoint silently.
           Breakpoint* bpt = matched_loc->breakpoints();
@@ -3111,7 +3130,7 @@
             pause_event_->breakpoint() == curr_bpt) {
           pause_event_->set_breakpoint(NULL);
         }
-        return;
+        break;
       }
 
       prev_bpt = curr_bpt;
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index acb69ec..5696e96 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -651,7 +651,8 @@
   // interrupts, etc.
   void Pause(DebuggerEvent* event);
 
-  void HandleSteppingRequest(DebuggerStackTrace* stack_trace);
+  void HandleSteppingRequest(DebuggerStackTrace* stack_trace,
+                             bool skip_next_step = false);
 
   Isolate* isolate_;
   Dart_Port isolate_id_;  // A unique ID for the isolate in the debugger.
@@ -690,6 +691,11 @@
   // lower on the stack.
   uword stepping_fp_;
 
+  // If we step while at a breakpoint, we would hit the same pc twice.
+  // We use this field to let us skip the next single-step after a
+  // breakpoint.
+  bool skip_next_step_;
+
   Dart_ExceptionPauseInfo exc_pause_info_;
 
   static EventHandler* event_handler_;
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 7e1ec45..5241d34 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -652,7 +652,7 @@
 
   // Construct the super type object, canonicalize it and return.
   Type& instantiated_type = Type::Handle(
-      Type::New(super_cls, super_type_args_array, Scanner::kNoSourcePos));
+      Type::New(super_cls, super_type_args_array, Token::kNoSourcePos));
   ASSERT(!instantiated_type.IsNull());
   instantiated_type.SetIsFinalized();
   return Api::NewHandle(T, instantiated_type.Canonicalize());
@@ -671,7 +671,7 @@
   if (!instance.IsClosure()) {
     return Api::NewError("%s: parameter 0 is not a closure", CURRENT_FUNC);
   }
-  const Function& func = Function::Handle(Closure::function(instance));
+  const Function& func = Function::Handle(Closure::Cast(instance).function());
   ASSERT(!func.IsNull());
   if (name != NULL) {
     *name = Api::NewHandle(T, func.QualifiedUserVisibleName());
diff --git a/runtime/vm/deferred_objects.cc b/runtime/vm/deferred_objects.cc
index 71a734a..d3f89c7 100644
--- a/runtime/vm/deferred_objects.cc
+++ b/runtime/vm/deferred_objects.cc
@@ -304,6 +304,48 @@
         }
       }
     }
+  } else if (cls.id() == kClosureCid) {
+    // TODO(regis): It would be better to programmatically add these fields to
+    // the VM Closure class. Declaring them in the Dart class _Closure does not
+    // work, because the class is prefinalized and CalculateFieldOffsets is
+    // therefore not called. Resetting the finalization state may be an option.
+    const Closure& closure = Closure::Cast(*object_);
+
+    Smi& offset = Smi::Handle();
+    Object& value = Object::Handle();
+
+    for (intptr_t i = 0; i < field_count_; i++) {
+      offset ^= GetFieldOffset(i);
+      if (offset.Value() == Closure::type_arguments_offset()) {
+        TypeArguments& arguments = TypeArguments::Handle();
+        arguments ^= GetValue(i);
+        closure.SetTypeArguments(arguments);
+        if (FLAG_trace_deoptimization_verbose) {
+          OS::PrintErr("    closure@type_arguments (offset %" Pd ") <- %s\n",
+                       offset.Value(),
+                       value.ToCString());
+        }
+      } else if (offset.Value() == Closure::function_offset()) {
+        Function& function = Function::Handle();
+        function ^= GetValue(i);
+        closure.set_function(function);
+        if (FLAG_trace_deoptimization_verbose) {
+          OS::PrintErr("    closure@function (offset %" Pd ") <- %s\n",
+                       offset.Value(),
+                       value.ToCString());
+        }
+      } else {
+        ASSERT(offset.Value() == Closure::context_offset());
+        Context& context = Context::Handle();
+        context ^= GetValue(i);
+        closure.set_context(context);
+        if (FLAG_trace_deoptimization_verbose) {
+          OS::PrintErr("    closure@context (offset %" Pd ") <- %s\n",
+                       offset.Value(),
+                       value.ToCString());
+        }
+      }
+    }
   } else {
     const Instance& obj = Instance::Cast(*object_);
 
@@ -324,8 +366,7 @@
                        value.ToCString());
         }
       } else {
-        ASSERT(cls.IsSignatureClass() ||
-               (offset.Value() == cls.type_arguments_field_offset()));
+        ASSERT(offset.Value() == cls.type_arguments_field_offset());
         obj.SetFieldAtOffset(offset.Value(), value);
         if (FLAG_trace_deoptimization_verbose) {
           OS::PrintErr("    null Field @ offset(%" Pd ") <- %s\n",
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index fed89bb..ee62949 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -48,6 +48,9 @@
 // Quick access to the locally defined zone() method.
 #define Z (zone())
 
+// Quick synthetic token position.
+#define ST(token_pos) Token::ToSynthetic(token_pos)
+
 // TODO(srdjan): Allow compiler to add constants as they are encountered in
 // the compilation.
 const double kCommonDoubleConstants[] =
@@ -829,20 +832,26 @@
 
 
 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
-                                               Value* value) {
+                                               Value* value,
+                                               intptr_t token_pos) {
   ASSERT(!local.is_captured());
-  return new(Z) StoreLocalInstr(local, value);
+  ASSERT(!Token::IsClassifying(token_pos));
+  return new(Z) StoreLocalInstr(local, value, ST(token_pos));
 }
 
 
-Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) {
+Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value,
+                                                   intptr_t token_pos) {
   return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(),
-                        value);
+                        value,
+                        token_pos);
 }
 
 
-Definition* EffectGraphVisitor::BuildLoadExprTemp() {
-  return BuildLoadLocal(*owner()->parsed_function().expression_temp_var());
+Definition* EffectGraphVisitor::BuildLoadExprTemp(intptr_t token_pos) {
+  ASSERT(!Token::IsClassifying(token_pos));
+  return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(),
+                        token_pos);
 }
 
 
@@ -850,7 +859,7 @@
                                                 Value* value,
                                                 intptr_t token_pos) {
   if (local.is_captured()) {
-    LocalVariable* tmp_var = EnterTempLocalScope(value);
+    LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos);
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
@@ -860,7 +869,7 @@
           context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
           token_pos));
     }
-    Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
+    Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos));
     StoreInstanceFieldInstr* store =
         new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()),
                                        context,
@@ -868,7 +877,7 @@
                                        kEmitStoreBarrier,
                                        token_pos);
     Do(store);
-    return ExitTempLocalScope(tmp_var);
+    return ExitTempLocalScope(tmp_var, token_pos);
   } else {
     return new(Z) StoreLocalInstr(local, value, token_pos);
   }
@@ -903,6 +912,7 @@
 void EffectGraphVisitor::BuildSaveContext(
     const LocalVariable& variable,
     intptr_t token_pos) {
+  ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos));
   Value* context = Bind(BuildCurrentContext(token_pos));
   Do(BuildStoreLocal(variable, context, token_pos));
 }
@@ -1122,7 +1132,7 @@
   // statements for which there is no associated source position.
   const Function& function = owner()->function();
   if (FLAG_support_debugger &&
-      (node->token_pos() >= 0) && !function.is_native()) {
+      Token::IsDebugPause(node->token_pos()) && !function.is_native()) {
     AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
                                               RawPcDescriptors::kRuntimeCall));
   }
@@ -1177,7 +1187,7 @@
   if (function.IsAsyncClosure() &&
       (node->return_type() == ReturnNode::kRegular)) {
     // Temporary store the computed return value.
-    Do(BuildStoreExprTemp(return_value));
+    Do(BuildStoreExprTemp(return_value, node->token_pos()));
 
     LocalVariable* rcv_var =
         node->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
@@ -1186,7 +1196,7 @@
         new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
     Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos()));
     arguments->Add(PushArgument(rcv_value));
-    Value* returned_value = Bind(BuildLoadExprTemp());
+    Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos()));
     arguments->Add(PushArgument(returned_value));
     InstanceCallInstr* call = new(Z) InstanceCallInstr(
         node->token_pos(),
@@ -1199,7 +1209,7 @@
     Do(call);
 
     // Rebind the return value for the actual return call to be null.
-    return_value = BuildNullValue();
+    return_value = BuildNullValue(node->token_pos());
   }
 
   intptr_t current_context_level = owner()->context_level();
@@ -1425,22 +1435,22 @@
                                                  right_value,
                                                  constant_true,
                                                  false));  // No number check.
-    for_right.Do(BuildStoreExprTemp(compare));
+    for_right.Do(BuildStoreExprTemp(compare, node->token_pos()));
 
     if (node->kind() == Token::kAND) {
       ValueGraphVisitor for_false(owner());
       Value* constant_false =
           for_false.Bind(new(Z) ConstantInstr(Bool::False()));
-      for_false.Do(BuildStoreExprTemp(constant_false));
+      for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos()));
       Join(for_test, for_right, for_false);
     } else {
       ASSERT(node->kind() == Token::kOR);
       ValueGraphVisitor for_true(owner());
       Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True()));
-      for_true.Do(BuildStoreExprTemp(constant_true));
+      for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos()));
       Join(for_test, for_true, for_right);
     }
-    ReturnDefinition(BuildLoadExprTemp());
+    ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
     return;
   }
 
@@ -1502,9 +1512,9 @@
   const Class& instantiator_class = Class::Handle(
       Z, owner()->function().Owner());
   // Since called only when type tested against is not instantiated.
-  ASSERT(instantiator_class.NumTypeParameters() > 0);
+  ASSERT(instantiator_class.IsGeneric());
   Value* instantiator_type_arguments = NULL;
-  Value* instantiator = BuildInstantiator(instantiator_class);
+  Value* instantiator = BuildInstantiator(token_pos);
   if (instantiator == NULL) {
     // No instantiator when inside factory.
     instantiator_type_arguments =
@@ -1527,8 +1537,8 @@
   const Class& instantiator_class = Class::Handle(
       Z, owner()->function().Owner());
   // Since called only when type tested against is not instantiated.
-  ASSERT(instantiator_class.NumTypeParameters() > 0);
-  instantiator = BuildInstantiator(instantiator_class);
+  ASSERT(instantiator_class.IsGeneric());
+  instantiator = BuildInstantiator(token_pos);
   if (instantiator == NULL) {
     // No instantiator when inside factory.
     instantiator_type_arguments =
@@ -1541,8 +1551,9 @@
 }
 
 
-Value* EffectGraphVisitor::BuildNullValue() {
-  return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())));
+Value* EffectGraphVisitor::BuildNullValue(intptr_t token_pos) {
+  return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()),
+                                   token_pos));
 }
 
 
@@ -1555,7 +1566,7 @@
   // Build the type check computation.
   Value* instantiator_type_arguments = NULL;
   if (dst_type.IsInstantiated()) {
-    instantiator_type_arguments = BuildNullValue();
+    instantiator_type_arguments = BuildNullValue(token_pos);
   } else {
     BuildTypecheckArguments(token_pos, &instantiator_type_arguments);
   }
@@ -1666,7 +1677,7 @@
   PushArgumentInstr* push_left = PushArgument(for_left_value.value());
   PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
-    push_type_args = PushArgument(BuildNullValue());
+    push_type_args = PushArgument(BuildNullValue(node->token_pos()));
   } else {
     BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
   }
@@ -1718,7 +1729,7 @@
   PushArgumentInstr* push_left = PushArgument(for_value.value());
   PushArgumentInstr* push_type_args = NULL;
   if (type.IsInstantiated()) {
-    push_type_args = PushArgument(BuildNullValue());
+    push_type_args = PushArgument(BuildNullValue(node->token_pos()));
   } else {
     BuildTypecheckPushArguments(node->token_pos(), &push_type_args);
   }
@@ -1917,15 +1928,17 @@
   ValueGraphVisitor for_true(owner());
   node->true_expr()->Visit(&for_true);
   ASSERT(for_true.is_open());
-  for_true.Do(BuildStoreExprTemp(for_true.value()));
+  for_true.Do(BuildStoreExprTemp(for_true.value(),
+                                 node->true_expr()->token_pos()));
 
   ValueGraphVisitor for_false(owner());
   node->false_expr()->Visit(&for_false);
   ASSERT(for_false.is_open());
-  for_false.Do(BuildStoreExprTemp(for_false.value()));
+  for_false.Do(BuildStoreExprTemp(for_false.value(),
+                                  node->false_expr()->token_pos()));
 
   Join(for_test, for_true, for_false);
-  ReturnDefinition(BuildLoadExprTemp());
+  ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
 }
 
 
@@ -2273,6 +2286,8 @@
   // We need to create a new await state which involves:
   // * Increase the jump counter. Sanity check against the list of targets.
   // * Save the current context for resuming.
+  ASSERT(Token::IsSynthetic(node->token_pos()) ||
+         Token::IsNoSource(node->token_pos()));
   ASSERT(node->async_scope() != NULL);
   ASSERT(node->await_scope() != NULL);
   LocalVariable* jump_var = node->async_scope()->LookupVariable(
@@ -2288,8 +2303,8 @@
   ASSERT(jump_count == owner()->await_joins()->length());
   // Store the counter in :await_jump_var.
   Value* jump_val = Bind(new(Z) ConstantInstr(
-      Smi::ZoneHandle(Z, Smi::New(jump_count))));
-  Do(BuildStoreLocal(*jump_var, jump_val));
+      Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos()));
+  Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos()));
   // Save the current context for resuming.
   BuildSaveContext(*ctx_var, node->token_pos());
 }
@@ -2304,7 +2319,8 @@
 }
 
 
-LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
+LocalVariable* EffectGraphVisitor::EnterTempLocalScope(
+    Value* value, intptr_t token_pos) {
   Do(new(Z) PushTempInstr(value));
   owner()->AllocateTemp();
 
@@ -2313,7 +2329,7 @@
   char name[64];
   OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
-      new(Z) LocalVariable(Scanner::kNoSourcePos,
+      new(Z) LocalVariable(Token::kNoSourcePos,
                            String::ZoneHandle(Z, Symbols::New(name)),
                            *value->Type()->ToAbstractType());
   var->set_index(index);
@@ -2321,8 +2337,9 @@
 }
 
 
-Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
-  Value* tmp = Bind(new(Z) LoadLocalInstr(*var));
+Definition* EffectGraphVisitor::ExitTempLocalScope(
+    LocalVariable* var, intptr_t token_pos) {
+  Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos));
   owner()->DeallocateTemps(1);
   ASSERT(GetCurrentTempLocalIndex() == var->index());
   return new(Z) DropTempsInstr(1, tmp);
@@ -2400,13 +2417,14 @@
                                                      num_elements);
   Value* array_val = Bind(create);
 
-  { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
+  { LocalVariable* tmp_var = EnterTempLocalScope(array_val, node->token_pos());
     const intptr_t class_id = kArrayCid;
     const intptr_t deopt_id = Thread::kNoDeoptId;
     for (int i = 0; i < node->length(); ++i) {
-      Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var));
+      Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
       Value* index =
-          Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i))));
+          Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)),
+                                    node->token_pos()));
       ValueGraphVisitor for_value(owner());
       node->ElementAt(i)->Visit(&for_value);
       Append(for_value);
@@ -2421,7 +2439,7 @@
           index_scale, class_id, deopt_id, node->token_pos());
       Do(store);
     }
-    ReturnDefinition(ExitTempLocalScope(tmp_var));
+    ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
   }
 }
 
@@ -2500,36 +2518,45 @@
       isolate()->AddClosureFunction(function);
     }
   }
-  ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   ASSERT(function.context_scope() != ContextScope::null());
 
   // The function type of a closure may have type arguments. In that case,
   // pass the type arguments of the instantiator.
-  const Class& cls = Class::ZoneHandle(Z, function.signature_class());
-  ASSERT(!cls.IsNull());
-  const bool requires_type_arguments = cls.NumTypeArguments() > 0;
-  Value* type_arguments = NULL;
-  if (requires_type_arguments) {
-    ASSERT(cls.type_arguments_field_offset() ==
-           Closure::type_arguments_offset());
-    ASSERT(cls.instance_size() == Closure::InstanceSize());
-    const Class& instantiator_class = Class::Handle(
-        Z, owner()->function().Owner());
-    type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
-                                                    instantiator_class,
-                                                    NULL);
-    arguments->Add(PushArgument(type_arguments));
-  }
+  const Class& closure_class =
+      Class::ZoneHandle(Z, isolate()->object_store()->closure_class());
+  ZoneGrowableArray<PushArgumentInstr*>* no_arguments =
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(0);
   AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(),
-                                                          cls,
-                                                          arguments);
+                                                          closure_class,
+                                                          no_arguments);
   alloc->set_closure_function(function);
 
   Value* closure_val = Bind(alloc);
-  { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
+  { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val,
+                                                         node->token_pos());
+    // Store type arguments if scope class is generic.
+    const FunctionType& function_type =
+        FunctionType::ZoneHandle(Z, function.SignatureType());
+    const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class());
+    if (scope_cls.IsGeneric()) {
+      ASSERT(function.Owner() == scope_cls.raw());
+      Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var,
+                                                          node->token_pos()));
+      const Class& instantiator_class = Class::Handle(
+          Z, owner()->function().Owner());
+      Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
+                                                             instantiator_class,
+                                                             NULL);
+      Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(),
+                                        closure_tmp_val,
+                                        type_arguments,
+                                        kEmitStoreBarrier,
+                                        node->token_pos()));
+    }
+
     // Store function.
-    Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
+    Value* closure_tmp_val =
+        Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
     Value* func_val =
         Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw())));
     Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(),
@@ -2543,9 +2570,11 @@
       Value* allocated_context =
           Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                            kNumContextVariables));
-      { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
+      { LocalVariable* context_tmp_var =
+            EnterTempLocalScope(allocated_context, node->token_pos());
         // Store receiver in context.
-        Value* context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
+        Value* context_tmp_val =
+            Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos()));
         ValueGraphVisitor for_receiver(owner());
         node->receiver()->Visit(&for_receiver);
         Append(for_receiver);
@@ -2556,14 +2585,16 @@
                                           kEmitStoreBarrier,
                                           node->token_pos()));
         // Store new context in closure.
-        closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
-        context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
+        closure_tmp_val =
+            Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
+        context_tmp_val =
+            Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos()));
         Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
                                           closure_tmp_val,
                                           context_tmp_val,
                                           kEmitStoreBarrier,
                                           node->token_pos()));
-        Do(ExitTempLocalScope(context_tmp_var));
+        Do(ExitTempLocalScope(context_tmp_var, node->token_pos()));
       }
     } else {
       // Store current context in closure.
@@ -2576,7 +2607,7 @@
                                         kEmitStoreBarrier,
                                         node->token_pos()));
     }
-    ReturnDefinition(ExitTempLocalScope(closure_tmp_var));
+    ReturnDefinition(ExitTempLocalScope(closure_tmp_var, node->token_pos()));
   }
 }
 
@@ -2595,34 +2626,34 @@
 
 
 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) {
+  const intptr_t token_pos = node->token_pos();
   LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-  LoadLocalNode* load_temp =
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
+  LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var);
 
   LiteralNode* null_constant =
-      new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+      new(Z) LiteralNode(ST(token_pos), Object::null_instance());
   ComparisonNode* check_is_null =
-      new(Z) ComparisonNode(Scanner::kNoSourcePos,
+      new(Z) ComparisonNode(ST(token_pos),
                             Token::kEQ,
                             load_temp,
                             null_constant);
-  TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+  TestGraphVisitor for_test(owner(), ST(token_pos));
   check_is_null->Visit(&for_test);
 
   EffectGraphVisitor for_true(owner());
   EffectGraphVisitor for_false(owner());
 
   StoreLocalNode* store_null =
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
+      new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
   store_null->Visit(&for_true);
 
   InstanceCallNode* call =
-      new(Z) InstanceCallNode(node->token_pos(),
+      new(Z) InstanceCallNode(token_pos,
                               load_temp,
                               node->function_name(),
                               node->arguments());
   StoreLocalNode* store_result =
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call);
+      new(Z) StoreLocalNode(ST(token_pos), temp_var, call);
   store_result->Visit(&for_false);
 
   Join(for_test, for_true, for_false);
@@ -2634,9 +2665,9 @@
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
     Append(for_receiver);
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
     BuildInstanceCallConditional(node);
-    ReturnDefinition(BuildLoadExprTemp());
+    ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
   } else {
     EffectGraphVisitor::VisitInstanceCallNode(node);
   }
@@ -2648,7 +2679,7 @@
   node->receiver()->Visit(&for_receiver);
   Append(for_receiver);
   if (node->is_conditional()) {
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
     BuildInstanceCallConditional(node);
   } else {
     PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
@@ -2730,16 +2761,17 @@
   node->closure()->Visit(&for_closure);
   Append(for_closure);
 
-  LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value());
+  LocalVariable* tmp_var =
+      EnterTempLocalScope(for_closure.value(), node->token_pos());
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
-  Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
+  Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
   PushArgumentInstr* push_closure = PushArgument(closure_val);
   arguments->Add(push_closure);
   BuildPushArguments(*node->arguments(), arguments);
 
-  closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
+  closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
   LoadFieldInstr* function_load = new(Z) LoadFieldInstr(
       closure_val,
       Closure::function_offset(),
@@ -2752,11 +2784,11 @@
       new(Z) ClosureCallInstr(function_val, node, arguments);
   if (result_needed) {
     Value* result = Bind(closure_call);
-    Do(new(Z) StoreLocalInstr(*tmp_var, result));
+    Do(new(Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos())));
   } else {
     Do(closure_call);
   }
-  ReturnDefinition(ExitTempLocalScope(tmp_var));
+  ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
 }
 
 
@@ -2886,8 +2918,7 @@
 }
 
 
-Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) {
-  ASSERT(instantiator_class.NumTypeParameters() > 0);
+Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos) {
   Function& outer_function = Function::Handle(Z, owner()->function().raw());
   while (outer_function.IsLocalFunction()) {
     outer_function = outer_function.parent_function();
@@ -2898,7 +2929,7 @@
 
   LocalVariable* instantiator = owner()->parsed_function().instantiator();
   ASSERT(instantiator != NULL);
-  Value* result = Bind(BuildLoadLocal(*instantiator));
+  Value* result = Bind(BuildLoadLocal(*instantiator, token_pos));
   return result;
 }
 
@@ -2909,7 +2940,7 @@
     intptr_t token_pos,
     const Class& instantiator_class,
     Value* instantiator) {
-  if (instantiator_class.NumTypeParameters() == 0) {
+  if (!instantiator_class.IsGeneric()) {
     // The type arguments are compile time constants.
     TypeArguments& type_arguments =
         TypeArguments::ZoneHandle(Z, TypeArguments::null());
@@ -2934,10 +2965,10 @@
     LocalVariable* instantiator_var =
         owner()->parsed_function().instantiator();
     ASSERT(instantiator_var != NULL);
-    return Bind(BuildLoadLocal(*instantiator_var));
+    return Bind(BuildLoadLocal(*instantiator_var, token_pos));
   }
   if (instantiator == NULL) {
-    instantiator = BuildInstantiator(instantiator_class);
+    instantiator = BuildInstantiator(token_pos);
   }
   // The instantiator is the receiver of the caller, which is not a factory.
   // The receiver cannot be null; extract its TypeArguments object.
@@ -2951,7 +2982,7 @@
       instantiator,
       type_arguments_field_offset,
       Type::ZoneHandle(Z, Type::null()),  // Not an instance, no type.
-      Scanner::kNoSourcePos));
+      token_pos));
 }
 
 
@@ -2995,11 +3026,12 @@
   //   tn       <- LoadLocal(temp)
 
   Value* allocate = BuildObjectAllocation(node);
-  { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
-    Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var));
+  { LocalVariable* tmp_var = EnterTempLocalScope(allocate, node->token_pos());
+    Value* allocated_tmp =
+        Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
     PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
     BuildConstructorCall(node, push_allocated_value);
-    ReturnDefinition(ExitTempLocalScope(tmp_var));
+    ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
   }
 }
 
@@ -3007,33 +3039,32 @@
 
 void EffectGraphVisitor::BuildInstanceGetterConditional(
     InstanceGetterNode* node) {
+  const intptr_t token_pos = node->token_pos();
   LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
-  LoadLocalNode* load_temp =
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
+  LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var);
 
   LiteralNode* null_constant =
-      new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+      new(Z) LiteralNode(ST(token_pos), Object::null_instance());
   ComparisonNode* check_is_null =
-      new(Z) ComparisonNode(Scanner::kNoSourcePos,
+      new(Z) ComparisonNode(ST(token_pos),
                             Token::kEQ,
                             load_temp,
                             null_constant);
-  TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+  TestGraphVisitor for_test(owner(), ST(token_pos));
   check_is_null->Visit(&for_test);
 
   EffectGraphVisitor for_true(owner());
   EffectGraphVisitor for_false(owner());
 
   StoreLocalNode* store_null =
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant);
+      new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant);
   store_null->Visit(&for_true);
 
-  InstanceGetterNode* getter =
-      new(Z) InstanceGetterNode(node->token_pos(),
-                                load_temp,
-                                node->field_name());
+  InstanceGetterNode* getter = new(Z) InstanceGetterNode(token_pos,
+                                                         load_temp,
+                                                         node->field_name());
   StoreLocalNode* store_getter =
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter);
+      new(Z) StoreLocalNode(ST(token_pos), temp_var, getter);
   store_getter->Visit(&for_false);
 
   Join(for_test, for_true, for_false);
@@ -3045,9 +3076,9 @@
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
     Append(for_receiver);
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
     BuildInstanceGetterConditional(node);
-    ReturnDefinition(BuildLoadExprTemp());
+    ReturnDefinition(BuildLoadExprTemp(node->token_pos()));
   } else {
     EffectGraphVisitor::VisitInstanceGetterNode(node);
   }
@@ -3059,7 +3090,7 @@
   node->receiver()->Visit(&for_receiver);
   Append(for_receiver);
   if (node->is_conditional()) {
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos()));
     BuildInstanceGetterConditional(node);
   } else {
     PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
@@ -3095,7 +3126,7 @@
 
   Value* value = NULL;
   if (result_is_needed) {
-    value = Bind(BuildStoreExprTemp(for_value.value()));
+    value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos()));
   } else {
     value = for_value.value();
   }
@@ -3104,30 +3135,31 @@
 
 
 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
+  const intptr_t token_pos = node->token_pos();
   if (node->is_conditional()) {
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
     Append(for_receiver);
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
 
     LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
     LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
+        new(Z) LoadLocalNode(ST(token_pos), temp_var);
     LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+        new(Z) LiteralNode(ST(token_pos), Object::null_instance());
     ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
+        new(Z) ComparisonNode(ST(token_pos),
                               Token::kEQ,
                               load_temp,
                               null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+    TestGraphVisitor for_test(owner(), ST(token_pos));
     check_is_null->Visit(&for_test);
 
     EffectGraphVisitor for_true(owner());
     EffectGraphVisitor for_false(owner());
 
     InstanceSetterNode* setter =
-        new(Z) InstanceSetterNode(node->token_pos(),
+        new(Z) InstanceSetterNode(token_pos,
                                   load_temp,
                                   node->field_name(),
                                   node->value());
@@ -3141,7 +3173,7 @@
   const String& name =
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
   const intptr_t kNumArgsChecked = 1;  // Do not check value type.
-  InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(token_pos,
                                                      name,
                                                      Token::kSET,
                                                      arguments,
@@ -3153,40 +3185,41 @@
 
 
 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
+  const intptr_t token_pos = node->token_pos();
   if (node->is_conditional()) {
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
     Append(for_receiver);
-    Do(BuildStoreExprTemp(for_receiver.value()));
+    Do(BuildStoreExprTemp(for_receiver.value(), token_pos));
 
     LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
     LoadLocalNode* load_temp =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var);
+        new(Z) LoadLocalNode(ST(token_pos), temp_var);
     LiteralNode* null_constant =
-        new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance());
+        new(Z) LiteralNode(ST(token_pos), Object::null_instance());
     ComparisonNode* check_is_null =
-        new(Z) ComparisonNode(Scanner::kNoSourcePos,
+        new(Z) ComparisonNode(ST(token_pos),
                               Token::kEQ,
                               load_temp,
                               null_constant);
-    TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+    TestGraphVisitor for_test(owner(), ST(token_pos));
     check_is_null->Visit(&for_test);
 
     ValueGraphVisitor for_true(owner());
     null_constant->Visit(&for_true);
-    for_true.Do(BuildStoreExprTemp(for_true.value()));
+    for_true.Do(BuildStoreExprTemp(for_true.value(), token_pos));
 
     ValueGraphVisitor for_false(owner());
     InstanceSetterNode* setter =
-        new(Z) InstanceSetterNode(node->token_pos(),
+        new(Z) InstanceSetterNode(token_pos,
                                   load_temp,
                                   node->field_name(),
                                   node->value());
     setter->Visit(&for_false);
-    for_false.Do(BuildStoreExprTemp(for_false.value()));
+    for_false.Do(BuildStoreExprTemp(for_false.value(), token_pos));
 
     Join(for_test, for_true, for_false);
-    ReturnDefinition(BuildLoadExprTemp());
+    ReturnDefinition(BuildLoadExprTemp(token_pos));
     return;
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
@@ -3195,14 +3228,14 @@
   const String& name =
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
   const intptr_t kNumArgsChecked = 1;  // Do not check value type.
-  Do(new(Z) InstanceCallInstr(node->token_pos(),
+  Do(new(Z) InstanceCallInstr(token_pos,
                               name,
                               Token::kSET,
                               arguments,
                               Object::null_array(),
                               kNumArgsChecked,
                               owner()->ic_data_array()));
-  ReturnDefinition(BuildLoadExprTemp());
+  ReturnDefinition(BuildLoadExprTemp(token_pos));
 }
 
 
@@ -3284,6 +3317,7 @@
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
+  const intptr_t token_pos = node->token_pos();
   // A super setter is an instance setter whose setter function is
   // resolved at compile time (in the caller instance getter's super class).
   // Unlike a static getter, a super getter has a receiver parameter.
@@ -3294,7 +3328,7 @@
     if (is_super_setter) {
       ASSERT(node->receiver() != NULL);
       // Resolve and call noSuchMethod.
-      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos);
       arguments->Add(node->receiver());
       arguments->Add(node->value());
       call = BuildStaticNoSuchMethodCall(
@@ -3306,10 +3340,10 @@
           true);  // Super invocation.
     } else {
       // Throw a NoSuchMethodError.
-      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos);
       arguments->Add(node->value());
       call = BuildThrowNoSuchMethodError(
-          node->token_pos(),
+          token_pos,
           node->cls(),
           setter_name,
           arguments,  // Argument is the value passed to the setter.
@@ -3332,13 +3366,13 @@
     Append(for_value);
     Value* value = NULL;
     if (result_is_needed) {
-      value = Bind(BuildStoreExprTemp(for_value.value()));
+      value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
     } else {
       value = for_value.value();
     }
     arguments->Add(PushArgument(value));
 
-    call = new(Z) StaticCallInstr(node->token_pos(),
+    call = new(Z) StaticCallInstr(token_pos,
                                   setter_function,
                                   Object::null_array(),  // No names.
                                   arguments,
@@ -3346,7 +3380,7 @@
   }
   if (result_is_needed) {
     Do(call);
-    ReturnDefinition(BuildLoadExprTemp());
+    ReturnDefinition(BuildLoadExprTemp(token_pos));
   } else {
     ReturnDefinition(call);
   }
@@ -3382,10 +3416,11 @@
 }
 
 
-LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) {
+LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(
+    LocalScope* scope, intptr_t token_pos) {
   LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
                                                       true);  // Test only.
-  return new(Z) LoadLocalInstr(*receiver_var);
+  return new(Z) LoadLocalInstr(*receiver_var, token_pos);
 }
 
 
@@ -3395,7 +3430,7 @@
     intptr_t offset,
     const Type& type,
     intptr_t class_id) {
-  Value* receiver = Bind(BuildLoadThisVar(node->scope()));
+  Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
   LoadFieldInstr* load = new(Z) LoadFieldInstr(receiver,
                                                offset,
                                                type,
@@ -3410,10 +3445,10 @@
     NativeBodyNode* node,
     intptr_t offset,
     StoreBarrierType emit_store_barrier) {
-  Value* receiver = Bind(BuildLoadThisVar(node->scope()));
+  Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos()));
   LocalVariable* value_var =
       node->scope()->LookupVariable(Symbols::Value(), true);
-  Value* value = Bind(new(Z) LoadLocalInstr(*value_var));
+  Value* value = Bind(new(Z) LoadLocalInstr(*value_var, node->token_pos()));
   StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
       offset,
       receiver,
@@ -3427,19 +3462,20 @@
 
 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
   const Function& function = owner()->function();
+  const intptr_t token_pos = node->token_pos();
   if (!function.IsClosureFunction()) {
     MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
     switch (kind) {
       case MethodRecognizer::kObjectEquals: {
-        Value* receiver = Bind(BuildLoadThisVar(node->scope()));
+        Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
         LocalVariable* other_var =
             node->scope()->LookupVariable(Symbols::Other(),
                                           true);  // Test only.
-        Value* other = Bind(new(Z) LoadLocalInstr(*other_var));
+        Value* other = Bind(new(Z) LoadLocalInstr(*other_var, token_pos));
         // Receiver is not a number because numbers override equality.
         const bool kNoNumberCheck = false;
         StrictCompareInstr* compare =
-            new(Z) StrictCompareInstr(node->token_pos(),
+            new(Z) StrictCompareInstr(token_pos,
                                       Token::kEQ_STRICT,
                                       receiver,
                                       other,
@@ -3463,11 +3499,11 @@
             Smi::ZoneHandle(Z, Smi::New(0))));
         Value* load_val = Bind(load);
         StrictCompareInstr* compare =
-            new(Z) StrictCompareInstr(node->token_pos(),
-                                   Token::kEQ_STRICT,
-                                   load_val,
-                                   zero_val,
-                                   false);  // No number check.
+            new(Z) StrictCompareInstr(token_pos,
+                                      Token::kEQ_STRICT,
+                                      load_val,
+                                      zero_val,
+                                      false);  // No number check.
         return ReturnDefinition(compare);
       }
       case MethodRecognizer::kGrowableArrayLength:
@@ -3483,12 +3519,12 @@
       case MethodRecognizer::kClassIDgetID: {
         LocalVariable* value_var =
             node->scope()->LookupVariable(Symbols::Value(), true);
-        Value* value = Bind(new(Z) LoadLocalInstr(*value_var));
+        Value* value = Bind(new(Z) LoadLocalInstr(*value_var, token_pos));
         LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value);
         return ReturnDefinition(load);
       }
       case MethodRecognizer::kGrowableArrayCapacity: {
-        Value* receiver = Bind(BuildLoadThisVar(node->scope()));
+        Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos));
         LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
             receiver,
             Array::data_offset(),
@@ -3509,12 +3545,14 @@
         LocalVariable* type_args_parameter =
             node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(),
                                           true);
-        Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter));
+        Value* element_type =
+            Bind(new(Z) LoadLocalInstr(*type_args_parameter, token_pos));
         LocalVariable* length_parameter =
             node->scope()->LookupVariable(Symbols::Length(), true);
-        Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter));
+        Value* length =
+            Bind(new(Z) LoadLocalInstr(*length_parameter, token_pos));
         CreateArrayInstr* create_array =
-            new CreateArrayInstr(node->token_pos(), element_type, length);
+            new CreateArrayInstr(token_pos, element_type, length);
         return ReturnDefinition(create_array);
       }
       case MethodRecognizer::kBigint_getDigits: {
@@ -3627,7 +3665,7 @@
             !node->value()->AsLoadLocalNode()->local().IsInternal()) ||
         node->value()->IsClosureNode()) &&
         !node->local().IsInternal() &&
-        (node->token_pos() >= 0)) {
+        Token::IsDebugPause(node->token_pos())) {
       AddInstruction(new(Z) DebugStepCheckInstr(
           node->token_pos(), RawPcDescriptors::kRuntimeCall));
     }
@@ -3673,6 +3711,7 @@
 
 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
     StoreInstanceFieldNode* node) {
+  const intptr_t token_pos = node->token_pos();
   ValueGraphVisitor for_instance(owner());
   node->instance()->Visit(&for_instance);
   Append(for_instance);
@@ -3691,26 +3730,26 @@
   }
 
   if (FLAG_use_field_guards) {
-    store_value = Bind(BuildStoreExprTemp(store_value));
+    store_value = Bind(BuildStoreExprTemp(store_value, token_pos));
     GuardFieldClassInstr* guard_field_class =
         new(Z) GuardFieldClassInstr(store_value,
-                                 node->field(),
-                                 thread()->GetNextDeoptId());
+                                    node->field(),
+                                    thread()->GetNextDeoptId());
     AddInstruction(guard_field_class);
-    store_value = Bind(BuildLoadExprTemp());
+    store_value = Bind(BuildLoadExprTemp(token_pos));
     GuardFieldLengthInstr* guard_field_length =
         new(Z) GuardFieldLengthInstr(store_value,
                                      node->field(),
                                      thread()->GetNextDeoptId());
     AddInstruction(guard_field_length);
-    store_value = Bind(BuildLoadExprTemp());
+    store_value = Bind(BuildLoadExprTemp(token_pos));
   }
   StoreInstanceFieldInstr* store =
       new(Z) StoreInstanceFieldInstr(node->field(),
                                      for_instance.value(),
                                      store_value,
                                      kEmitStoreBarrier,
-                                     node->token_pos());
+                                     token_pos);
   // Maybe initializing unboxed store.
   store->set_is_potential_unboxed_initialization(true);
   ReturnDefinition(store);
@@ -3743,7 +3782,7 @@
   Append(for_value);
   Value* store_value = NULL;
   if (result_is_needed) {
-    store_value = Bind(BuildStoreExprTemp(for_value.value()));
+    store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
   } else {
     store_value = for_value.value();
   }
@@ -3752,7 +3791,7 @@
 
   if (result_is_needed) {
     Do(store);
-    return BuildLoadExprTemp();
+    return BuildLoadExprTemp(token_pos);
   } else {
     return store;
   }
@@ -3835,6 +3874,7 @@
     StoreIndexedNode* node,
     bool result_is_needed) {
   Function* super_function = NULL;
+  const intptr_t token_pos = node->token_pos();
   if (node->IsSuperStore()) {
     // Resolve the store indexed operator in the super class.
     super_function = &Function::ZoneHandle(
@@ -3843,7 +3883,7 @@
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
-      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos);
       arguments->Add(node->array());
       arguments->Add(node->index_expr());
       arguments->Add(node->value());
@@ -3857,7 +3897,7 @@
       if (result_is_needed) {
         Do(call);
         // BuildStaticNoSuchMethodCall stores the value in expression_temp.
-        return BuildLoadExprTemp();
+        return BuildLoadExprTemp(token_pos);
       } else {
         return call;
       }
@@ -3881,7 +3921,7 @@
   Append(for_value);
   Value* value = NULL;
   if (result_is_needed) {
-    value = Bind(BuildStoreExprTemp(for_value.value()));
+    value = Bind(BuildStoreExprTemp(for_value.value(), token_pos));
   } else {
     value = for_value.value();
   }
@@ -3891,14 +3931,14 @@
     // Generate static call to super operator []=.
 
     StaticCallInstr* store =
-        new(Z) StaticCallInstr(node->token_pos(),
+        new(Z) StaticCallInstr(token_pos,
                                *super_function,
                                Object::null_array(),
                                arguments,
                                owner()->ic_data_array());
     if (result_is_needed) {
       Do(store);
-      return BuildLoadExprTemp();
+      return BuildLoadExprTemp(token_pos);
     } else {
       return store;
     }
@@ -3908,7 +3948,7 @@
     const String& name =
         String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
     InstanceCallInstr* store =
-        new(Z) InstanceCallInstr(node->token_pos(),
+        new(Z) InstanceCallInstr(token_pos,
                                  name,
                                  Token::kASSIGN_INDEX,
                                  arguments,
@@ -3917,7 +3957,7 @@
                                  owner()->ic_data_array());
     if (result_is_needed) {
       Do(store);
-      return BuildLoadExprTemp();
+      return BuildLoadExprTemp(token_pos);
     } else {
       return store;
     }
@@ -4008,7 +4048,8 @@
     Value* allocated_context =
         Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                          num_context_variables));
-    { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
+    { LocalVariable* tmp_var =
+          EnterTempLocalScope(allocated_context, node->token_pos());
       if (!is_top_level_sequence || HasContextScope()) {
         ASSERT(is_top_level_sequence ||
                (nested_block.ContextLevel() ==
@@ -4023,7 +4064,7 @@
                                           node->token_pos()));
       }
       Do(BuildStoreContext(
-          Bind(ExitTempLocalScope(tmp_var)),
+          Bind(ExitTempLocalScope(tmp_var, node->token_pos())),
           node->token_pos()));
     }
 
@@ -4041,7 +4082,7 @@
           // Create a temporary local describing the original position.
           const String& temp_name = Symbols::TempParam();
           LocalVariable* temp_local = new(Z) LocalVariable(
-              Scanner::kNoSourcePos,  // Token index.
+              Token::kNoSourcePos,  // Token index.
               temp_name,
               Object::dynamic_type());  // Type.
           temp_local->set_index(param_frame_index);
@@ -4053,14 +4094,16 @@
           temp_local->set_is_captured_parameter(true);
 
           // Copy parameter from local frame to current context.
-          Value* load = Bind(BuildLoadLocal(*temp_local));
-          Do(BuildStoreLocal(parameter, load));
+          Value* load = Bind(BuildLoadLocal(*temp_local, node->token_pos()));
+          Do(BuildStoreLocal(parameter, load, ST(node->token_pos())));
           // Write NULL to the source location to detect buggy accesses and
           // allow GC of passed value if it gets overwritten by a new value in
           // the function.
           Value* null_constant = Bind(new(Z) ConstantInstr(
               Object::ZoneHandle(Z, Object::null())));
-          Do(BuildStoreLocal(*temp_local, null_constant));
+          Do(BuildStoreLocal(*temp_local,
+                             null_constant,
+                             ST(node->token_pos())));
         }
       }
     }
@@ -4074,15 +4117,15 @@
     // basic block. Place this check at the last parameter to ensure parameters
     // are in scope in the debugger at method entry.
     const int num_params = function.NumParameters();
-    intptr_t check_pos = Scanner::kNoSourcePos;
+    intptr_t check_pos = Token::kNoSourcePos;
     if (num_params > 0) {
       const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
       check_pos = parameter.token_pos();
     }
-    if (check_pos < 0) {
+    if (!Token::IsDebugPause(check_pos)) {
       // No parameters or synthetic parameters.
       check_pos = node->token_pos();
-      ASSERT(check_pos >= 0);
+      ASSERT(Token::IsDebugPause(check_pos));
     }
     AddInstruction(new(Z) DebugStepCheckInstr(check_pos,
                                               RawPcDescriptors::kRuntimeCall));
@@ -4122,7 +4165,8 @@
                             NULL,
                             parameter.type(),
                             parameter.name())) {
-        Value* parameter_value = Bind(BuildLoadLocal(parameter));
+        Value* parameter_value =
+            Bind(BuildLoadLocal(parameter, parameter.token_pos()));
         Do(BuildAssertAssignable(parameter.token_pos(),
                                  parameter_value,
                                  parameter.type(),
@@ -4181,7 +4225,7 @@
     exit_ = NULL;
 
     LoadLocalNode* load_jump_count =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, jump_var);
+        new(Z) LoadLocalNode(node->token_pos(), jump_var);
     ComparisonNode* check_jump_count;
     const intptr_t num_await_states = owner()->await_joins()->length();
 
@@ -4189,12 +4233,12 @@
         Symbols::AwaitContextVar(), false);
     for (intptr_t i = 0; i < num_await_states; i++) {
       check_jump_count = new(Z) ComparisonNode(
-          Scanner::kNoSourcePos,
+          ST(node->token_pos()),
           Token::kEQ,
           load_jump_count,
           new(Z) LiteralNode(
-              Scanner::kNoSourcePos, Smi::ZoneHandle(Z, Smi::New(i))));
-      TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
+              ST(node->token_pos()), Smi::ZoneHandle(Z, Smi::New(i))));
+      TestGraphVisitor for_test(owner(), ST(node->token_pos()));
       check_jump_count->Visit(&for_test);
       EffectGraphVisitor for_true(owner());
       EffectGraphVisitor for_false(owner());
@@ -4206,7 +4250,7 @@
 
       // Restore the saved continuation context, i.e. the context that was
       // saved into :await_ctx_var before the closure suspended.
-      for_true.BuildRestoreContext(*old_context, Scanner::kNoSourcePos);
+      for_true.BuildRestoreContext(*old_context, ST(node->token_pos()));
 
       // Goto saved join.
       for_true.Goto((*owner()->await_joins())[i]);
@@ -4264,7 +4308,7 @@
   owner()->set_try_index(try_handler_index);
 
   // Preserve current context into local variable ':saved_try_context_var'.
-  BuildSaveContext(node->context_var(), node->token_pos());
+  BuildSaveContext(node->context_var(), ST(node->token_pos()));
 
   EffectGraphVisitor for_try(owner());
   node->try_block()->Visit(&for_try);
@@ -4341,11 +4385,11 @@
     node->rethrow_clause()->Visit(&for_finally);
     if (for_finally.is_open()) {
       // Rethrow the exception.  Manually build the graph for rethrow.
-      Value* exception = for_finally.Bind(
-          for_finally.BuildLoadLocal(catch_block->rethrow_exception_var()));
+      Value* exception = for_finally.Bind(for_finally.BuildLoadLocal(
+          catch_block->rethrow_exception_var(), finally_block->token_pos()));
       for_finally.PushArgument(exception);
-      Value* stacktrace = for_finally.Bind(
-          for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var()));
+      Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal(
+          catch_block->rethrow_stacktrace_var(), finally_block->token_pos()));
       for_finally.PushArgument(stacktrace);
       for_finally.AddInstruction(
           new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
@@ -4420,7 +4464,7 @@
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>();
   // Object receiver, actually a class literal of the unresolved method's owner.
-  Type& type = Type::ZoneHandle(
+  AbstractType& type = Type::ZoneHandle(
       Z,
       Type::New(function_class,
                 TypeArguments::Handle(Z, TypeArguments::null()),
@@ -4621,6 +4665,7 @@
   Report::MessageF(Report::kBailout,
                    Script::Handle(function.script()),
                    function.token_pos(),
+                   Report::AtLocation,
                    "FlowGraphBuilder Bailout: %s %s",
                    String::Handle(function.name()).ToCString(),
                    reason);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 94c9444..2c2d14d 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -303,16 +303,18 @@
   void AddReturnExit(intptr_t token_pos, Value* value);
 
  protected:
-  Definition* BuildStoreTemp(const LocalVariable& local, Value* value);
-  Definition* BuildStoreExprTemp(Value* value);
-  Definition* BuildLoadExprTemp();
+  Definition* BuildStoreTemp(const LocalVariable& local,
+                             Value* value,
+                             intptr_t token_pos);
+  Definition* BuildStoreExprTemp(Value* value, intptr_t token_pos);
+  Definition* BuildLoadExprTemp(intptr_t token_pos);
 
   Definition* BuildStoreLocal(const LocalVariable& local,
                               Value* value,
-                              intptr_t token_pos = Scanner::kNoSourcePos);
+                              intptr_t token_pos);
   Definition* BuildLoadLocal(const LocalVariable& local,
-                             intptr_t token_pos = Scanner::kNoSourcePos);
-  LoadLocalInstr* BuildLoadThisVar(LocalScope* scope);
+                             intptr_t token_pos);
+  LoadLocalInstr* BuildLoadThisVar(LocalScope* scope, intptr_t token_pos);
   LoadFieldInstr* BuildNativeGetter(
       NativeBodyNode* node,
       MethodRecognizer::Kind kind,
@@ -341,7 +343,7 @@
       PushArgumentInstr** push_instantiator_type_arguments);
   void BuildTypecheckArguments(intptr_t token_pos,
                                Value** instantiator_type_arguments);
-  Value* BuildInstantiator(const Class& instantiator_class);
+  Value* BuildInstantiator(intptr_t token_pos);
   Value* BuildInstantiatorTypeArguments(intptr_t token_pos,
                                         const Class& instantiator_class,
                                         Value* instantiator);
@@ -428,7 +430,7 @@
 
   void BuildClosureCall(ClosureCallNode* node, bool result_needed);
 
-  Value* BuildNullValue();
+  Value* BuildNullValue(intptr_t token_pos);
 
   // Returns true if the run-time type check can be eliminated.
   bool CanSkipTypeCheck(intptr_t token_pos,
@@ -438,8 +440,8 @@
 
   // Helpers for allocating and deallocating temporary locals on top of the
   // expression stack.
-  LocalVariable* EnterTempLocalScope(Value* value);
-  Definition* ExitTempLocalScope(LocalVariable* var);
+  LocalVariable* EnterTempLocalScope(Value* value, intptr_t token_pos);
+  Definition* ExitTempLocalScope(LocalVariable* var, intptr_t token_pos);
 
   void BuildLetTempExpressions(LetNode* node);
 
diff --git a/runtime/vm/flow_graph_builder_test.cc b/runtime/vm/flow_graph_builder_test.cc
index 91a13b2..2213d0b 100644
--- a/runtime/vm/flow_graph_builder_test.cc
+++ b/runtime/vm/flow_graph_builder_test.cc
@@ -95,6 +95,26 @@
     DUMP_ASSERT(count > 0);
   }
 
+  // Expect to find an instance call at |line| and |column|.
+  void InstanceCallAt(const char* needle,
+                      intptr_t line,
+                      intptr_t column = -1) {
+    ZoneGrowableArray<Instruction*>* instructions =
+        FindInstructionsAt(line, column);
+    intptr_t count = 0;
+    for (intptr_t i = 0; i < instructions->length(); i++) {
+      Instruction* instr = instructions->At(i);
+      EXPECT(instr != NULL);
+      if (instr->IsInstanceCall()) {
+        const char* haystack = instr->ToCString();
+        if (strstr(haystack, needle) != NULL) {
+          count++;
+        }
+      }
+    }
+    DUMP_ASSERT(count > 0);
+  }
+
   // Expect to find at least one static call at |line| and |column|. The
   // static call will have |needle| in its |ToCString| representation.
   void StaticCallAt(const char* needle,
@@ -146,9 +166,26 @@
     }
   }
 
+  // Fails if any of the IR nodes has a token position of Token::kNoSourcePos.
+  void EnsureSourcePositions() {
+    for (intptr_t i = 0; i < blocks_->length(); i++) {
+      BlockEntryInstr* entry = (*blocks_)[i];
+      DUMP_ASSERT(entry->token_pos() != Token::kNoSourcePos);
+      for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+        Instruction* instr = it.Current();
+        DUMP_ASSERT(instr->token_pos() != Token::kNoSourcePos);
+      }
+    }
+  }
+
  private:
   void DumpInstruction(Instruction* instr) {
-    const intptr_t token_pos = instr->token_pos();
+    intptr_t token_pos = instr->token_pos();
+    bool synthetic = false;
+    if (Token::IsSynthetic(token_pos)) {
+      synthetic = true;
+      token_pos = Token::FromSynthetic(token_pos);
+    }
     if (token_pos < 0) {
       const char* token_pos_string =
           ClassifyingTokenPositions::ToCString(token_pos);
@@ -161,10 +198,17 @@
                                   &token_line,
                                   &token_column,
                                   NULL);
-    THR_Print("       %02d:%02d -- %s\n",
-              static_cast<int>(token_line),
-              static_cast<int>(token_column),
-              instr->ToCString());
+    if (synthetic) {
+      THR_Print("      *%02d:%02d -- %s\n",
+                static_cast<int>(token_line),
+                static_cast<int>(token_column),
+                instr->ToCString());
+    } else {
+      THR_Print("       %02d:%02d -- %s\n",
+                static_cast<int>(token_line),
+                static_cast<int>(token_column),
+                instr->ToCString());
+    }
   }
 
   Instruction* FindFirstInstructionAt(intptr_t line, intptr_t column) {
@@ -185,6 +229,9 @@
       for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
         Instruction* instr = it.Current();
         intptr_t token_pos = instr->token_pos();
+        if (Token::IsSynthetic(token_pos)) {
+          token_pos = Token::FromSynthetic(token_pos);
+        }
         if (token_pos < 0) {
           continue;
         }
@@ -267,6 +314,8 @@
   spt.InstanceCallAt(4, 13, Token::kADD);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 5, 3);
   spt.FuzzyInstructionMatchAt("Return", 5, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -294,6 +343,8 @@
   spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
   spt.FuzzyInstructionMatchAt("Return", 7, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -323,6 +374,8 @@
   spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 10);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 3);
   spt.FuzzyInstructionMatchAt("Return", 7, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -370,6 +423,8 @@
   spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
   spt.FuzzyInstructionMatchAt("Return", 10, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -408,6 +463,8 @@
   spt.FuzzyInstructionMatchAt("LoadStaticField", 10, 10);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 10, 3);
   spt.FuzzyInstructionMatchAt("Return", 10, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -445,6 +502,8 @@
   spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
   spt.FuzzyInstructionMatchAt("Return", 6, 1);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -487,6 +546,8 @@
   spt.FuzzyInstructionMatchAt("Constant(#null)", 6, 1);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 6, 1);
   spt.FuzzyInstructionMatchAt("Return", 6, 1);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -535,6 +596,8 @@
   spt.FuzzyInstructionMatchAt("LoadLocal(z", 9, 10);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3);
   spt.FuzzyInstructionMatchAt("Return", 9, 3);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -563,6 +626,8 @@
   spt.FuzzyInstructionMatchAt("LoadStaticField", 7, 12);
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 5);
   spt.FuzzyInstructionMatchAt("Return", 7, 5);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -607,6 +672,8 @@
   spt.FuzzyInstructionMatchAt("Constant(#5", 7, 21);             // '5'
   spt.FuzzyInstructionMatchAt("DebugStepCheck", 7, 14);
   spt.FuzzyInstructionMatchAt("Return", 7, 14);
+
+  spt.EnsureSourcePositions();
 }
 
 
@@ -657,6 +724,82 @@
 
   spt.FuzzyInstructionMatchAt("Constant(#99", 10, 12);                 // '9'
   spt.FuzzyInstructionMatchAt("Return", 10, 5);                        // 'r'
+
+  spt.EnsureSourcePositions();
+}
+
+
+TEST_CASE(SourcePosition_InstanceFields) {
+  const char* kScript =
+      "class A {\n"
+      "  var x;\n"
+      "  var y;\n"
+      "}\n"
+      "main() {\n"
+      "  var z = new A();\n"
+      "  z.x = 99;\n"
+      "  z.y = z.x;\n"
+      "  return z.y;\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("main");
+  spt.FuzzyInstructionMatchAt("AllocateObject(A)", 6, 15);       // 'A'
+  spt.FuzzyInstructionMatchAt("StaticCall", 6, 15);              // 'A'
+  spt.FuzzyInstructionMatchAt("StoreLocal(z", 6, 9);             // '='
+  spt.InstanceCallAt("set:x", 7, 5);                             // 'x'
+  spt.InstanceCallAt("get:x", 8, 11);                            // 'x'
+  spt.InstanceCallAt("set:y", 8, 5);                             // 'y'
+
+  spt.InstanceCallAt("get:y", 9, 12);                            // 'y'
+  spt.FuzzyInstructionMatchAt("DebugStepCheck", 9, 3);
+  spt.FuzzyInstructionMatchAt("Return", 9, 3);
+
+  spt.EnsureSourcePositions();
+}
+
+
+TEST_CASE(SourcePosition_Async) {
+  const char* kScript =
+      "import 'dart:async';\n"
+      "var x = 5;\n"
+      "var y = 5;\n"
+      "foo(Future f1, Future f2) async {\n"
+      "  await f1;\n"
+      "  await f2;\n"
+      "  return 55;\n"
+      "}\n"
+      "main() {\n"
+      "  foo(new Future.value(33));\n"
+      "}\n";
+
+  SourcePositionTest spt(thread, kScript);
+  spt.BuildGraphFor("foo");
+  spt.EnsureSourcePositions();
+  spt.Dump();
+}
+
+
+static bool SyntheticRoundTripTest(intptr_t token_pos) {
+  return Token::FromSynthetic(Token::ToSynthetic(token_pos)) == token_pos;
+}
+
+
+UNIT_TEST_CASE(SourcePosition_SyntheticTokens) {
+  EXPECT(Token::kNoSourcePos == -1);
+  EXPECT(Token::kMinSourcePos == 0);
+  EXPECT(Token::kMaxSourcePos > 0);
+
+  EXPECT(!Token::IsSynthetic(0));
+  EXPECT(Token::IsSynthetic(Token::ToSynthetic(0)));
+  EXPECT(Token::IsSynthetic(Token::ToSynthetic(9)));
+  EXPECT(!Token::IsSynthetic(Token::FromSynthetic(-1)));
+  EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kPrivate));
+  EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kLast));
+
+  EXPECT(SyntheticRoundTripTest(0));
+  EXPECT(SyntheticRoundTripTest(Token::kMaxSourcePos));
+  EXPECT(SyntheticRoundTripTest(Token::kMinSourcePos));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 1f02942..eabcbf1 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -627,6 +627,7 @@
   Report::MessageF(Report::kBailout,
                    Script::Handle(function.script()),
                    function.token_pos(),
+                   Report::AtLocation,
                    "FlowGraphCompiler Bailout: %s %s",
                    String::Handle(function.name()).ToCString(),
                    reason);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index abd8b65..429631f 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -273,7 +273,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
+  ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
   const Register kInstanceReg = R0;
   Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
@@ -286,15 +286,15 @@
   } else {
     __ b(is_not_instance_lbl, EQ);
   }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-      type_arguments.IsRaw(from_index, num_type_params);
-  // Signature class is an instantiated parameterized type.
-  if (!type_class.IsSignatureClass()) {
+  // A function type test requires checking the function signature.
+  if (!type.IsFunctionType()) {
+    const intptr_t num_type_args = type_class.NumTypeArguments();
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::ZoneHandle(zone(), type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
     if (is_raw_type) {
       const Register kClassIdReg = R2;
       // dynamic type argument, check only classes.
@@ -362,6 +362,10 @@
     Label* is_not_instance_lbl) {
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
+  if (type.IsFunctionType()) {
+    // Fallthrough.
+    return true;
+  }
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -392,12 +396,10 @@
     __ b(is_not_instance_lbl);
     return false;
   }
-  if (type.IsFunctionType()) {
+  if (type.IsDartFunctionType()) {
     // Check if instance is a closure.
-    __ LoadClassById(R3, kClassIdReg);
-    __ ldr(R3, FieldAddress(R3, Class::signature_function_offset()));
-    __ CompareObject(R3, Object::null_object());
-    __ b(is_instance_lbl, NE);
+    __ CompareImmediate(kClassIdReg, kClosureCid);
+    __ b(is_instance_lbl, EQ);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -505,7 +507,7 @@
     __ Bind(&fall_through);
     return type_test_cache.raw();
   }
-  if (type.IsType()) {
+  if (type.IsType() || type.IsFunctionType()) {
     const Register kInstanceReg = R0;
     const Register kTypeArgumentsReg = R1;
     __ tst(kInstanceReg, Operand(kSmiTagMask));  // Is instance Smi?
@@ -547,10 +549,10 @@
   }
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type of a
-    // non-parameterized class, non-signature class, or with a raw dst type of
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
     // a parameterized class.
-    if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
+    if (type.IsFunctionType() || (type_class.NumTypeArguments() > 0)) {
       return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
                                                        type,
                                                        is_instance_lbl,
@@ -673,7 +675,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 359c89c..977010a 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -265,7 +265,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
+  ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
   const Register kInstanceReg = R0;
   Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
@@ -278,15 +278,15 @@
   } else {
     __ b(is_not_instance_lbl, EQ);
   }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-      type_arguments.IsRaw(from_index, num_type_params);
-  // Signature class is an instantiated parameterized type.
-  if (!type_class.IsSignatureClass()) {
+  // A function type test requires checking the function signature.
+  if (!type.IsFunctionType()) {
+    const intptr_t num_type_args = type_class.NumTypeArguments();
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::ZoneHandle(zone(), type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
     if (is_raw_type) {
       const Register kClassIdReg = R2;
       // dynamic type argument, check only classes.
@@ -354,6 +354,10 @@
     Label* is_not_instance_lbl) {
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
+  if (type.IsFunctionType()) {
+    // Fallthrough.
+    return true;
+  }
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -384,12 +388,10 @@
     __ b(is_not_instance_lbl);
     return false;
   }
-  if (type.IsFunctionType()) {
+  if (type.IsDartFunctionType()) {
     // Check if instance is a closure.
-    __ LoadClassById(R3, kClassIdReg);
-    __ LoadFieldFromOffset(R3, R3, Class::signature_function_offset());
-    __ CompareObject(R3, Object::null_object());
-    __ b(is_instance_lbl, NE);
+    __ CompareImmediate(kClassIdReg, kClosureCid);
+    __ b(is_instance_lbl, EQ);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -497,7 +499,7 @@
     __ Bind(&fall_through);
     return type_test_cache.raw();
   }
-  if (type.IsType()) {
+  if (type.IsType() || type.IsFunctionType()) {
     const Register kInstanceReg = R0;
     const Register kTypeArgumentsReg = R1;
     __ tsti(kInstanceReg, Immediate(kSmiTagMask));  // Is instance Smi?
@@ -539,10 +541,10 @@
   }
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type of a
-    // non-parameterized class, non-signature class, or with a raw dst type of
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
     // a parameterized class.
-    if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
+    if (type.IsFunctionType() || (type_class.NumTypeArguments() > 0)) {
       return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
                                                        type,
                                                        is_instance_lbl,
@@ -665,7 +667,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index b2272fe9..3a2ee04 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -277,7 +277,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
+  ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
   const Register kInstanceReg = EAX;
   Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
@@ -290,15 +290,15 @@
   } else {
     __ j(ZERO, is_not_instance_lbl);
   }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-      type_arguments.IsRaw(from_index, num_type_params);
-  // Signature class is an instantiated parameterized type.
-  if (!type_class.IsSignatureClass()) {
+  // A function type test requires checking the function signature.
+  if (!type.IsFunctionType()) {
+    const intptr_t num_type_args = type_class.NumTypeArguments();
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::ZoneHandle(zone(), type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
     if (is_raw_type) {
       const Register kClassIdReg = ECX;
       // dynamic type argument, check only classes.
@@ -365,6 +365,10 @@
     Label* is_not_instance_lbl) {
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
+  if (type.IsFunctionType()) {
+    // Fallthrough.
+    return true;
+  }
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -395,14 +399,10 @@
     __ jmp(is_not_instance_lbl);
     return false;
   }
-  if (type.IsFunctionType()) {
+  if (type.IsDartFunctionType()) {
     // Check if instance is a closure.
-    const Immediate& raw_null =
-        Immediate(reinterpret_cast<intptr_t>(Object::null()));
-    __ LoadClassById(EDI, kClassIdReg);
-    __ movl(EDI, FieldAddress(EDI, Class::signature_function_offset()));
-    __ cmpl(EDI, raw_null);
-    __ j(NOT_EQUAL, is_instance_lbl);
+    __ cmpl(kClassIdReg, Immediate(kClosureCid));
+    __ j(EQUAL, is_instance_lbl);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -513,7 +513,7 @@
     __ Bind(&fall_through);
     return type_test_cache.raw();
   }
-  if (type.IsType()) {
+  if (type.IsType() || type.IsFunctionType()) {
     const Register kInstanceReg = EAX;
     const Register kTypeArgumentsReg = EDX;
     __ testl(kInstanceReg, Immediate(kSmiTagMask));  // Is instance Smi?
@@ -555,10 +555,10 @@
   }
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type of a
-    // non-parameterized class, non-signature class, or with a raw dst type of
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
     // a parameterized class.
-    if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
+    if (type.IsFunctionType() || (type_class.NumTypeArguments() > 0)) {
       return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
                                                        type,
                                                        is_instance_lbl,
@@ -684,7 +684,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index f98bb67..a6fef0b 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -265,7 +265,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
+  ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
   const Register kInstanceReg = A0;
   Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
@@ -278,15 +278,15 @@
   } else {
     __ beq(CMPRES1, ZR, is_not_instance_lbl);
   }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-      type_arguments.IsRaw(from_index, num_type_params);
-  // Signature class is an instantiated parameterized type.
-  if (!type_class.IsSignatureClass()) {
+  // A function type test requires checking the function signature.
+  if (!type.IsFunctionType()) {
+    const intptr_t num_type_args = type_class.NumTypeArguments();
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::ZoneHandle(zone(), type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
     if (is_raw_type) {
       const Register kClassIdReg = T0;
       // dynamic type argument, check only classes.
@@ -353,6 +353,10 @@
     Label* is_not_instance_lbl) {
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
+  if (type.IsFunctionType()) {
+    // Fallthrough.
+    return true;
+  }
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -382,11 +386,9 @@
     __ b(is_not_instance_lbl);
     return false;
   }
-  if (type.IsFunctionType()) {
+  if (type.IsDartFunctionType()) {
     // Check if instance is a closure.
-    __ LoadClassById(T1, kClassIdReg);
-    __ lw(T1, FieldAddress(T1, Class::signature_function_offset()));
-    __ BranchNotEqual(T1, Object::null_object(), is_instance_lbl);
+    __ BranchEqual(kClassIdReg, Immediate(kClosureCid), is_instance_lbl);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -493,7 +495,7 @@
     __ Bind(&fall_through);
     return type_test_cache.raw();
   }
-  if (type.IsType()) {
+  if (type.IsType() || type.IsFunctionType()) {
     const Register kInstanceReg = A0;
     const Register kTypeArgumentsReg = A1;
     __ andi(CMPRES1, kInstanceReg, Immediate(kSmiTagMask));
@@ -535,10 +537,10 @@
   }
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type of a
-    // non-parameterized class, non-signature class, or with a raw dst type of
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
     // a parameterized class.
-    if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
+    if (type.IsFunctionType() || (type_class.NumTypeArguments() > 0)) {
       return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
                                                        type,
                                                        is_instance_lbl,
@@ -667,7 +669,7 @@
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
   __ Comment("AssertAssignable");
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index e54b1eb..4662afb 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -274,7 +274,7 @@
   __ Comment("InstantiatedTypeWithArgumentsTest");
   ASSERT(type.IsInstantiated());
   const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-  ASSERT((type_class.NumTypeArguments() > 0) || type_class.IsSignatureClass());
+  ASSERT(type.IsFunctionType() || (type_class.NumTypeArguments() > 0));
   const Register kInstanceReg = RAX;
   Error& bound_error = Error::Handle(zone());
   const Type& int_type = Type::Handle(zone(), Type::IntType());
@@ -287,15 +287,15 @@
   } else {
     __ j(ZERO, is_not_instance_lbl);
   }
-  const intptr_t num_type_args = type_class.NumTypeArguments();
-  const intptr_t num_type_params = type_class.NumTypeParameters();
-  const intptr_t from_index = num_type_args - num_type_params;
-  const TypeArguments& type_arguments =
-      TypeArguments::ZoneHandle(zone(), type.arguments());
-  const bool is_raw_type = type_arguments.IsNull() ||
-      type_arguments.IsRaw(from_index, num_type_params);
-  // Signature class is an instantiated parameterized type.
-  if (!type_class.IsSignatureClass()) {
+  // A function type test requires checking the function signature.
+  if (!type.IsFunctionType()) {
+    const intptr_t num_type_args = type_class.NumTypeArguments();
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::ZoneHandle(zone(), type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
     if (is_raw_type) {
       const Register kClassIdReg = R10;
       // dynamic type argument, check only classes.
@@ -362,6 +362,10 @@
     Label* is_not_instance_lbl) {
   __ Comment("InstantiatedTypeNoArgumentsTest");
   ASSERT(type.IsInstantiated());
+  if (type.IsFunctionType()) {
+    // Fallthrough.
+    return true;
+  }
   const Class& type_class = Class::Handle(zone(), type.type_class());
   ASSERT(type_class.NumTypeArguments() == 0);
 
@@ -392,12 +396,10 @@
     __ jmp(is_not_instance_lbl);
     return false;
   }
-  if (type.IsFunctionType()) {
+  if (type.IsDartFunctionType()) {
     // Check if instance is a closure.
-    __ LoadClassById(R13, kClassIdReg);
-    __ movq(R13, FieldAddress(R13, Class::signature_function_offset()));
-    __ CompareObject(R13, Object::null_object());
-    __ j(NOT_EQUAL, is_instance_lbl);
+    __ cmpq(kClassIdReg, Immediate(kClosureCid));
+    __ j(EQUAL, is_instance_lbl);
   }
   // Custom checking for numbers (Smi, Mint, Bigint and Double).
   // Note that instance is not Smi (checked above).
@@ -507,7 +509,7 @@
     __ Bind(&fall_through);
     return type_test_cache.raw();
   }
-  if (type.IsType()) {
+  if (type.IsType() || type.IsFunctionType()) {
     const Register kInstanceReg = RAX;
     const Register kTypeArgumentsReg = RDX;
     __ testq(kInstanceReg, Immediate(kSmiTagMask));  // Is instance Smi?
@@ -549,10 +551,10 @@
   }
   if (type.IsInstantiated()) {
     const Class& type_class = Class::ZoneHandle(zone(), type.type_class());
-    // A class equality check is only applicable with a dst type of a
-    // non-parameterized class, non-signature class, or with a raw dst type of
+    // A class equality check is only applicable with a dst type (not a
+    // function type) of a non-parameterized class or with a raw dst type of
     // a parameterized class.
-    if (type_class.IsSignatureClass() || (type_class.NumTypeArguments() > 0)) {
+    if (type.IsFunctionType() || (type_class.NumTypeArguments() > 0)) {
       return GenerateInstantiatedTypeWithArgumentsTest(token_pos,
                                                        type,
                                                        is_instance_lbl,
@@ -676,7 +678,7 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index bc5d7bc..1b39f97 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -687,213 +687,236 @@
     // Save and clear deopt id.
     const intptr_t prev_deopt_id = thread()->deopt_id();
     thread()->set_deopt_id(0);
-    // Install bailout jump.
-    LongJumpScope jump;
-    if (setjmp(*jump.Set()) == 0) {
-      // Parse the callee function.
-      bool in_cache;
-      ParsedFunction* parsed_function;
-      {
-        CSTAT_TIMER_SCOPE(thread(), graphinliner_parse_timer);
-        parsed_function = GetParsedFunction(function, &in_cache);
-      }
+    Error& error = Error::Handle();
+    {
+      // Install bailout jump.
+      LongJumpScope jump;
+      if (setjmp(*jump.Set()) == 0) {
+        // Parse the callee function.
+        bool in_cache;
+        ParsedFunction* parsed_function;
+        {
+          CSTAT_TIMER_SCOPE(thread(), graphinliner_parse_timer);
+          parsed_function = GetParsedFunction(function, &in_cache);
+        }
 
-      // Load IC data for the callee.
-      ZoneGrowableArray<const ICData*>* ic_data_array =
-            new(Z) ZoneGrowableArray<const ICData*>();
-      const bool clone_descriptors = Compiler::IsBackgroundCompilation();
-      function.RestoreICDataMap(ic_data_array, clone_descriptors);
+        // Load IC data for the callee.
+        ZoneGrowableArray<const ICData*>* ic_data_array =
+              new(Z) ZoneGrowableArray<const ICData*>();
+        const bool clone_descriptors = Compiler::IsBackgroundCompilation();
+        function.RestoreICDataMap(ic_data_array, clone_descriptors);
 
-      // Build the callee graph.
-      InlineExitCollector* exit_collector =
-          new(Z) InlineExitCollector(caller_graph_, call);
-      FlowGraphBuilder builder(*parsed_function,
-                               *ic_data_array,
-                               exit_collector,
-                               Compiler::kNoOSRDeoptId);
-      builder.SetInitialBlockId(caller_graph_->max_block_id());
-      FlowGraph* callee_graph;
-      {
-        CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
-        callee_graph = builder.BuildGraph();
-      }
+        // Build the callee graph.
+        InlineExitCollector* exit_collector =
+            new(Z) InlineExitCollector(caller_graph_, call);
+        FlowGraphBuilder builder(*parsed_function,
+                                 *ic_data_array,
+                                 exit_collector,
+                                 Compiler::kNoOSRDeoptId);
+        builder.SetInitialBlockId(caller_graph_->max_block_id());
+        FlowGraph* callee_graph;
+        {
+          CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
+          callee_graph = builder.BuildGraph();
+        }
 
-      // The parameter stubs are a copy of the actual arguments providing
-      // concrete information about the values, for example constant values,
-      // without linking between the caller and callee graphs.
-      // TODO(zerny): Put more information in the stubs, eg, type information.
-      ZoneGrowableArray<Definition*>* param_stubs =
-          new(Z) ZoneGrowableArray<Definition*>(
-              function.NumParameters());
+        // The parameter stubs are a copy of the actual arguments providing
+        // concrete information about the values, for example constant values,
+        // without linking between the caller and callee graphs.
+        // TODO(zerny): Put more information in the stubs, eg, type information.
+        ZoneGrowableArray<Definition*>* param_stubs =
+            new(Z) ZoneGrowableArray<Definition*>(
+                function.NumParameters());
 
-      // Create a parameter stub for each fixed positional parameter.
-      for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) {
-        param_stubs->Add(CreateParameterStub(i, (*arguments)[i], callee_graph));
-      }
+        // Create a parameter stub for each fixed positional parameter.
+        for (intptr_t i = 0; i < function.num_fixed_parameters(); ++i) {
+          param_stubs->Add(CreateParameterStub(i, (*arguments)[i],
+                                               callee_graph));
+        }
 
-      // If the callee has optional parameters, rebuild the argument and stub
-      // arrays so that actual arguments are in one-to-one with the formal
-      // parameters.
-      if (function.HasOptionalParameters()) {
-        TRACE_INLINING(THR_Print("     adjusting for optional parameters\n"));
-        if (!AdjustForOptionalParameters(*parsed_function,
-                                         argument_names,
-                                         arguments,
-                                         param_stubs,
-                                         callee_graph)) {
-          function.set_is_inlinable(false);
-          TRACE_INLINING(THR_Print("     Bailout: optional arg mismatch\n"));
-          PRINT_INLINING_TREE("Optional arg mismatch",
+        // If the callee has optional parameters, rebuild the argument and stub
+        // arrays so that actual arguments are in one-to-one with the formal
+        // parameters.
+        if (function.HasOptionalParameters()) {
+          TRACE_INLINING(THR_Print("     adjusting for optional parameters\n"));
+          if (!AdjustForOptionalParameters(*parsed_function,
+                                           argument_names,
+                                           arguments,
+                                           param_stubs,
+                                           callee_graph)) {
+            function.set_is_inlinable(false);
+            TRACE_INLINING(THR_Print("     Bailout: optional arg mismatch\n"));
+            PRINT_INLINING_TREE("Optional arg mismatch",
+                &call_data->caller, &function, call_data->call);
+            return false;
+          }
+        }
+
+        // After treating optional parameters the actual/formal count must
+        // match.
+        ASSERT(arguments->length() == function.NumParameters());
+        ASSERT(param_stubs->length() == callee_graph->parameter_count());
+
+        // Update try-index of the callee graph.
+        BlockEntryInstr* call_block = call_data->call->GetBlock();
+        if (call_block->InsideTryBlock()) {
+          intptr_t try_index = call_block->try_index();
+          for (BlockIterator it = callee_graph->reverse_postorder_iterator();
+               !it.Done(); it.Advance()) {
+            BlockEntryInstr* block = it.Current();
+            block->set_try_index(try_index);
+          }
+        }
+
+        BlockScheduler block_scheduler(callee_graph);
+        block_scheduler.AssignEdgeWeights();
+
+        {
+          CSTAT_TIMER_SCOPE(thread(), graphinliner_ssa_timer);
+          // Compute SSA on the callee graph, catching bailouts.
+          callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
+                                   param_stubs);
+          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+        }
+
+        {
+          CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
+          // TODO(fschneider): Improve suppression of speculative inlining.
+          // Deopt-ids overlap between caller and callee.
+          FlowGraphOptimizer optimizer(callee_graph,
+                                       inliner_->use_speculative_inlining_,
+                                       inliner_->inlining_black_list_);
+          if (Compiler::always_optimize()) {
+            optimizer.PopulateWithICData();
+
+            optimizer.ApplyClassIds();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+            FlowGraphTypePropagator::Propagate(callee_graph);
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+          }
+          optimizer.ApplyICData();
+          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+          // Optimize (a << b) & c patterns, merge instructions. Must occur
+          // before 'SelectRepresentations' which inserts conversion nodes.
+          optimizer.TryOptimizePatterns();
+          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+        }
+
+        if (FLAG_trace_inlining &&
+            (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
+          THR_Print("Callee graph for inlining %s\n",
+                    function.ToFullyQualifiedCString());
+          FlowGraphPrinter printer(*callee_graph);
+          printer.PrintBlocks();
+        }
+
+        // Collect information about the call site and caller graph.
+        // TODO(zerny): Do this after CP and dead code elimination.
+        intptr_t constants_count = 0;
+        for (intptr_t i = 0; i < param_stubs->length(); ++i) {
+          if ((*param_stubs)[i]->IsConstant()) ++constants_count;
+        }
+
+        FlowGraphInliner::CollectGraphInfo(callee_graph);
+        const intptr_t size = function.optimized_instruction_count();
+        const intptr_t call_site_count = function.optimized_call_site_count();
+
+        function.set_optimized_instruction_count(size);
+        function.set_optimized_call_site_count(call_site_count);
+
+        // Use heuristics do decide if this call should be inlined.
+        if (!ShouldWeInline(function, size, call_site_count, constants_count)) {
+          // If size is larger than all thresholds, don't consider it again.
+          if ((size > FLAG_inlining_size_threshold) &&
+              (call_site_count > FLAG_inlining_callee_call_sites_threshold) &&
+              (size > FLAG_inlining_constant_arguments_min_size_threshold) &&
+              (size > FLAG_inlining_constant_arguments_max_size_threshold)) {
+            function.set_is_inlinable(false);
+          }
+          thread()->set_deopt_id(prev_deopt_id);
+          TRACE_INLINING(THR_Print("     Bailout: heuristics with "
+                                   "code size:  %" Pd ", "
+                                   "call sites: %" Pd ", "
+                                   "const args: %" Pd "\n",
+                                   size,
+                                   call_site_count,
+                                   constants_count));
+          PRINT_INLINING_TREE("Heuristic fail",
               &call_data->caller, &function, call_data->call);
           return false;
         }
-      }
 
-      // After treating optional parameters the actual/formal count must match.
-      ASSERT(arguments->length() == function.NumParameters());
-      ASSERT(param_stubs->length() == callee_graph->parameter_count());
+        // Inline dispatcher methods regardless of the current depth.
+        const intptr_t depth =
+            (function.IsInvokeFieldDispatcher() ||
+             function.IsNoSuchMethodDispatcher()) ? 0 : inlining_depth_;
+        collected_call_sites_->FindCallSites(callee_graph, depth,
+                                             &inlined_info_);
 
-      // Update try-index of the callee graph.
-      BlockEntryInstr* call_block = call_data->call->GetBlock();
-      if (call_block->InsideTryBlock()) {
-        intptr_t try_index = call_block->try_index();
-        for (BlockIterator it = callee_graph->reverse_postorder_iterator();
-             !it.Done(); it.Advance()) {
-          BlockEntryInstr* block = it.Current();
-          block->set_try_index(try_index);
+        // Add the function to the cache.
+        if (!in_cache) {
+          function_cache_.Add(parsed_function);
         }
-      }
 
-      BlockScheduler block_scheduler(callee_graph);
-      block_scheduler.AssignEdgeWeights();
-
-      {
-        CSTAT_TIMER_SCOPE(thread(), graphinliner_ssa_timer);
-        // Compute SSA on the callee graph, catching bailouts.
-        callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(),
-                                 param_stubs);
-        DEBUG_ASSERT(callee_graph->VerifyUseLists());
-      }
-
-      {
-        CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
-        // TODO(fschneider): Improve suppression of speculative inlining.
-        // Deopt-ids overlap between caller and callee.
-        FlowGraphOptimizer optimizer(callee_graph,
-                                     inliner_->use_speculative_inlining_,
-                                     inliner_->inlining_black_list_);
-        if (Compiler::always_optimize()) {
-          optimizer.PopulateWithICData();
-
-          optimizer.ApplyClassIds();
-          DEBUG_ASSERT(callee_graph->VerifyUseLists());
-
-          FlowGraphTypePropagator::Propagate(callee_graph);
-          DEBUG_ASSERT(callee_graph->VerifyUseLists());
-        }
-        optimizer.ApplyICData();
-        DEBUG_ASSERT(callee_graph->VerifyUseLists());
-
-        // Optimize (a << b) & c patterns, merge instructions. Must occur before
-        // 'SelectRepresentations' which inserts conversion nodes.
-        optimizer.TryOptimizePatterns();
-        DEBUG_ASSERT(callee_graph->VerifyUseLists());
-      }
-
-      if (FLAG_trace_inlining &&
-          (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) {
-        THR_Print("Callee graph for inlining %s\n",
-                  function.ToFullyQualifiedCString());
-        FlowGraphPrinter printer(*callee_graph);
-        printer.PrintBlocks();
-      }
-
-      // Collect information about the call site and caller graph.
-      // TODO(zerny): Do this after CP and dead code elimination.
-      intptr_t constants_count = 0;
-      for (intptr_t i = 0; i < param_stubs->length(); ++i) {
-        if ((*param_stubs)[i]->IsConstant()) ++constants_count;
-      }
-
-      FlowGraphInliner::CollectGraphInfo(callee_graph);
-      const intptr_t size = function.optimized_instruction_count();
-      const intptr_t call_site_count = function.optimized_call_site_count();
-
-      function.set_optimized_instruction_count(size);
-      function.set_optimized_call_site_count(call_site_count);
-
-      // Use heuristics do decide if this call should be inlined.
-      if (!ShouldWeInline(function, size, call_site_count, constants_count)) {
-        // If size is larger than all thresholds, don't consider it again.
-        if ((size > FLAG_inlining_size_threshold) &&
-            (call_site_count > FLAG_inlining_callee_call_sites_threshold) &&
-            (size > FLAG_inlining_constant_arguments_min_size_threshold) &&
-            (size > FLAG_inlining_constant_arguments_max_size_threshold)) {
-          function.set_is_inlinable(false);
+        // Build succeeded so we restore the bailout jump.
+        inlined_ = true;
+        inlined_size_ += size;
+        if (is_recursive_call) {
+          inlined_recursive_call_ = true;
         }
         thread()->set_deopt_id(prev_deopt_id);
-        TRACE_INLINING(THR_Print("     Bailout: heuristics with "
-                                 "code size:  %" Pd ", "
-                                 "call sites: %" Pd ", "
-                                 "const args: %" Pd "\n",
-                                 size,
-                                 call_site_count,
-                                 constants_count));
-        PRINT_INLINING_TREE("Heuristic fail",
-            &call_data->caller, &function, call_data->call);
-        return false;
+
+        call_data->callee_graph = callee_graph;
+        call_data->parameter_stubs = param_stubs;
+        call_data->exit_collector = exit_collector;
+
+        // When inlined, we add the guarded fields of the callee to the caller's
+        // list of guarded fields.
+        for (intptr_t i = 0;
+             i < callee_graph->guarded_fields()->length();
+             ++i) {
+          FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
+                                        (*callee_graph->guarded_fields())[i]);
+        }
+        // When inlined, we add the deferred prefixes of the callee to the
+        // caller's list of deferred prefixes.
+        caller_graph()->AddToDeferredPrefixes(
+            callee_graph->deferred_prefixes());
+
+        FlowGraphInliner::SetInliningId(callee_graph,
+            inliner_->NextInlineId(callee_graph->function(),
+                                   call_data->caller_inlining_id_));
+        TRACE_INLINING(THR_Print("     Success\n"));
+        PRINT_INLINING_TREE(NULL,
+            &call_data->caller, &function, call);
+        return true;
+      } else {
+        error = isolate()->object_store()->sticky_error();
+        isolate()->object_store()->clear_sticky_error();
+        ASSERT(error.IsLanguageError());
+
+        if (LanguageError::Cast(error).kind() == Report::kBailout) {
+          thread()->set_deopt_id(prev_deopt_id);
+          TRACE_INLINING(THR_Print("     Bailout: %s\n",
+                                   error.ToErrorCString()));
+          PRINT_INLINING_TREE("Bailout",
+              &call_data->caller, &function, call);
+          return false;
+        } else {
+          // Fall through to exit long jump scope.
+        }
       }
-
-      // Inline dispatcher methods regardless of the current depth.
-      const intptr_t depth =
-          (function.IsInvokeFieldDispatcher() ||
-           function.IsNoSuchMethodDispatcher()) ? 0 : inlining_depth_;
-      collected_call_sites_->FindCallSites(callee_graph, depth, &inlined_info_);
-
-      // Add the function to the cache.
-      if (!in_cache) {
-        function_cache_.Add(parsed_function);
-      }
-
-      // Build succeeded so we restore the bailout jump.
-      inlined_ = true;
-      inlined_size_ += size;
-      if (is_recursive_call) {
-        inlined_recursive_call_ = true;
-      }
-      thread()->set_deopt_id(prev_deopt_id);
-
-      call_data->callee_graph = callee_graph;
-      call_data->parameter_stubs = param_stubs;
-      call_data->exit_collector = exit_collector;
-
-      // When inlined, we add the guarded fields of the callee to the caller's
-      // list of guarded fields.
-      for (intptr_t i = 0; i < callee_graph->guarded_fields()->length(); ++i) {
-        FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
-                                      (*callee_graph->guarded_fields())[i]);
-      }
-      // When inlined, we add the deferred prefixes of the callee to the
-      // caller's list of deferred prefixes.
-      caller_graph()->AddToDeferredPrefixes(callee_graph->deferred_prefixes());
-
-      FlowGraphInliner::SetInliningId(callee_graph,
-          inliner_->NextInlineId(callee_graph->function(),
-                                 call_data->caller_inlining_id_));
-      TRACE_INLINING(THR_Print("     Success\n"));
-      PRINT_INLINING_TREE(NULL,
-          &call_data->caller, &function, call);
-      return true;
-    } else {
-      Error& error = Error::Handle();
-      error = isolate()->object_store()->sticky_error();
-      isolate()->object_store()->clear_sticky_error();
-      thread()->set_deopt_id(prev_deopt_id);
-      TRACE_INLINING(THR_Print("     Bailout: %s\n", error.ToErrorCString()));
-      PRINT_INLINING_TREE("Bailout",
-          &call_data->caller, &function, call);
-      return false;
     }
+
+    // Propagate a compile-time error. Only in precompilation do we attempt to
+    // inline functions that have never been compiled before; when JITing we
+    // should only see compile-time errors in unoptimized compilation.
+    ASSERT(Compiler::always_optimize());
+    Thread::Current()->long_jump_base()->Jump(1, error);
+    UNREACHABLE();
+    return false;
   }
 
   void PrintInlinedInfo(const Function& top) {
@@ -1105,14 +1128,13 @@
           call->ArgumentAt(0)->OriginalDefinition()->AsAllocateObject();
       if ((alloc != NULL) && !alloc->closure_function().IsNull()) {
         target ^= alloc->closure_function().raw();
-        ASSERT(target.signature_class() == alloc->cls().raw());
+        ASSERT(alloc->cls().IsClosureClass());
       }
       ConstantInstr* constant =
           call->ArgumentAt(0)->OriginalDefinition()->AsConstant();
       if ((constant != NULL) &&
-          constant->value().IsInstance() &&
-          Instance::Cast(constant->value()).IsClosure()) {
-        target ^= Closure::function(Instance::Cast(constant->value()));
+          constant->value().IsClosure()) {
+        target ^= Closure::Cast(constant->value()).function();
       }
 
       if (target.IsNull()) {
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index c36bf53..ecc3350 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -225,14 +225,6 @@
       // finalized yet.
       return false;
     }
-    // Do not run the optimization below if in background compilation since
-    // resolution of method extractor functions may create new signature
-    // classes.
-    // TODO(regis): Remove test for background compilation once signature
-    // classes are not generated any longer.
-    if (!thread()->IsMutatorThread()) {
-      return false;
-    }
     const Array& args_desc_array = Array::Handle(Z,
         ArgumentsDescriptor::New(call->ArgumentCount(),
                                  call->argument_names()));
@@ -284,12 +276,7 @@
   }
 
   // Check if getter or setter in function's class and class is currently leaf.
-  // Do not run the optimization below if in background compilation since
-  // resolution of getter functions may create new signature classes.
-  // TODO(regis): Remove test for background compilation once signature classes
-  // are not generated any longer.
-  if (thread()->IsMutatorThread() &&
-      FLAG_guess_icdata_cid &&
+  if (FLAG_guess_icdata_cid &&
       ((call->token_kind() == Token::kGET) ||
           (call->token_kind() == Token::kSET))) {
     const Class& owner_class = Class::Handle(Z, function().Owner());
@@ -3904,7 +3891,8 @@
     ZoneGrowableArray<intptr_t>* results) const {
   ASSERT(results->is_empty());
   ASSERT(ic_data.NumArgsTested() == 1);  // Unary checks only.
-  if (!type.IsInstantiated() || type.IsMalformedOrMalbounded()) {
+  if (type.IsFunctionType() || type.IsDartFunctionType() ||
+      !type.IsInstantiated() || type.IsMalformedOrMalbounded()) {
     return Bool::null();
   }
   const Class& type_class = Class::Handle(Z, type.type_class());
@@ -3959,9 +3947,9 @@
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
   // Requires CHA.
   if (!type.IsInstantiated()) return false;
+  // Function types have different type checking rules.
+  if (type.IsFunctionType()) return false;
   const Class& type_class = Class::Handle(type.type_class());
-  // Signature classes have different type checking rules.
-  if (type_class.IsSignatureClass()) return false;
   // Could be an interface check?
   if (CHA::IsImplemented(type_class)) return false;
   // Check if there are subclasses.
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 7ea528a..85371e0 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -489,15 +489,15 @@
       cid_ = kDynamicCid;
     } else if (type_->IsVoidType()) {
       cid_ = kNullCid;
+    } else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
+      cid_ = kClosureCid;
     } else if (type_->HasResolvedTypeClass()) {
       const Class& type_class = Class::Handle(type_->type_class());
       Thread* thread = Thread::Current();
       CHA* cha = thread->cha();
-      // Don't infer a cid from an abstract type for signature classes since
-      // there can be multiple compatible classes with different cids.
-      if (!type_class.IsSignatureClass() &&
-          !CHA::IsImplemented(type_class) &&
-          !CHA::HasSubclasses(type_class)) {
+      // Don't infer a cid from an abstract type since there can be multiple
+      // compatible classes with different cids.
+      if (!CHA::IsImplemented(type_class) && !CHA::HasSubclasses(type_class)) {
         if (type_class.IsPrivate()) {
           // Type of a private class cannot change through later loaded libs.
           cid_ = type_class.id();
@@ -978,10 +978,11 @@
 
 CompileType AllocateObjectInstr::ComputeType() const {
   if (!closure_function().IsNull()) {
-    ASSERT(cls().raw() == closure_function().signature_class());
+    ASSERT(cls().id() == kClosureCid);
     return CompileType(CompileType::kNonNullable,
-                       cls().id(),
-                       &Type::ZoneHandle(cls().SignatureType()));
+                       kClosureCid,
+                       &FunctionType::ZoneHandle(
+                           closure_function().SignatureType()));
   }
   // TODO(vegorov): Incorporate type arguments into the returned type.
   return CompileType::FromCid(cls().id());
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index f5eef18..9b1e89c 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -27,6 +27,11 @@
 const intptr_t kSmiMax = (static_cast<intptr_t>(1) << kSmiBits) - 1;
 const intptr_t kSmiMin =  -(static_cast<intptr_t>(1) << kSmiBits);
 
+// Hard coded from above but for 32-bit architectures.
+const intptr_t kSmiBits32 = kBitsPerInt32 - 2;
+const intptr_t kSmiMax32 = (static_cast<intptr_t>(1) << kSmiBits32) - 1;
+const intptr_t kSmiMin32 =  -(static_cast<intptr_t>(1) << kSmiBits32);
+
 #define kPosInfinity bit_cast<double>(DART_UINT64_C(0x7ff0000000000000))
 #define kNegInfinity bit_cast<double>(DART_UINT64_C(0xfff0000000000000))
 
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index 592cf07..2334bbc 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -435,6 +435,13 @@
     return table.Release().raw();
   }
 
+  template<typename Table>
+  static RawArray* New(const Array& array) {
+    Table table(array.raw());
+    table.Initialize();
+    return table.Release().raw();
+  }
+
   // Clears 'to' and inserts all elements from 'from', in iteration order.
   // The tables must have the same user payload size.
   template<typename From, typename To>
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 15635bc..12663f3 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2734,7 +2734,7 @@
   if (!compiler->is_optimizing()) {
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -2760,7 +2760,7 @@
     // code that matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -3689,6 +3689,7 @@
     Report::MessageF(Report::kError,
                      Script::Handle(function().script()),
                      function().token_pos(),
+                     Report::AtLocation,
                      "native function '%s' (%" Pd " arguments) cannot be found",
                      native_name().ToCString(),
                      function().NumParameters());
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 0a40848..60e25a9 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -38,47 +38,6 @@
 class RangeBoundary;
 class UnboxIntegerInstr;
 
-// These token positions are used to classify instructions that can't be
-// directly tied to an actual source position.
-#define CLASSIFYING_TOKEN_POSITIONS(V)                                         \
-    V(Private, -2)                                                             \
-    V(Box, -3)                                                                 \
-    V(ParallelMove, -4)                                                        \
-    V(TempMove, -5)                                                            \
-    V(Constant, -6)                                                            \
-    V(PushArgument, -7)                                                        \
-    V(ControlFlow, -8)                                                         \
-    V(Context, -9)
-
-// COMPILE_ASSERT that all CLASSIFYING_TOKEN_POSITIONS are less than
-// Scanner::kNoSourcePos.
-#define SANITY_CHECK_VALUES(name, value)                                       \
-  COMPILE_ASSERT(value < Scanner::kNoSourcePos);
-  CLASSIFYING_TOKEN_POSITIONS(SANITY_CHECK_VALUES);
-#undef SANITY_CHECK_VALUES
-
-class ClassifyingTokenPositions : public AllStatic {
- public:
-#define DEFINE_VALUES(name, value)                                             \
-  static const intptr_t k##name = value;
-  CLASSIFYING_TOKEN_POSITIONS(DEFINE_VALUES);
-#undef DEFINE_VALUES
-
-  static const char* ToCString(intptr_t token_pos) {
-    ASSERT(token_pos < 0);
-    switch (token_pos) {
-      case Scanner::kNoSourcePos: return "NoSource";
-#define DEFINE_CASE(name, value)                                               \
-      case value: return #name;
-      CLASSIFYING_TOKEN_POSITIONS(DEFINE_CASE);
-#undef DEFINE_CASE
-      default:
-        UNIMPLEMENTED();
-        return NULL;
-    }
-  }
-};
-
 // CompileType describes type of the value produced by the definition.
 //
 // It captures the following properties:
@@ -668,7 +627,7 @@
   const ICData* GetICData(
       const ZoneGrowableArray<const ICData*>& ic_data_array) const;
 
-  virtual intptr_t token_pos() const { return Scanner::kNoSourcePos; }
+  virtual intptr_t token_pos() const { return Token::kNoSourcePos; }
 
   virtual intptr_t InputCount() const = 0;
   virtual Value* InputAt(intptr_t i) const = 0;
@@ -3312,7 +3271,7 @@
 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> {
  public:
   LoadLocalInstr(const LocalVariable& local,
-                 intptr_t token_pos = Scanner::kNoSourcePos)
+                 intptr_t token_pos)
       : local_(local), is_last_(false), token_pos_(token_pos) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
@@ -3428,7 +3387,7 @@
  public:
   StoreLocalInstr(const LocalVariable& local,
                   Value* value,
-                  intptr_t token_pos = Scanner::kNoSourcePos)
+                  intptr_t token_pos)
       : local_(local), is_dead_(false), is_last_(false), token_pos_(token_pos) {
     SetInputAt(0, value);
   }
@@ -3757,7 +3716,7 @@
  public:
   StoreStaticFieldInstr(const Field& field,
                         Value* value,
-                        intptr_t token_pos = Scanner::kNoSourcePos)
+                        intptr_t token_pos)
       : field_(field),
         token_pos_(token_pos) {
     ASSERT(field.IsZoneHandle());
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 9120195..c585771 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -1834,7 +1834,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -6651,7 +6651,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6854,7 +6854,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ Push(typed_data);
-  compiler->GenerateRuntimeCall(Scanner::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 05ce132..18d82cd 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -1686,7 +1686,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -5414,7 +5414,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -5616,7 +5616,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ Push(typed_data);
-  compiler->GenerateRuntimeCall(Scanner::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 0c2f782..3ceb83c 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1675,7 +1675,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -6551,7 +6551,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6862,7 +6862,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ pushl(typed_data);
-  compiler->GenerateRuntimeCall(Scanner::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index e403445..ebdd48b 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1859,7 +1859,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -5389,7 +5389,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -5591,7 +5591,7 @@
   __ LoadObject(TMP, Object::null_object());
   __ sw(TMP, Address(SP, 1 * kWordSize));
   __ sw(typed_data, Address(SP, 0 * kWordSize));
-  compiler->GenerateRuntimeCall(Scanner::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 7ca52de..8c164fc 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -1685,7 +1685,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Scanner::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -6192,7 +6192,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Scanner::kNoSourcePos);
+                                   Token::kNoSourcePos);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6444,7 +6444,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ pushq(typed_data);
-  compiler->GenerateRuntimeCall(Scanner::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index c3356b3..748c8c4 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -68,19 +68,19 @@
   ASSERT(!func.IsNull());                                                      \
   func.set_is_intrinsic(true);
 
-  // Set up all core lib functions that can be intrisified.
+  // Set up all core lib functions that can be intrinsified.
   lib = Library::CoreLibrary();
   ASSERT(!lib.IsNull());
   CORE_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
   CORE_INTEGER_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
   GRAPH_CORE_INTRINSICS_LIST(SETUP_FUNCTION);
 
-  // Set up all math lib functions that can be intrisified.
+  // Set up all math lib functions that can be intrinsified.
   lib = Library::MathLibrary();
   ASSERT(!lib.IsNull());
   MATH_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
 
-  // Set up all dart:typed_data lib functions that can be intrisified.
+  // Set up all dart:typed_data lib functions that can be intrinsified.
   lib = Library::TypedDataLibrary();
   ASSERT(!lib.IsNull());
   TYPED_DATA_LIB_INTRINSIC_LIST(SETUP_FUNCTION);
@@ -304,7 +304,7 @@
       new LoadFieldInstr(new Value(array),
                          length_offset,
                          Type::ZoneHandle(Type::SmiType()),
-                         Scanner::kNoSourcePos));
+                         Token::kNoSourcePos));
   builder->AddInstruction(
       new CheckArrayBoundInstr(new Value(length),
                                new Value(index),
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index bb3121f..1b49169 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1537,12 +1537,10 @@
   Label fall_through;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(&fall_through, EQ);  // Instance is a closure.
   __ LoadClassById(R2, R1);
-
   // R2: class of instance (R0).
-  __ ldr(R3, FieldAddress(R2, Class::signature_function_offset()));
-  __ CompareObject(R3, Object::null_object());
-  __ b(&fall_through, NE);
 
   __ ldrh(R3, FieldAddress(R2, Class::num_type_arguments_offset()));
   __ CompareImmediate(R3, 0);
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index 265d5d4..3c28ec1 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -1614,11 +1614,10 @@
   Label fall_through;
   __ ldr(R0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(R1, R0);
+  __ CompareImmediate(R1, kClosureCid);
+  __ b(&fall_through, EQ);  // Instance is a closure.
   __ LoadClassById(R2, R1);
   // R2: class of instance (R0).
-  __ ldr(R3, FieldAddress(R2, Class::signature_function_offset()));
-  __ CompareObject(R3, Object::null_object());
-  __ b(&fall_through, NE);
 
   __ ldr(R3, FieldAddress(R2, Class::num_type_arguments_offset()), kHalfword);
   __ CompareImmediate(R3, 0);
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 61620c8..9f4c622 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1680,19 +1680,16 @@
   Label fall_through;
   __ movl(EAX, Address(ESP, + 1 * kWordSize));
   __ LoadClassIdMayBeSmi(EDI, EAX);
+  __ cmpl(EDI, Immediate(kClosureCid));
+  __ j(EQUAL, &fall_through, Assembler::kNearJump);  // Instance is a closure.
   __ LoadClassById(EBX, EDI);
   // EBX: class of instance (EAX).
-  const Immediate& raw_null =
-      Immediate(reinterpret_cast<intptr_t>(Object::null()));
-  __ movl(EDI, FieldAddress(EBX, Class::signature_function_offset()));
-  __ cmpl(EDI, raw_null);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
 
   __ movzxw(EDI, FieldAddress(EBX, Class::num_type_arguments_offset()));
   __ cmpl(EDI, Immediate(0));
   __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
   __ movl(EAX, FieldAddress(EBX, Class::canonical_types_offset()));
-  __ cmpl(EAX, raw_null);
+  __ CompareObject(EAX, Object::null_object());
   __ j(EQUAL, &fall_through, Assembler::kNearJump);  // Not yet set.
   __ ret();
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index 2be1114..1e289cc 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1646,12 +1646,10 @@
   Label fall_through;
   __ lw(T0, Address(SP, 0 * kWordSize));
   __ LoadClassIdMayBeSmi(T1, T0);
+  __ BranchEqual(T1, Immediate(kClosureCid), &fall_through);
   __ LoadClassById(T2, T1);
   // T2: class of instance (T0).
 
-  __ lw(T1, FieldAddress(T2, Class::signature_function_offset()));
-  __ BranchNotEqual(T1, Object::null_object(), &fall_through);
-
   __ lhu(T1, FieldAddress(T2, Class::num_type_arguments_offset()));
   __ BranchNotEqual(T1, Immediate(0), &fall_through);
 
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index e3f2ca4..d9eb08b 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1536,11 +1536,11 @@
   __ LoadClassIdMayBeSmi(RCX, RAX);
 
   // RCX: untagged cid of instance (RAX).
+  __ cmpq(RCX, Immediate(kClosureCid));
+  __ j(EQUAL, &fall_through, Assembler::kNearJump);  // Instance is a closure.
+
   __ LoadClassById(RDI, RCX);
   // RDI: class of instance (RAX).
-  __ movq(RCX, FieldAddress(RDI, Class::signature_function_offset()));
-  __ CompareObject(RCX, Object::null_object());
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
 
   __ movzxw(RCX, FieldAddress(RDI, Class::num_type_arguments_offset()));
   __ cmpq(RCX, Immediate(0));
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 5c764df..a62ac0e 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -58,6 +58,9 @@
             "Pause isolates before starting.");
 DEFINE_FLAG(bool, pause_isolates_on_exit, false,
             "Pause isolates exiting.");
+DEFINE_FLAG(bool, pause_isolates_on_unhandled_exceptions, false,
+            "Pause isolates on unhandled exceptions.");
+
 DEFINE_FLAG(bool, break_at_isolate_spawn, false,
             "Insert a one-time breakpoint at the entrypoint for all spawned "
             "isolates");
@@ -1070,6 +1073,9 @@
   if (!ServiceIsolate::IsServiceIsolate(this)) {
     message_handler()->set_pause_on_start(FLAG_pause_isolates_on_start);
     message_handler()->set_pause_on_exit(FLAG_pause_isolates_on_exit);
+    if (FLAG_pause_isolates_on_unhandled_exceptions) {
+      debugger()->SetExceptionPauseInfo(kPauseOnUnhandledExceptions);
+    }
   }
   IsolateSpawnState* state = spawn_state();
   if (state != NULL) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 8e84d00..56cf82e 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -718,6 +718,7 @@
   RawCode* ic_miss_code_;
   ClassTable class_table_;
   bool single_step_;
+  bool skip_step_;  // skip the next single step.
 
   ThreadRegistry* thread_registry_;
   Dart_MessageNotifyCallback message_notify_callback_;
diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc
index d576beb..b7f6589 100644
--- a/runtime/vm/log.cc
+++ b/runtime/vm/log.cc
@@ -13,7 +13,8 @@
 
 DEFINE_FLAG(charp, isolate_log_filter, NULL,
             "Log isolates whose name include the filter. "
-            "Default: service isolate log messages are suppressed.");
+            "Default: service isolate log messages are suppressed "
+            "(specify 'vm-service' to log them).");
 
 Log::Log(LogPrinter printer)
     : printer_(printer),
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 7f4bbec..6f2d172 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -72,6 +72,7 @@
                                      false,  // Not native.
                                      cls,
                                      0));  // No token position.
+  function.set_result_type(Type::Handle(Type::DynamicType()));
   function.set_is_debuggable(false);
   function.set_is_visible(false);
   function.AttachCode(code);
diff --git a/runtime/vm/message.cc b/runtime/vm/message.cc
index 54f40b4..195b2c6 100644
--- a/runtime/vm/message.cc
+++ b/runtime/vm/message.cc
@@ -203,9 +203,9 @@
     // TODO(johnmccutchan): Move port -> handler map out of Dart and into the
     // VM, that way we can lookup the handler without invoking Dart code.
     msg_handler = DartLibraryCalls::LookupHandler(current->dest_port());
-    if (msg_handler.IsInstance() && Instance::Cast(msg_handler).IsClosure()) {
+    if (msg_handler.IsClosure()) {
       // Grab function from closure.
-      msg_handler = Closure::function(Instance::Cast(msg_handler));
+      msg_handler = Closure::Cast(msg_handler).function();
     }
     if (msg_handler.IsFunction()) {
       const Function& function = Function::Cast(msg_handler);
diff --git a/runtime/vm/mirrors_api_impl.cc b/runtime/vm/mirrors_api_impl.cc
index 4d0a348..ddc649b 100644
--- a/runtime/vm/mirrors_api_impl.cc
+++ b/runtime/vm/mirrors_api_impl.cc
@@ -334,18 +334,8 @@
   String& name = String::Handle(Z);
   while (it.HasNext()) {
     cls = it.GetNextClass();
-    if (cls.IsSignatureClass()) {
-      if (!cls.IsCanonicalSignatureClass()) {
-        // This is a typedef.  Add it to the list of class names.
-        name = cls.UserVisibleName();
-        names.Add(name);
-      } else {
-        // Skip canonical signature classes.  These are not named.
-      }
-    } else {
-      name = cls.UserVisibleName();
-      names.Add(name);
-    }
+    name = cls.UserVisibleName();
+    names.Add(name);
   }
   return Api::NewHandle(T, Array::MakeArray(names));
 }
@@ -362,7 +352,7 @@
 
   ASSERT(ClassFinalizer::AllClassesFinalized());
 
-  RawFunction* rf = Closure::function(closure_obj);
+  RawFunction* rf = Closure::Cast(closure_obj).function();
   return Api::NewHandle(T, rf);
 }
 
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 3fb2f74..0655a69 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -107,7 +107,7 @@
       // Retrieve the receiver from the context.
       const Object& closure = Object::Handle(ArgAt(0));
       const Context& context =
-          Context::Handle(Closure::context(Instance::Cast(closure)));
+          Context::Handle(Closure::Cast(closure).context());
       return context.At(0);
     }
     return ArgAt(NumHiddenArgs(function_bits));
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 730d560..df6fde0 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -141,6 +141,8 @@
 RawClass* Object::instructions_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::object_pool_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::pc_descriptors_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
+RawClass* Object::code_source_map_class_ =
+    reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::stackmap_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 RawClass* Object::var_descriptors_class_ =
     reinterpret_cast<RawClass*>(RAW_NULL);
@@ -613,6 +615,9 @@
   cls = Class::New<PcDescriptors>();
   pc_descriptors_class_ = cls.raw();
 
+  cls = Class::New<CodeSourceMap>();
+  code_source_map_class_ = cls.raw();
+
   cls = Class::New<Stackmap>();
   stackmap_class_ = cls.raw();
 
@@ -945,6 +950,7 @@
   SET_CLASS_NAME(code, Code);
   SET_CLASS_NAME(instructions, Instructions);
   SET_CLASS_NAME(object_pool, ObjectPool);
+  SET_CLASS_NAME(code_source_map, CodeSourceMap);
   SET_CLASS_NAME(pc_descriptors, PcDescriptors);
   SET_CLASS_NAME(stackmap, Stackmap);
   SET_CLASS_NAME(var_descriptors, LocalVarDescriptors);
@@ -1122,6 +1128,8 @@
 
   // Setup type class early in the process.
   const Class& type_cls = Class::Handle(zone, Class::New<Type>());
+  const Class& function_type_cls = Class::Handle(zone,
+                                                 Class::New<FunctionType>());
   const Class& type_ref_cls = Class::Handle(zone, Class::New<TypeRef>());
   const Class& type_parameter_cls = Class::Handle(zone,
                                                   Class::New<TypeParameter>());
@@ -1176,7 +1184,7 @@
   // could expect. Use with caution.
   type ^= Type::New(Object::Handle(zone, cls.raw()),
                     TypeArguments::Handle(zone),
-                    Scanner::kNoSourcePos);
+                    Token::kNoSourcePos);
   type.SetIsFinalized();
   type ^= type.Canonicalize();
   object_store->set_array_type(type);
@@ -1284,6 +1292,9 @@
   RegisterPrivateClass(type_cls, Symbols::Type(), core_lib);
   pending_classes.Add(type_cls);
 
+  RegisterPrivateClass(function_type_cls, Symbols::FunctionType(), core_lib);
+  pending_classes.Add(function_type_cls);
+
   RegisterPrivateClass(type_ref_cls, Symbols::TypeRef(), core_lib);
   pending_classes.Add(type_ref_cls);
 
@@ -1321,15 +1332,14 @@
   RegisterPrivateClass(cls, Symbols::_Double(), core_lib);
   pending_classes.Add(cls);
 
-  // Abstract super class for all signature classes.
-  cls = Class::New<Instance>(kIllegalCid);
-  cls.set_num_type_arguments(0);
+  // Class that represents the Dart class _Closure and C++ class Closure.
+  cls = Class::New<Closure>();
+  cls.set_type_arguments_field_offset(Closure::type_arguments_offset());
+  cls.set_num_type_arguments(0);  // Although a closure has type_arguments_.
   cls.set_num_own_type_arguments(0);
-  cls.set_is_prefinalized();
-  RegisterPrivateClass(cls, Symbols::FunctionImpl(), core_lib);
+  RegisterPrivateClass(cls, Symbols::_Closure(), core_lib);
   pending_classes.Add(cls);
-  type = Type::NewNonParameterizedType(cls);
-  object_store->set_function_impl_type(type);
+  object_store->set_closure_class(cls);
 
   cls = Class::New<WeakProperty>();
   object_store->set_weak_property_class(cls);
@@ -1606,6 +1616,7 @@
 
   cls = Class::New<LibraryPrefix>();
   cls = Class::New<Type>();
+  cls = Class::New<FunctionType>();
   cls = Class::New<TypeRef>();
   cls = Class::New<TypeParameter>();
   cls = Class::New<BoundedType>();
@@ -1660,6 +1671,9 @@
   cls = Class::New<Double>();
   object_store->set_double_class(cls);
 
+  cls = Class::New<Closure>();
+  object_store->set_closure_class(cls);
+
   cls = Class::New<Bigint>();
   object_store->set_bigint_class(cls);
 
@@ -1953,41 +1967,11 @@
 }
 
 
-RawType* Class::SignatureType() const {
-  ASSERT(IsSignatureClass());
-  Zone* zone = Thread::Current()->zone();
-  const Function& function = Function::Handle(zone, signature_function());
-  ASSERT(!function.IsNull());
-  if (function.signature_class() != raw()) {
-    // This class is a function type alias. Return the canonical signature type.
-    const Class& canonical_signature_class =
-        Class::Handle(zone, function.signature_class());
-    return canonical_signature_class.SignatureType();
-  }
-  const Type& signature_type = Type::Handle(zone, CanonicalType());
-  if (!signature_type.IsNull()) {
-    return signature_type.raw();
-  }
-  // A signature class extends class Instance and is parameterized in the same
-  // way as the owner class of its non-static signature function.
-  // It is not type parameterized if its signature function is static.
-  // See Class::NewSignatureClass() for the setup of its type parameters.
-  // During type finalization, the type arguments of the super class of the
-  // owner class of its signature function will be prepended to the type
-  // argument vector. Therefore, we only need to set the type arguments
-  // matching the type parameters here.
-  const TypeArguments& signature_type_arguments =
-      TypeArguments::Handle(zone, type_parameters());
-  // Return the still unfinalized signature type.
-  return Type::New(*this, signature_type_arguments, token_pos());
-}
-
-
 RawAbstractType* Class::RareType() const {
   const Type& type = Type::Handle(Type::New(
       *this,
       Object::null_type_arguments(),
-      Scanner::kNoSourcePos));
+      Token::kNoSourcePos));
   return ClassFinalizer::FinalizeType(*this,
                                       type,
                                       ClassFinalizer::kCanonicalize);
@@ -1999,7 +1983,7 @@
   const Type& type = Type::Handle(Type::New(
       *this,
       args,
-      Scanner::kNoSourcePos));
+      Token::kNoSourcePos));
   return ClassFinalizer::FinalizeType(*this,
                                       type,
                                       ClassFinalizer::kCanonicalize);
@@ -2037,7 +2021,7 @@
   result.set_num_type_arguments(0);
   result.set_num_own_type_arguments(0);
   result.set_num_native_fields(0);
-  result.set_token_pos(Scanner::kNoSourcePos);
+  result.set_token_pos(Token::kNoSourcePos);
   result.InitEmptyFields();
   Isolate::Current()->RegisterClass(result);
   return result.raw();
@@ -2049,6 +2033,7 @@
   Report::MessageF(Report::kError,
                    Script::Handle(cls.script()),
                    cls.token_pos(),
+                   Report::AtLocation,
                    "too many type parameters declared in class '%s' or in its "
                    "super classes",
                    String::Handle(cls.Name()).ToCString());
@@ -2180,6 +2165,8 @@
       set.Insert(func);
     }
     StorePointer(&raw_ptr()->functions_hash_table_, set.Release().raw());
+  } else {
+    StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
   }
 }
 
@@ -2457,14 +2444,6 @@
   cls = raw();
   intptr_t num_type_args = 0;
   do {
-    if (cls.IsSignatureClass()) {
-      Function& signature_fun = Function::Handle(zone);
-      signature_fun ^= cls.signature_function();
-      if (!signature_fun.is_static() &&
-          !signature_fun.HasInstantiatedSignature()) {
-        cls = signature_fun.Owner();
-      }
-    }
     // Calling NumOwnTypeArguments() on a mixin application class will setup the
     // type parameters if not already done.
     num_type_args += cls.NumOwnTypeArguments();
@@ -2474,8 +2453,12 @@
       break;
     }
     sup_type = cls.super_type();
-    ClassFinalizer::ResolveTypeClass(cls, sup_type);
+    // A BoundedType, TypeRef, or FunctionType can appear as type argument of
+    // sup_type, but not as sup_type itself.
+    ASSERT(sup_type.IsType());
+    sup_type = ClassFinalizer::ResolveTypeClass(cls, Type::Cast(sup_type));
     cls = sup_type.type_class();
+    ASSERT(!cls.IsTypedefClass());
   } while (true);
   set_num_type_arguments(num_type_args);
   return num_type_args;
@@ -2527,6 +2510,7 @@
 
 
 void Class::CalculateFieldOffsets() const {
+  ASSERT(id() != kClosureCid);  // Class _Closure is prefinalized.
   Array& flds = Array::Handle(fields());
   const Class& super = Class::Handle(SuperClass());
   intptr_t offset = 0;
@@ -2694,7 +2678,7 @@
                   false,  // Not external.
                   false,  // Not native.
                   owner,
-                  0));    // token_pos
+                  ClassifyingTokenPositions::kMethodExtractor));  // token_pos
 
   // Initialize signature: receiver is a single fixed parameter.
   const intptr_t kNumParameters = 1;
@@ -2740,9 +2724,7 @@
 
 void Class::Finalize() const {
   ASSERT(Thread::Current()->IsMutatorThread());
-  // Even if all regular classes are prefinalized (precompilation), signature
-  // classes may be added later when we encounter local functions.
-  ASSERT(IsSignatureClass() || !Isolate::Current()->all_classes_finalized());
+  ASSERT(!Isolate::Current()->all_classes_finalized());
   ASSERT(!is_finalized());
   // Prefinalized classes have a VM internal representation and no Dart fields.
   // Their instance size  is precomputed and field offsets are known.
@@ -2898,6 +2880,7 @@
           *error,  // No previous error.
           Script::Handle(patch.script()),
           func.token_pos(),
+          Report::AtLocation,
           Report::kError,
           Heap::kNew,
           "signature mismatch: '%s'", member_name.ToCString());
@@ -2943,6 +2926,7 @@
           *error,  // No previous error.
           Script::Handle(patch.script()),
           field.token_pos(),
+          Report::AtLocation,
           Report::kError,
           Heap::kNew,
           "duplicate field: %s", member_name.ToCString());
@@ -3107,7 +3091,7 @@
   result.set_num_type_arguments(kUnknownNumTypeArguments);
   result.set_num_own_type_arguments(kUnknownNumTypeArguments);
   result.set_num_native_fields(0);
-  result.set_token_pos(Scanner::kNoSourcePos);
+  result.set_token_pos(Token::kNoSourcePos);
   result.InitEmptyFields();
   Isolate::Current()->RegisterClass(result);
   return result.raw();
@@ -3125,79 +3109,12 @@
 }
 
 
-RawClass* Class::NewSignatureClass(const String& name,
-                                   const Function& signature_function,
-                                   const Script& script,
-                                   intptr_t token_pos) {
-  const Class& result = Class::Handle(New(name, script, token_pos));
-  // Instances of a signature class can only be closures.
-  result.set_instance_size(Closure::InstanceSize());
-  result.set_next_field_offset(Closure::NextFieldOffset());
-  // Signature classes extend the _FunctionImpl class.
-  result.set_super_type(Type::Handle(
-      Isolate::Current()->object_store()->function_impl_type()));
-  result.set_is_synthesized_class();
-  result.set_type_arguments_field_offset(Closure::type_arguments_offset());
-  if (!signature_function.IsNull()) {
-    result.PatchSignatureFunction(signature_function);
-  }
-  return result.raw();
-}
-
-
-void Class::PatchSignatureFunction(const Function& signature_function) const {
-  ASSERT(!signature_function.IsNull());
-  set_signature_function(signature_function);
-  const Class& owner_class = Class::Handle(signature_function.Owner());
-  ASSERT(!owner_class.IsNull());
-  // A signature class extends class Instance and is either not parameterized or
-  // parameterized with exactly the same list of type parameters as the owner
-  // class of its function.
-  // In case of a function type alias, the function owner is the alias class,
-  // which is also the signature class. The signature class is therefore
-  // parameterized according to the alias class declaration, even if the
-  // function type is not generic.
-  // Otherwise, if the function is static or if its signature type is
-  // non-generic, i.e. it does not depend on any type parameter of the owner
-  // class, then the signature class is not parameterized, although the owner
-  // class may be.
-  if (owner_class.raw() == raw()) {
-    // This signature class is an alias, which cannot be the canonical
-    // signature class for this signature function.
-    ASSERT(!IsCanonicalSignatureClass());
-    // Do not modify the declared type parameters of the alias, even if unused.
-  } else {
-    // Copy the type parameters only for an instance function type that is not
-    // instantiated, i.e. that depends on the type parameters of the owner
-    // class.
-    // TODO(regis): Verify that it is not a problem for the copied type
-    // parameters to refer to the owner class rather than to the signature
-    // class. In other words, uninstantiated function types should only get
-    // instantiated by the owner class as instantiator and never by the
-    // signature class itself.
-    TypeArguments& type_parameters = TypeArguments::Handle();
-    if (!signature_function.is_static() &&
-        (owner_class.NumTypeParameters() > 0) &&
-        !signature_function.HasInstantiatedSignature()) {
-      type_parameters = owner_class.type_parameters();
-    }
-    set_type_parameters(type_parameters);
-    if (signature_function.signature_class() == Object::null()) {
-      // Make this signature class the canonical signature class.
-      signature_function.set_signature_class(*this);
-      ASSERT(IsCanonicalSignatureClass());
-    }
-  }
-  set_is_prefinalized();
-}
-
-
 RawClass* Class::NewNativeWrapper(const Library& library,
                                   const String& name,
                                   int field_count) {
   Class& cls = Class::Handle(library.LookupClass(name));
   if (cls.IsNull()) {
-    cls = New(name, Script::Handle(), Scanner::kNoSourcePos);
+    cls = New(name, Script::Handle(), Token::kNoSourcePos);
     cls.SetFields(Object::empty_array());
     cls.SetFunctions(Object::empty_array());
     // Set super class to Object.
@@ -3289,12 +3206,8 @@
 
 
 RawString* Class::GeneratePrettyName() const {
-  if (!IsCanonicalSignatureClass()) {
-    const String& name = String::Handle(Name());
-    return String::IdentifierPrettyName(name);
-  } else {
-    return Name();
-  }
+  const String& name = String::Handle(Name());
+  return String::IdentifierPrettyName(name);
 }
 
 
@@ -3343,6 +3256,8 @@
       return Symbols::Instructions().raw();
     case kObjectPoolCid:
       return Symbols::ObjectPool().raw();
+    case kCodeSourceMapCid:
+      return Symbols::CodeSourceMap().raw();
     case kPcDescriptorsCid:
       return Symbols::PcDescriptors().raw();
     case kStackmapCid:
@@ -3432,12 +3347,8 @@
     case kExternalTypedDataFloat64ArrayCid:
       return Symbols::Float64List().raw();
     default:
-      if (!IsCanonicalSignatureClass()) {
-        const String& name = String::Handle(Name());
-        return String::IdentifierPrettyName(name);
-      } else {
-        return Name();
-      }
+      const String& name = String::Handle(Name());
+      return String::IdentifierPrettyName(name);
   }
   UNREACHABLE();
 }
@@ -3449,14 +3360,14 @@
 
 
 void Class::set_token_pos(intptr_t token_pos) const {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
 intptr_t Class::ComputeEndTokenPos() const {
   // Return the begin token for synthetic classes.
-  if (IsSignatureClass() || IsMixinApplication() || IsTopLevel()) {
+  if (IsMixinApplication() || IsTopLevel()) {
     return token_pos();
   }
   const Script& scr = Script::Handle(script());
@@ -3639,7 +3550,7 @@
 
 
 RawType* Class::CanonicalType() const {
-  if (!IsGeneric()) {
+  if (!IsGeneric() && !IsClosureClass()) {
     return reinterpret_cast<RawType*>(raw_ptr()->canonical_types_);
   }
   Array& types = Array::Handle();
@@ -3653,7 +3564,7 @@
 
 void Class::SetCanonicalType(const Type& type) const {
   ASSERT(type.IsCanonical());
-  if (!IsGeneric()) {
+  if (!IsGeneric() && !IsClosureClass()) {
     ASSERT((canonical_types() == Object::null()) ||
            (canonical_types() == type.raw()));  // Set during own finalization.
     set_canonical_types(type);
@@ -3667,7 +3578,7 @@
 }
 
 
-intptr_t Class::FindCanonicalTypeIndex(const Type& needle) const {
+intptr_t Class::FindCanonicalTypeIndex(const AbstractType& needle) const {
   Thread* thread = Thread::Current();
   if (EnsureIsFinalized(thread) != Error::null()) {
     return -1;
@@ -3697,8 +3608,8 @@
 }
 
 
-RawType* Class::CanonicalTypeFromIndex(intptr_t idx) const {
-  Type& type = Type::Handle();
+RawAbstractType* Class::CanonicalTypeFromIndex(intptr_t idx) const {
+  AbstractType& type = AbstractType::Handle();
   if (idx == 0) {
     type = CanonicalType();
     if (!type.IsNull()) {
@@ -3745,12 +3656,6 @@
 }
 
 
-bool Class::IsCanonicalSignatureClass() const {
-  const Function& function = Function::Handle(signature_function());
-  return (!function.IsNull() && (function.signature_class() == raw()));
-}
-
-
 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T.
 // If test_kind == kIsMoreSpecificThan, checks if S is more specific than T.
 // Type S is specified by this class parameterized with 'type_arguments', and
@@ -3823,25 +3728,8 @@
                                      bound_error,
                                      space);
     }
-    const bool other_is_function_class = other.IsFunctionClass();
-    if (other.IsSignatureClass() || other_is_function_class) {
-      const Function& other_fun = Function::Handle(zone,
-                                                   other.signature_function());
-      if (thsi.IsSignatureClass()) {
-        if (other_is_function_class) {
-          return true;
-        }
-        // Check for two function types.
-        const Function& fun =
-            Function::Handle(zone, thsi.signature_function());
-        return fun.TypeTest(test_kind,
-                            type_arguments,
-                            other_fun,
-                            other_type_arguments,
-                            bound_error,
-                            space);
-      }
-      // Check if type S has a call() method of function type T.
+    if (other.IsFunctionClass()) {
+      // Check if type S has a call() method.
       Function& function =
           Function::Handle(zone, thsi.LookupDynamicFunction(Symbols::Call()));
       if (function.IsNull()) {
@@ -3853,15 +3741,7 @@
         }
       }
       if (!function.IsNull()) {
-        if (other_is_function_class ||
-            function.TypeTest(test_kind,
-                              type_arguments,
-                              other_fun,
-                              other_type_arguments,
-                              bound_error,
-                              space)) {
-              return true;
-            }
+        return true;
       }
     }
     // Check for 'direct super type' specified in the implements clause
@@ -4385,7 +4265,7 @@
 
 
 void UnresolvedClass::set_token_pos(intptr_t token_pos) const {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -4901,7 +4781,8 @@
   }
   // Cache lookup failed. Instantiate the type arguments.
   TypeArguments& result = TypeArguments::Handle();
-  result = InstantiateFrom(instantiator_type_arguments, bound_error);
+  result = InstantiateFrom(
+      instantiator_type_arguments, bound_error, NULL, Heap::kOld);
   if ((bound_error != NULL) && !bound_error->IsNull()) {
     return result.raw();
   }
@@ -5493,33 +5374,67 @@
 }
 
 
-RawClass* Function::signature_class() const {
+RawFunctionType* Function::SignatureType() const {
+  FunctionType& type = FunctionType::Handle();
+  const Object& obj = Object::Handle(raw_ptr()->data_);
   if (IsSignatureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
-    ASSERT(obj.IsNull() || obj.IsClass());
-    return (obj.IsNull()) ? Class::null() : Class::Cast(obj).raw();
-  }
-  if (IsClosureFunction()) {
-    const Object& obj = Object::Handle(raw_ptr()->data_);
+    ASSERT(obj.IsNull() || obj.IsFunctionType());
+    type = obj.IsNull() ? FunctionType::null() : FunctionType::Cast(obj).raw();
+  } else {
+    ASSERT(IsClosureFunction());
     ASSERT(!obj.IsNull());
-    return ClosureData::Cast(obj).signature_class();
+    type = ClosureData::Cast(obj).signature_type();
   }
-  return Class::null();
+  if (type.IsNull()) {
+    // A function type is parameterized in the same way as the owner class of
+    // its non-static signature function.
+    // It is not type parameterized if its signature function is static.
+    // During type finalization, the type arguments of the super class of the
+    // owner class of its signature function will be prepended to the type
+    // argument vector. Therefore, we only need to set the type arguments
+    // matching the type parameters here.
+    // In case of a function type alias, the function owner is the alias class,
+    // i.e. the typedef. The signature type is therefore parameterized according
+    // to the alias class declaration, even if the function type is not generic.
+    // Otherwise, if the function is static or if its signature type is
+    // non-generic, i.e. it does not depend on any type parameter of the owner
+    // class, then the signature type is not parameterized, although the owner
+    // class may be. In this case, the scope class of the function type is reset
+    // to _Closure class as well as the owner of the signature function.
+    Class& scope_class = Class::Handle(Owner());
+    if (!scope_class.IsTypedefClass() &&
+        (is_static() ||
+         !scope_class.IsGeneric() ||
+         HasInstantiatedSignature())) {
+      scope_class = Isolate::Current()->object_store()->closure_class();
+      if (IsSignatureFunction()) {
+        set_owner(scope_class);
+        set_token_pos(Token::kNoSourcePos);
+      }
+    }
+    const TypeArguments& signature_type_arguments =
+        TypeArguments::Handle(scope_class.type_parameters());
+    // Return the still unfinalized signature type.
+    type = FunctionType::New(scope_class,
+                             signature_type_arguments,
+                             *this,
+                             token_pos());
+
+    SetSignatureType(type);
+  }
+  return type.raw();
 }
 
 
-void Function::set_signature_class(const Class& value) const {
+void Function::SetSignatureType(const FunctionType& value) const {
   if (IsSignatureFunction()) {
     set_data(value);
-    return;
-  }
-  if (IsClosureFunction()) {
+  } else {
+    ASSERT(IsClosureFunction());
     const Object& obj = Object::Handle(raw_ptr()->data_);
     ASSERT(!obj.IsNull());
-    ClosureData::Cast(obj).set_signature_class(value);
-    return;
+    ClosureData::Cast(obj).set_signature_type(value);
   }
-  UNREACHABLE();
 }
 
 
@@ -5640,7 +5555,7 @@
 
 // This field is heavily overloaded:
 //   eval function:           Script expression source
-//   signature function:      Class signature class
+//   signature function:      Function type
 //   method extractor:        Function extracted closure function
 //   noSuchMethod dispatcher: Array arguments descriptor
 //   invoke-field dispatcher: Array arguments descriptor
@@ -5787,7 +5702,7 @@
 
 
 void Function::set_token_pos(intptr_t token_pos) const {
-  ASSERT(token_pos >= 0);
+  ASSERT(!Token::IsClassifying(token_pos) || IsMethodExtractor());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -6169,6 +6084,7 @@
         *bound_error,  // A bound error if non null.
         Script::Handle(other.script()),
         other.token_pos(),
+        Report::AtLocation,
         Report::kError,
         Heap::kNew,
         "signature type '%s' of function '%s' is not a subtype of signature "
@@ -6505,6 +6421,25 @@
 }
 
 
+RawFunction* Function::NewSignatureFunction(const Class& owner,
+                                            intptr_t token_pos) {
+  const Function& result = Function::Handle(Function::New(
+      Symbols::AnonymousSignature(),
+      RawFunction::kSignatureFunction,
+      /* is_static = */ false,
+      /* is_const = */ false,
+      /* is_abstract = */ false,
+      /* is_external = */ false,
+      /* is_native = */ false,
+      owner,  // Same as function type scope class.
+      token_pos));
+  result.set_is_reflectable(false);
+  result.set_is_visible(false);
+  result.set_is_debuggable(false);
+  return result.raw();
+}
+
+
 RawFunction* Function::NewEvalFunction(const Class& owner,
                                        const Script& script,
                                        bool is_static) {
@@ -6583,35 +6518,12 @@
     param_name = ParameterNameAt(has_receiver - kClosure + i);
     closure_function.SetParameterNameAt(i, param_name);
   }
-
-  // Lookup or create a new signature class for the closure function in the
-  // library of the owner class.
-  const Class& owner_class = Class::Handle(Owner());
-  ASSERT(!owner_class.IsNull() && (Owner() == closure_function.Owner()));
-  const Library& library = Library::Handle(owner_class.library());
-  ASSERT(!library.IsNull());
-  const String& signature = String::Handle(closure_function.Signature());
-  Class& signature_class = Class::ZoneHandle(
-      library.LookupLocalClass(signature));
-  if (signature_class.IsNull()) {
-    const Script& script = Script::Handle(this->script());
-    signature_class = Class::NewSignatureClass(signature,
-                                               closure_function,
-                                               script,
-                                               closure_function.token_pos());
-    library.AddClass(signature_class);
-  } else {
-    closure_function.set_signature_class(signature_class);
-  }
-  // Finalize types in signature class here, so that the
-  // signature type is not computed twice.
-  ClassFinalizer::FinalizeTypesInClass(signature_class);
-  const Type& signature_type = Type::Handle(signature_class.SignatureType());
+  const FunctionType& signature_type =
+      FunctionType::Handle(closure_function.SignatureType());
   if (!signature_type.IsFinalized()) {
     ClassFinalizer::FinalizeType(
-        signature_class, signature_type, ClassFinalizer::kCanonicalize);
+        Class::Handle(Owner()), signature_type, ClassFinalizer::kCanonicalize);
   }
-  ASSERT(closure_function.signature_class() == signature_class.raw());
   set_implicit_closure_function(closure_function);
   ASSERT(closure_function.IsImplicitClosureFunction());
   return closure_function.raw();
@@ -6716,9 +6628,6 @@
         Context::Handle(zone, object_store->empty_context());
     Instance& closure =
         Instance::Handle(zone, Closure::New(*this, context, Heap::kOld));
-    const char* error_str = NULL;
-    closure ^= closure.CheckAndCanonicalize(&error_str);
-    ASSERT(!closure.IsNull());
     set_implicit_static_closure(closure);
   }
   return implicit_static_closure();
@@ -6727,11 +6636,12 @@
 
 RawInstance* Function::ImplicitInstanceClosure(const Instance& receiver) const {
   ASSERT(IsImplicitClosureFunction());
-  const Class& cls = Class::Handle(signature_class());
+  const FunctionType& signature_type = FunctionType::Handle(SignatureType());
+  const Class& cls = Class::Handle(signature_type.type_class());
   const Context& context = Context::Handle(Context::New(1));
   context.SetAt(0, receiver);
   const Instance& result = Instance::Handle(Closure::New(*this, context));
-  if (cls.NumTypeArguments() > 0) {
+  if (cls.IsGeneric()) {
     const TypeArguments& type_arguments =
         TypeArguments::Handle(receiver.GetTypeArguments());
     result.SetTypeArguments(type_arguments);
@@ -6748,18 +6658,17 @@
   GrowableHandlePtrArray<const String> pieces(zone, 4);
   String& name = String::Handle(zone);
   if (!instantiate && !is_static() && (name_visibility == kInternalName)) {
-    // Prefix the signature with its signature class and type parameters, if any
+    // Prefix the signature with its scope class and type parameters, if any
     // (e.g. "Map<K, V>(K) => bool"). In case of a function type alias, the
-    // signature class name is the alias name.
+    // scope class name is the alias name.
     // The signature of static functions cannot be type parameterized.
-    const Class& function_class = Class::Handle(zone, Owner());
-    ASSERT(!function_class.IsNull());
-    const TypeArguments& type_parameters = TypeArguments::Handle(
-        zone, function_class.type_parameters());
-    if (!type_parameters.IsNull()) {
-      const String& function_class_name =
-          String::Handle(zone, function_class.Name());
-      pieces.Add(function_class_name);
+    const Class& scope_class = Class::Handle(zone, Owner());
+    ASSERT(!scope_class.IsNull());
+    if (scope_class.IsGeneric()) {
+      const TypeArguments& type_parameters = TypeArguments::Handle(
+          zone, scope_class.type_parameters());
+      const String& scope_class_name = String::Handle(zone, scope_class.Name());
+      pieces.Add(scope_class_name);
       const intptr_t num_type_parameters = type_parameters.Length();
       pieces.Add(Symbols::LAngleBracket());
       TypeParameter& type_parameter = TypeParameter::Handle(zone);
@@ -7271,8 +7180,8 @@
 }
 
 
-void ClosureData::set_signature_class(const Class& value) const {
-  StorePointer(&raw_ptr()->signature_class_, value.raw());
+void ClosureData::set_signature_type(const FunctionType& value) const {
+  StorePointer(&raw_ptr()->signature_type_, value.raw());
 }
 
 
@@ -8547,7 +8456,10 @@
       cur_token_kind_(Token::kILLEGAL),
       cur_token_obj_index_(-1),
       stream_type_(stream_type) {
-  SetCurrentPosition(token_pos);
+  ASSERT(token_pos != Token::kNoSourcePos);
+  if (token_pos >= 0) {
+    SetCurrentPosition(token_pos);
+  }
 }
 
 
@@ -9239,7 +9151,8 @@
   const String& url = String::Handle(lib.url());
   Report::MessageF(Report::kError,
                    Script::Handle(lib.LookupScript(url)),
-                   Scanner::kNoSourcePos,
+                   Token::kNoSourcePos,
+                   Report::AtLocation,
                    "too many imports in library '%s'",
                    url.ToCString());
   UNREACHABLE();
@@ -10155,9 +10068,17 @@
 }
 
 
-void Library::InitResolvedNamesCache(intptr_t size) const {
-  const Array& cache = Array::Handle(HashTables::New<ResolvedNamesMap>(size));
-  StorePointer(&raw_ptr()->resolved_names_, cache.raw());
+void Library::InitResolvedNamesCache(intptr_t size,
+                                     SnapshotReader* reader) const {
+  if (reader == NULL) {
+    StorePointer(&raw_ptr()->resolved_names_,
+                 HashTables::New<ResolvedNamesMap>(size));
+  } else {
+    intptr_t len = ResolvedNamesMap::ArrayLengthForNumOccupied(size);
+    *reader->ArrayHandle() ^= reader->NewArray(len);
+    StorePointer(&raw_ptr()->resolved_names_,
+                 HashTables::New<ResolvedNamesMap>(*reader->ArrayHandle()));
+  }
 }
 
 
@@ -10512,8 +10433,7 @@
     Class& klass = Class::Handle();
     while (class_iter.HasNext()) {
       klass = class_iter.GetNextClass();
-      if (!klass.IsCanonicalSignatureClass() &&
-          !klass.IsMixinApplication()) {
+      if (!klass.IsMixinApplication()) {
         jsarr.AddValue(klass);
       }
     }
@@ -11246,15 +11166,15 @@
 }
 
 
-// Encode integer in SLEB128 format.
-void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data,
-                                  intptr_t value) {
+// Encode integer |value| in SLEB128 format and store into |data|.
+static void EncodeSLEB128(GrowableArray<uint8_t>* data,
+                          intptr_t value) {
   bool is_last_part = false;
   while (!is_last_part) {
-    intptr_t part = value & 0x7f;
+    uint8_t part = value & 0x7f;
     value >>= 7;
     if ((value == 0 && (part & 0x40) == 0) ||
-        (value == -1 && (part & 0x40) != 0)) {
+        (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
       is_last_part = true;
     } else {
       part |= 0x80;
@@ -11264,24 +11184,39 @@
 }
 
 
+// Decode integer in SLEB128 format from |data| and update |byte_index|.
+static intptr_t DecodeSLEB128(const uint8_t* data,
+                              const intptr_t data_length,
+                              intptr_t* byte_index) {
+  ASSERT(*byte_index < data_length);
+  uword shift = 0;
+  intptr_t value = 0;
+  uint8_t part = 0;
+  do {
+    part = data[(*byte_index)++];
+    value |= static_cast<intptr_t>(part & 0x7f) << shift;
+    shift += 7;
+  } while ((part & 0x80) != 0);
+
+  if ((shift < (sizeof(value) * 8)) && ((part & 0x40) != 0)) {
+    value |= static_cast<intptr_t>(-1) << shift;
+  }
+  return value;
+}
+
+
+// Encode integer in SLEB128 format.
+void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data,
+                                  intptr_t value) {
+  return EncodeSLEB128(data, value);
+}
+
+
 // Decode SLEB128 encoded integer. Update byte_index to the next integer.
 intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const {
   NoSafepointScope no_safepoint;
   const uint8_t* data = raw_ptr()->data();
-  ASSERT(*byte_index < Length());
-  uword shift = 0;
-  intptr_t value = 0;
-  intptr_t part = 0;
-  do {
-    part = data[(*byte_index)++];
-    value |= (part & 0x7f) << shift;
-    shift += 7;
-  } while ((part & 0x80) != 0);
-
-  if (shift < sizeof(value) * 8 && (part & 0x40) != 0) {
-    value |= -(1 << shift);
-  }
-  return value;
+  return DecodeSLEB128(data, Length(), byte_index);
 }
 
 
@@ -11583,6 +11518,114 @@
 }
 
 
+intptr_t CodeSourceMap::Length() const {
+  return raw_ptr()->length_;
+}
+
+
+void CodeSourceMap::SetLength(intptr_t value) const {
+  StoreNonPointer(&raw_ptr()->length_, value);
+}
+
+
+void CodeSourceMap::CopyData(GrowableArray<uint8_t>* delta_encoded_data) {
+  NoSafepointScope no_safepoint;
+  uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]);
+  for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) {
+    data[i] = (*delta_encoded_data)[i];
+  }
+}
+
+
+RawCodeSourceMap* CodeSourceMap::New(GrowableArray<uint8_t>* data) {
+  ASSERT(Object::code_source_map_class() != Class::null());
+  Thread* thread = Thread::Current();
+  CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
+  {
+    uword size = CodeSourceMap::InstanceSize(data->length());
+    RawObject* raw = Object::Allocate(CodeSourceMap::kClassId,
+                                      size,
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+    result.SetLength(data->length());
+    result.CopyData(data);
+  }
+  return result.raw();
+}
+
+
+RawCodeSourceMap* CodeSourceMap::New(intptr_t length) {
+  ASSERT(Object::code_source_map_class() != Class::null());
+  Thread* thread = Thread::Current();
+  CodeSourceMap& result = CodeSourceMap::Handle(thread->zone());
+  {
+    uword size = CodeSourceMap::InstanceSize(length);
+    RawObject* raw = Object::Allocate(CodeSourceMap::kClassId,
+                                      size,
+                                      Heap::kOld);
+    NoSafepointScope no_safepoint;
+    result ^= raw;
+    result.SetLength(length);
+  }
+  return result.raw();
+}
+
+
+void CodeSourceMap::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  Object::PrintJSONImpl(stream, ref);
+}
+
+
+const char* CodeSourceMap::ToCString() const {
+  // "*" in a printf format specifier tells it to read the field width from
+  // the printf argument list.
+#define FORMAT "%#-*" Px "\t%" Pd "\n"
+  if (Length() == 0) {
+    return "empty CodeSourceMap\n";
+  }
+  // 4 bits per hex digit.
+  const int addr_width = kBitsPerWord / 4;
+  // First compute the buffer size required.
+  intptr_t len = 1;  // Trailing '\0'.
+  {
+    Iterator iter(*this);
+    while (iter.MoveNext()) {
+      len += OS::SNPrint(NULL, 0, FORMAT, addr_width,
+                         iter.PcOffset(),
+                         iter.TokenPos());
+    }
+  }
+  // Allocate the buffer.
+  char* buffer = Thread::Current()->zone()->Alloc<char>(len);
+  // Layout the fields in the buffer.
+  intptr_t index = 0;
+  Iterator iter(*this);
+  while (iter.MoveNext()) {
+    index += OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width,
+                         iter.PcOffset(),
+                         iter.TokenPos());
+  }
+  return buffer;
+#undef FORMAT
+}
+
+
+// Encode integer in SLEB128 format.
+void CodeSourceMap::EncodeInteger(GrowableArray<uint8_t>* data,
+                                  intptr_t value) {
+  return EncodeSLEB128(data, value);
+}
+
+
+// Decode SLEB128 encoded integer. Update byte_index to the next integer.
+intptr_t CodeSourceMap::DecodeInteger(intptr_t* byte_index) const {
+  NoSafepointScope no_safepoint;
+  const uint8_t* data = raw_ptr()->data();
+  return DecodeSLEB128(data, Length(), byte_index);
+}
+
+
 bool Stackmap::GetBit(intptr_t bit_index) const {
   ASSERT(InRange(bit_index));
   int byte_index = bit_index >> kBitsPerByteLog2;
@@ -14379,7 +14422,7 @@
 
 
 void SubtypeTestCache::AddCheck(
-    intptr_t instance_class_id,
+    const Object& instance_class_id_or_function,
     const TypeArguments& instance_type_arguments,
     const TypeArguments& instantiator_type_arguments,
     const Bool& test_result) const {
@@ -14389,24 +14432,24 @@
   data = Array::Grow(data, new_len);
   set_cache(data);
   intptr_t data_pos = old_num * kTestEntryLength;
-  data.SetAt(data_pos + kInstanceClassId,
-      Smi::Handle(Smi::New(instance_class_id)));
+  data.SetAt(data_pos + kInstanceClassIdOrFunction,
+             instance_class_id_or_function);
   data.SetAt(data_pos + kInstanceTypeArguments, instance_type_arguments);
   data.SetAt(data_pos + kInstantiatorTypeArguments,
-      instantiator_type_arguments);
+             instantiator_type_arguments);
   data.SetAt(data_pos + kTestResult, test_result);
 }
 
 
 void SubtypeTestCache::GetCheck(intptr_t ix,
-                                intptr_t* instance_class_id,
+                                Object* instance_class_id_or_function,
                                 TypeArguments* instance_type_arguments,
                                 TypeArguments* instantiator_type_arguments,
                                 Bool* test_result) const {
   Array& data = Array::Handle(cache());
   intptr_t data_pos = ix * kTestEntryLength;
-  *instance_class_id =
-      Smi::Value(Smi::RawCast(data.At(data_pos + kInstanceClassId)));
+  *instance_class_id_or_function =
+      data.At(data_pos + kInstanceClassIdOrFunction);
   *instance_type_arguments ^= data.At(data_pos + kInstanceTypeArguments);
   *instantiator_type_arguments ^=
       data.At(data_pos + kInstantiatorTypeArguments);
@@ -14503,6 +14546,7 @@
 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
                                                const Script& script,
                                                intptr_t token_pos,
+                                               bool report_after_token,
                                                Report::Kind kind,
                                                Heap::Space space,
                                                const char* format,
@@ -14519,6 +14563,7 @@
   result.set_previous_error(prev_error);
   result.set_script(script);
   result.set_token_pos(token_pos);
+  result.set_report_after_token(report_after_token);
   result.set_kind(kind);
   result.set_message(String::Handle(
       String::NewFormattedV(format, args, space)));
@@ -14529,13 +14574,15 @@
 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
                                               const Script& script,
                                               intptr_t token_pos,
+                                              bool report_after_token,
                                               Report::Kind kind,
                                               Heap::Space space,
                                               const char* format, ...) {
   va_list args;
   va_start(args, format);
   RawLanguageError* result = LanguageError::NewFormattedV(
-      prev_error, script, token_pos, kind, space, format, args);
+      prev_error, script, token_pos, report_after_token,
+      kind, space, format, args);
   NoSafepointScope no_safepoint;
   va_end(args);
   return result;
@@ -14571,11 +14618,16 @@
 
 
 void LanguageError::set_token_pos(intptr_t token_pos) const {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
+void LanguageError::set_report_after_token(bool value) {
+  StoreNonPointer(&raw_ptr()->report_after_token_, value);
+}
+
+
 void LanguageError::set_kind(uint8_t value) const {
   StoreNonPointer(&raw_ptr()->kind_, value);
 }
@@ -14599,6 +14651,7 @@
       Report::PrependSnippet(kind(),
                              Script::Handle(script()),
                              token_pos(),
+                             report_after_token(),
                              String::Handle(message())));
   // Prepend previous error message.
   const Error& prev_error = Error::Handle(previous_error());
@@ -14955,11 +15008,32 @@
 }
 
 
-RawType* Instance::GetType() const {
+RawAbstractType* Instance::GetType() const {
   if (IsNull()) {
     return Type::NullType();
   }
   const Class& cls = Class::Handle(clazz());
+  if (cls.IsClosureClass()) {
+    const Function& signature =
+        Function::Handle(Closure::Cast(*this).function());
+    FunctionType& type = FunctionType::Handle(signature.SignatureType());
+    if (type.scope_class() == cls.raw()) {
+      // Type is not parameterized.
+      if (!type.IsCanonical()) {
+        type ^= type.Canonicalize();
+        signature.SetSignatureType(type);
+      }
+      return type.raw();
+    }
+    const Class& scope_cls = Class::Handle(type.scope_class());
+    ASSERT(scope_cls.NumTypeArguments() > 0);
+    TypeArguments& type_arguments = TypeArguments::Handle(GetTypeArguments());
+    type = FunctionType::New(
+        scope_cls, type_arguments, signature, Token::kNoSourcePos);
+    type.SetIsFinalized();
+    type ^= type.Canonicalize();
+    return type.raw();
+  }
   Type& type = Type::Handle();
   if (!cls.IsGeneric()) {
     type = cls.CanonicalType();
@@ -14969,7 +15043,7 @@
     if (cls.NumTypeArguments() > 0) {
       type_arguments = GetTypeArguments();
     }
-    type = Type::New(cls, type_arguments, Scanner::kNoSourcePos);
+    type = Type::New(cls, type_arguments, Token::kNoSourcePos);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
@@ -15008,6 +15082,47 @@
   }
   Zone* zone = Thread::Current()->zone();
   const Class& cls = Class::Handle(zone, clazz());
+  if (cls.IsClosureClass()) {
+    if (other.IsObjectType() || other.IsDartFunctionType()) {
+      return true;
+    }
+    Function& other_signature = Function::Handle(zone);
+    TypeArguments& other_type_arguments = TypeArguments::Handle(zone);
+    // Note that we may encounter a bound error in checked mode.
+    if (!other.IsInstantiated()) {
+      const AbstractType& instantiated_other = AbstractType::Handle(
+          zone, other.InstantiateFrom(other_instantiator, bound_error));
+      if ((bound_error != NULL) && !bound_error->IsNull()) {
+        ASSERT(Isolate::Current()->flags().type_checks());
+        return false;
+      }
+      if (instantiated_other.IsDynamicType() ||
+          instantiated_other.IsObjectType() ||
+          instantiated_other.IsDartFunctionType()) {
+        return true;
+      }
+      if (!instantiated_other.IsFunctionType()) {
+        return false;
+      }
+      other_signature = FunctionType::Cast(instantiated_other).signature();
+      other_type_arguments = instantiated_other.arguments();
+    } else {
+      if (!other.IsFunctionType()) {
+        return false;
+      }
+      other_signature = FunctionType::Cast(other).signature();
+      other_type_arguments = other.arguments();
+    }
+    const Function& signature =
+        Function::Handle(zone, Closure::Cast(*this).function());
+    const TypeArguments& type_arguments =
+        TypeArguments::Handle(zone, GetTypeArguments());
+    return signature.IsSubtypeOf(type_arguments,
+                                 other_signature,
+                                 other_type_arguments,
+                                 bound_error,
+                                 Heap::kOld);
+  }
   TypeArguments& type_arguments = TypeArguments::Handle(zone);
   if (cls.NumTypeArguments() > 0) {
     type_arguments = GetTypeArguments();
@@ -15025,20 +15140,54 @@
   }
   Class& other_class = Class::Handle(zone);
   TypeArguments& other_type_arguments = TypeArguments::Handle(zone);
+  AbstractType& instantiated_other = AbstractType::Handle(zone, other.raw());
   // Note that we may encounter a bound error in checked mode.
   if (!other.IsInstantiated()) {
-    const AbstractType& instantiated_other = AbstractType::Handle(
-        zone, other.InstantiateFrom(other_instantiator, bound_error));
+    instantiated_other = other.InstantiateFrom(other_instantiator, bound_error);
     if ((bound_error != NULL) && !bound_error->IsNull()) {
       ASSERT(Isolate::Current()->flags().type_checks());
       return false;
     }
-    other_class = instantiated_other.type_class();
-    other_type_arguments = instantiated_other.arguments();
-  } else {
-    other_class = other.type_class();
-    other_type_arguments = other.arguments();
+    if (instantiated_other.IsTypeRef()) {
+      instantiated_other = TypeRef::Cast(instantiated_other).type();
+    }
+    if (instantiated_other.IsDynamicType()) {
+      return true;
+    }
   }
+  other_type_arguments = instantiated_other.arguments();
+  const bool other_is_dart_function = instantiated_other.IsDartFunctionType();
+  if (other_is_dart_function || instantiated_other.IsFunctionType()) {
+    // Check if this instance understands a call() method of a compatible type.
+    Function& call =
+        Function::Handle(zone, cls.LookupDynamicFunction(Symbols::Call()));
+    if (call.IsNull()) {
+      // Walk up the super_class chain.
+      Class& super_cls = Class::Handle(zone, cls.SuperClass());
+      while (!super_cls.IsNull() && call.IsNull()) {
+        call = super_cls.LookupDynamicFunction(Symbols::Call());
+        super_cls = super_cls.SuperClass();
+      }
+    }
+    if (!call.IsNull()) {
+      if (other_is_dart_function) {
+        return true;
+      }
+      const Function& other_signature = Function::Handle(
+          zone, FunctionType::Cast(instantiated_other).signature());
+      if (call.IsSubtypeOf(type_arguments,
+                           other_signature,
+                           other_type_arguments,
+                           bound_error,
+                           Heap::kOld)) {
+        return true;
+      }
+    }
+  }
+  if (!instantiated_other.IsType()) {
+    return false;
+  }
+  other_class = instantiated_other.type_class();
   return cls.IsSubtypeOf(type_arguments, other_class, other_type_arguments,
                          bound_error, Heap::kOld);
 }
@@ -15104,17 +15253,11 @@
 }
 
 
-bool Instance::IsClosure() const {
-  const Class& cls = Class::Handle(clazz());
-  return cls.IsSignatureClass();
-}
-
-
 bool Instance::IsCallable(Function* function) const {
   Class& cls = Class::Handle(clazz());
-  if (cls.IsSignatureClass()) {
+  if (cls.IsClosureClass()) {
     if (function != NULL) {
-      *function = Closure::function(*this);
+      *function = Closure::Cast(*this).function();
     }
     return true;
   }
@@ -15219,7 +15362,7 @@
     return "Instance";
   } else {
     if (IsClosure()) {
-      return Closure::ToCString(*this);
+      return Closure::Cast(*this).ToCString();
     }
     const Class& cls = Class::Handle(clazz());
     TypeArguments& type_arguments = TypeArguments::Handle();
@@ -15228,7 +15371,7 @@
       type_arguments = GetTypeArguments();
     }
     const Type& type =
-        Type::Handle(Type::New(cls, type_arguments, Scanner::kNoSourcePos));
+        Type::Handle(Type::New(cls, type_arguments, Token::kNoSourcePos));
     const String& type_name = String::Handle(type.UserVisibleName());
     return OS::SCreate(Thread::Current()->zone(),
         "Instance of '%s'", type_name.ToCString());
@@ -15304,9 +15447,9 @@
   jsobj.AddServiceId(*this);
   if (IsClosure()) {
     jsobj.AddProperty("closureFunction",
-                      Function::Handle(Closure::function(*this)));
+                      Function::Handle(Closure::Cast(*this).function()));
     jsobj.AddProperty("closureContext",
-                      Context::Handle(Closure::context(*this)));
+                      Context::Handle(Closure::Cast(*this).context()));
   }
   if (ref) {
     return;
@@ -15328,6 +15471,12 @@
 }
 
 
+void AbstractType::SetIsResolved() const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+}
+
+
 bool AbstractType::HasResolvedTypeClass() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -15356,6 +15505,11 @@
 }
 
 
+void AbstractType::set_arguments(const TypeArguments& value) const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+}
+
 intptr_t AbstractType::token_pos() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -15377,6 +15531,12 @@
 }
 
 
+void AbstractType::SetIsFinalized() const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+}
+
+
 bool AbstractType::IsBeingFinalized() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -15384,6 +15544,12 @@
 }
 
 
+void AbstractType::SetIsBeingFinalized() const {
+  // AbstractType is an abstract class.
+  UNREACHABLE();
+}
+
+
 bool AbstractType::IsMalformed() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
@@ -15538,8 +15704,29 @@
   String& class_name = String::Handle(zone);
   intptr_t first_type_param_index;
   intptr_t num_type_params;  // Number of type parameters to print.
-  if (HasResolvedTypeClass()) {
-    const Class& cls = Class::Handle(zone, type_class());
+  Class& cls = Class::Handle(zone);
+  if (IsFunctionType()) {
+    cls = type_class();
+    if (!cls.IsTypedefClass()) {
+      const Function& signature_function = Function::Handle(
+          zone, FunctionType::Cast(*this).signature());
+      if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
+        return signature_function.UserVisibleSignature();
+      }
+      return signature_function.InstantiatedSignatureFrom(args,
+                                                          name_visibility);
+    }
+    class_name = cls.Name();  // Typedef name.
+    // We may be reporting an error about a malformed function type. In that
+    // case, avoid instantiating the signature, since it may cause divergence.
+    if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
+      return class_name.raw();
+    }
+    // Print the name of a typedef as a regular, possibly parameterized, class.
+  } else if (HasResolvedTypeClass()) {
+    cls = type_class();
+  }
+  if (!cls.IsNull()) {
     if (IsResolved() || !cls.IsMixinApplication()) {
       // Do not print the full vector, but only the declared type parameters.
       num_type_params = cls.NumTypeParameters();
@@ -15577,29 +15764,8 @@
         first_type_param_index = num_args - num_type_params;
       }
     }
-    if (cls.IsSignatureClass()) {
-      // We may be reporting an error about a malformed function type. In that
-      // case, avoid instantiating the signature, since it may cause divergence.
-      if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
-        return class_name.raw();
-      }
-      // To avoid divergence, print the name of a typedef (non-canonical
-      // signature class) as a regular, possibly parameterized, class.
-      if (cls.IsCanonicalSignatureClass()) {
-        const Function& signature_function = Function::Handle(
-            zone, cls.signature_function());
-        // Signature classes have no super type, however, they take as many
-        // type arguments as the owner class of their signature function (if it
-        // is non static and generic, see Class::NumTypeArguments()). Therefore,
-        // first_type_param_index may be greater than 0 here.
-        return signature_function.InstantiatedSignatureFrom(args,
-                                                            name_visibility);
-      }
-    }
   } else {
-    const UnresolvedClass& cls =
-        UnresolvedClass::Handle(zone, unresolved_class());
-    class_name = cls.Name();
+    class_name = UnresolvedClass::Handle(zone, unresolved_class()).Name();
     num_type_params = num_args;
     first_type_param_index = 0;
   }
@@ -15691,7 +15857,7 @@
 }
 
 
-bool AbstractType::IsFunctionType() const {
+bool AbstractType::IsDartFunctionType() const {
   return HasResolvedTypeClass() &&
       (type_class() == Type::Handle(Type::Function()).type_class());
 }
@@ -15729,6 +15895,9 @@
     }
     return false;
   }
+  if (other.IsObjectType() || other.IsDynamicType()) {
+    return true;
+  }
   if (IsBoundedType() || other.IsBoundedType()) {
     if (Equals(other)) {
       return true;
@@ -15740,6 +15909,7 @@
     }
     return false;  // TODO(regis): We should return "maybe after instantiation".
   }
+  Zone* zone = Thread::Current()->zone();
   // Type parameters cannot be handled by Class::TypeTest().
   // When comparing two uninstantiated function types, one returning type
   // parameter K, the other returning type parameter V, we cannot assume that K
@@ -15748,7 +15918,7 @@
   // The same rule applies when checking the upper bound of a still
   // uninstantiated type at compile time. Returning false will defer the test
   // to run time.
-  // There are however some cases can be decided at compile time.
+  // There are however some cases that can be decided at compile time.
   // For example, with class A<K, V extends K>, new A<T, T> called from within
   // a class B<T> will never require a run time bound check, even if T is
   // uninstantiated at compile time.
@@ -15760,7 +15930,7 @@
         return true;
       }
     }
-    const AbstractType& bound = AbstractType::Handle(type_param.bound());
+    const AbstractType& bound = AbstractType::Handle(zone, type_param.bound());
     // We may be checking bounds at finalization time and can encounter
     // a still unfinalized bound. Finalizing the bound here may lead to cycles.
     if (!bound.IsFinalized()) {
@@ -15774,13 +15944,59 @@
   if (other.IsTypeParameter()) {
     return false;  // TODO(regis): We should return "maybe after instantiation".
   }
-  const Class& cls = Class::Handle(type_class());
-  return cls.TypeTest(test_kind,
-                      TypeArguments::Handle(arguments()),
-                      Class::Handle(other.type_class()),
-                      TypeArguments::Handle(other.arguments()),
-                      bound_error,
-                      space);
+  const Class& type_cls = Class::Handle(zone, type_class());
+  // Function types cannot be handled by Class::TypeTest().
+  const bool other_is_dart_function_type = other.IsDartFunctionType();
+  if (other_is_dart_function_type || other.IsFunctionType()) {
+    if (IsFunctionType()) {
+      if (other_is_dart_function_type) {
+        return true;
+      }
+      const Function& other_fun =
+          Function::Handle(zone, FunctionType::Cast(other).signature());
+      // Check for two function types.
+      const Function& fun =
+          Function::Handle(zone, FunctionType::Cast(*this).signature());
+      return fun.TypeTest(test_kind,
+                          TypeArguments::Handle(zone, arguments()),
+                          other_fun,
+                          TypeArguments::Handle(zone, other.arguments()),
+                          bound_error,
+                          space);
+    }
+    // Check if type S has a call() method of function type T.
+    Function& function =
+        Function::Handle(zone, type_cls.LookupDynamicFunction(Symbols::Call()));
+    if (function.IsNull()) {
+      // Walk up the super_class chain.
+      Class& cls = Class::Handle(zone, type_cls.SuperClass());
+      while (!cls.IsNull() && function.IsNull()) {
+        function = cls.LookupDynamicFunction(Symbols::Call());
+        cls = cls.SuperClass();
+      }
+    }
+    if (!function.IsNull()) {
+      if (other_is_dart_function_type ||
+          function.TypeTest(test_kind,
+                            TypeArguments::Handle(zone, arguments()),
+                            Function::Handle(
+                                zone, FunctionType::Cast(other).signature()),
+                            TypeArguments::Handle(zone, other.arguments()),
+                            bound_error,
+                            space)) {
+        return true;
+      }
+    }
+  }
+  if (IsFunctionType()) {
+    return false;
+  }
+  return type_cls.TypeTest(test_kind,
+                           TypeArguments::Handle(zone, arguments()),
+                           Class::Handle(zone, other.type_class()),
+                           TypeArguments::Handle(zone, other.arguments()),
+                           bound_error,
+                           space);
 }
 
 
@@ -15890,7 +16106,7 @@
     const TypeArguments& no_type_arguments = TypeArguments::Handle();
     type ^= Type::New(Object::Handle(type_class.raw()),
                       no_type_arguments,
-                      Scanner::kNoSourcePos);
+                      Token::kNoSourcePos);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
@@ -15910,14 +16126,7 @@
 }
 
 
-void Type::ResetIsFinalized() const {
-  ASSERT(IsFinalized());
-  set_type_state(RawType::kBeingFinalized);
-  SetIsFinalized();
-}
-
-
-void Type::set_is_being_finalized() const {
+void Type::SetIsBeingFinalized() const {
   ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized());
   set_type_state(RawType::kBeingFinalized);
 }
@@ -15962,8 +16171,10 @@
 }
 
 
-void Type::set_is_resolved() const {
+void Type::SetIsResolved() const {
   ASSERT(!IsResolved());
+  // A Typedef is a FunctionType, not a type.
+  ASSERT(!Class::Handle(type_class()).IsTypedefClass());
   set_type_state(RawType::kResolved);
 }
 
@@ -16001,11 +16212,6 @@
 }
 
 
-RawTypeArguments* Type::arguments() const {
-  return raw_ptr()->arguments_;
-}
-
-
 bool Type::IsInstantiated(TrailPtr trail) const {
   if (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) {
     return true;
@@ -16021,7 +16227,6 @@
   intptr_t len = num_type_args;  // Check the full vector of type args.
   ASSERT(num_type_args > 0);
   // This type is not instantiated if it refers to type parameters.
-  // This IsInstantiated() call may be invoked on an unresolved signature type.
   // Although this type may still be unresolved, the type parameters it may
   // refer to are resolved by definition. We can therefore return the correct
   // result even for an unresolved type. We just need to look at all type
@@ -16068,7 +16273,8 @@
 
   // This uninstantiated type is not modified, as it can be instantiated
   // with different instantiators. Allocate a new instantiated version of it.
-  instantiated_type = Type::New(cls, TypeArguments::Handle(zone), token_pos());
+  instantiated_type =
+      Type::New(cls, TypeArguments::Handle(zone), token_pos(), space);
   TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments());
   ASSERT(type_arguments.Length() == cls.NumTypeArguments());
   if (type_arguments.IsRecursive()) {
@@ -16082,7 +16288,7 @@
   if (IsFinalized()) {
     instantiated_type.SetIsFinalized();
   } else {
-    instantiated_type.set_is_resolved();
+    instantiated_type.SetIsResolved();
   }
   // Canonicalization is not part of instantiation.
   return instantiated_type.raw();
@@ -16184,9 +16390,9 @@
   ASSERT(!IsBeingFinalized());  // Cloning must occur prior to finalization.
   TypeArguments& type_args = TypeArguments::Handle(arguments());
   type_args = type_args.CloneUnfinalized();
-  const Class& type_cls = Class::Handle(type_class());
-  const Type& clone = Type::Handle(Type::New(type_cls, type_args, token_pos()));
-  clone.set_is_resolved();
+  const Type& clone = Type::Handle(
+      Type::New(Class::Handle(type_class()), type_args, token_pos()));
+  clone.SetIsResolved();
   return clone.raw();
 }
 
@@ -16228,13 +16434,14 @@
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
-  Type& type = Type::Handle(zone);
+  AbstractType& type = Type::Handle(zone);
   const Class& cls = Class::Handle(zone, type_class());
+  ASSERT(!cls.IsTypedefClass());  // This type should be a FunctionType.
   if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
     return Object::dynamic_type().raw();
   }
   // Fast canonical lookup/registry for simple types.
-  if (!cls.IsGeneric()) {
+  if (!cls.IsGeneric() && !cls.IsClosureClass()) {
     type = cls.CanonicalType();
     if (type.IsNull()) {
       ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate()));
@@ -16319,36 +16526,6 @@
     canonical_types = new_canonical_types.raw();
   }
   canonical_types.SetAt(index, *this);
-  if ((index == 1) && cls.IsCanonicalSignatureClass()) {
-    canonical_types.SetAt(0, *this);  // Also set canonical signature type at 0.
-#ifdef DEBUG
-    // Verify that the first canonical type is the signature type by checking
-    // that the type argument vector of the canonical type ends with the
-    // uninstantiated type parameters of the signature class. Note that these
-    // type parameters may be bounded if the super class of the owner class
-    // declares bounds.
-    // The signature type is finalized during class finalization, before the
-    // optimizer may canonicalize instantiated function types of the same
-    // signature class.
-    // Although the signature class extends class Instance, the type arguments
-    // of the super class of the owner class of its signature function will be
-    // prepended to the type argument vector during class finalization.
-    const TypeArguments& type_params =
-        TypeArguments::Handle(zone, cls.type_parameters());
-    const intptr_t num_type_params = cls.NumTypeParameters();
-    const intptr_t num_type_args = cls.NumTypeArguments();
-    AbstractType& type_arg = AbstractType::Handle(zone);
-    TypeParameter& type_param = TypeParameter::Handle(zone);
-    for (intptr_t i = 0; i < num_type_params; i++) {
-      type_arg = type_args.TypeAt(num_type_args - num_type_params + i);
-      while (type_arg.IsBoundedType()) {
-        type_arg = BoundedType::Cast(type_arg).type();
-      }
-      type_param ^= type_params.TypeAt(i);
-      ASSERT(type_arg.Equals(type_param));
-    }
-#endif
-  }
   ASSERT(IsOld());
   ASSERT(type_args.IsNull() || type_args.IsOld());
   SetCanonical();
@@ -16399,7 +16576,7 @@
 
 
 void Type::set_token_pos(intptr_t token_pos) const {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -16465,6 +16642,552 @@
 }
 
 
+void FunctionType::SetIsFinalized() const {
+  ASSERT(!IsFinalized());
+  if (IsInstantiated()) {
+    set_type_state(RawFunctionType::kFinalizedInstantiated);
+  } else {
+    set_type_state(RawFunctionType::kFinalizedUninstantiated);
+  }
+}
+
+
+void FunctionType::ResetIsFinalized() const {
+  ASSERT(IsFinalized());
+  set_type_state(RawFunctionType::kBeingFinalized);
+  SetIsFinalized();
+}
+
+
+void FunctionType::SetIsBeingFinalized() const {
+  ASSERT(IsResolved() && !IsFinalized() && !IsBeingFinalized());
+  set_type_state(RawFunctionType::kBeingFinalized);
+}
+
+
+bool FunctionType::IsMalformed() const {
+  if (raw_ptr()->error_ == LanguageError::null()) {
+    return false;
+  }
+  const LanguageError& type_error = LanguageError::Handle(error());
+  return type_error.kind() == Report::kMalformedType;
+}
+
+
+bool FunctionType::IsMalbounded() const {
+  if (!Isolate::Current()->flags().type_checks()) {
+    return false;
+  }
+  if (raw_ptr()->error_ == LanguageError::null()) {
+    return false;
+  }
+  const LanguageError& type_error = LanguageError::Handle(error());
+  return type_error.kind() == Report::kMalboundedType;
+}
+
+
+bool FunctionType::IsMalformedOrMalbounded() const {
+  if (raw_ptr()->error_ == LanguageError::null()) {
+    return false;
+  }
+  const LanguageError& type_error = LanguageError::Handle(error());
+  if (type_error.kind() == Report::kMalformedType) {
+    return true;
+  }
+  ASSERT(type_error.kind() == Report::kMalboundedType);
+  return Isolate::Current()->flags().type_checks();
+}
+
+
+void FunctionType::set_error(const LanguageError& value) const {
+  StorePointer(&raw_ptr()->error_, value.raw());
+}
+
+
+void FunctionType::SetIsResolved() const {
+  ASSERT(!IsResolved());
+  set_type_state(RawFunctionType::kResolved);
+}
+
+
+bool FunctionType::IsInstantiated(TrailPtr trail) const {
+  if (raw_ptr()->type_state_ == RawFunctionType::kFinalizedInstantiated) {
+    return true;
+  }
+  if (raw_ptr()->type_state_ == RawFunctionType::kFinalizedUninstantiated) {
+    return false;
+  }
+  if (arguments() == TypeArguments::null()) {
+    return true;
+  }
+  const Class& scope_cls = Class::Handle(scope_class());
+  if (!scope_cls.IsGeneric()) {
+    ASSERT(scope_cls.IsClosureClass() || scope_cls.IsTypedefClass());
+    ASSERT(arguments() == TypeArguments::null());
+    return true;
+  }
+  const TypeArguments& type_arguments = TypeArguments::Handle(arguments());
+  const intptr_t num_type_args = scope_cls.NumTypeArguments();
+  const intptr_t num_type_params = scope_cls.NumTypeParameters();
+  // The vector may be longer than necessary. An empty vector is handled above.
+  ASSERT(type_arguments.Length() >= num_type_args);
+  return
+      (num_type_params == 0) ||
+      type_arguments.IsSubvectorInstantiated(num_type_args - num_type_params,
+                                             num_type_params);
+}
+
+
+RawAbstractType* FunctionType::InstantiateFrom(
+    const TypeArguments& instantiator_type_arguments,
+    Error* bound_error,
+    TrailPtr trail,
+    Heap::Space space) const {
+  Zone* zone = Thread::Current()->zone();
+  ASSERT(IsFinalized() || IsBeingFinalized());
+  ASSERT(!IsInstantiated());
+  ASSERT(!IsMalformed());  // FunctionType cannot be malformed.
+  // Instantiating this type with its own type arguments as instantiator can
+  // occur during finalization and bounds checking. Return the type unchanged.
+  if (arguments() == instantiator_type_arguments.raw()) {
+    return raw();
+  }
+  // If this type is recursive, we may already be instantiating it.
+  FunctionType& instantiated_type = FunctionType::Handle(zone);
+  instantiated_type ^= OnlyBuddyInTrail(trail);
+  if (!instantiated_type.IsNull()) {
+    ASSERT(IsRecursive());
+    return instantiated_type.raw();
+  }
+  // Note that the scope class has to be resolved at this time, but not
+  // necessarily finalized yet. We may be checking bounds at compile time or
+  // finalizing the type argument vector of a recursive type.
+  const Class& cls = Class::Handle(zone, scope_class());
+
+  // This uninstantiated type is not modified, as it can be instantiated
+  // with different instantiators. Allocate a new instantiated version of it.
+  instantiated_type =
+      FunctionType::New(cls,
+                        TypeArguments::Handle(zone),
+                        Function::Handle(zone, signature()),
+                        token_pos(),
+                        space);
+  TypeArguments& type_arguments = TypeArguments::Handle(zone, arguments());
+  ASSERT(type_arguments.Length() == cls.NumTypeArguments());
+  if (type_arguments.IsRecursive()) {
+    AddOnlyBuddyToTrail(&trail, instantiated_type);
+  }
+  type_arguments = type_arguments.InstantiateFrom(instantiator_type_arguments,
+                                                  bound_error,
+                                                  trail,
+                                                  space);
+  instantiated_type.set_arguments(type_arguments);
+  if (IsFinalized()) {
+    instantiated_type.SetIsFinalized();
+  } else {
+    instantiated_type.SetIsResolved();
+  }
+  // Canonicalization is not part of instantiation.
+  return instantiated_type.raw();
+}
+
+
+bool FunctionType::IsEquivalent(const Instance& other, TrailPtr trail) const {
+  ASSERT(!IsNull());
+  if (raw() == other.raw()) {
+    return true;
+  }
+  if (!other.IsFunctionType()) {
+    return false;
+  }
+  const FunctionType& other_type = FunctionType::Cast(other);
+  ASSERT(IsResolved() && other_type.IsResolved());
+  if (IsMalformed() || other_type.IsMalformed()) {
+    return false;
+  }
+  if (scope_class() != other_type.scope_class()) {
+    return false;
+  }
+  if ((arguments() == other_type.arguments()) &&
+      (signature() == other_type.signature())) {
+    return true;
+  }
+  if (!IsFinalized() || !other_type.IsFinalized()) {
+    return false;
+  }
+
+  // We do not instantiate the types of the signature. This happens on demand
+  // at runtime during a type test.
+  // Therefore, equal function types must have equal type arguments.
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  const TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
+  const TypeArguments& other_type_args = TypeArguments::Handle(
+      zone, other_type.arguments());
+  if (!type_args.Equals(other_type_args)) {
+    return false;
+  }
+
+  // Type arguments are equal.
+  // Equal function types must have equal signature types and equal optional
+  // named arguments.
+  if (signature() == other_type.signature()) {
+    return true;
+  }
+  const Function& sig_fun = Function::Handle(zone, signature());
+  const Function& other_sig_fun = Function::Handle(
+      zone, other_type.signature());
+
+  // Compare number of function parameters.
+  const intptr_t num_fixed_params = sig_fun.num_fixed_parameters();
+  const intptr_t other_num_fixed_params = other_sig_fun.num_fixed_parameters();
+  if (num_fixed_params != other_num_fixed_params) {
+    return false;
+  }
+  const intptr_t num_opt_pos_params = sig_fun.NumOptionalPositionalParameters();
+  const intptr_t other_num_opt_pos_params =
+      other_sig_fun.NumOptionalPositionalParameters();
+  if (num_opt_pos_params != other_num_opt_pos_params) {
+    return false;
+  }
+  const intptr_t num_opt_named_params = sig_fun.NumOptionalNamedParameters();
+  const intptr_t other_num_opt_named_params =
+      other_sig_fun.NumOptionalNamedParameters();
+  if (num_opt_named_params != other_num_opt_named_params) {
+    return false;
+  }
+  const intptr_t num_ignored_params = sig_fun.NumImplicitParameters();
+  const intptr_t other_num_ignored_params =
+      other_sig_fun.NumImplicitParameters();
+  if (num_ignored_params != other_num_ignored_params) {
+    return false;
+  }
+  AbstractType& param_type = Type::Handle(zone);
+  AbstractType& other_param_type = Type::Handle(zone);
+  // Check the result type.
+  param_type = sig_fun.result_type();
+  other_param_type = other_sig_fun.result_type();
+  if (!param_type.Equals(other_param_type)) {
+    return false;
+  }
+  // Check the types of all parameters.
+  const intptr_t num_params = sig_fun.NumParameters();
+  ASSERT(other_sig_fun.NumParameters() == num_params);
+  for (intptr_t i = 0; i < num_params; i++) {
+    param_type = sig_fun.ParameterTypeAt(i);
+    other_param_type = other_sig_fun.ParameterTypeAt(i);
+    if (!param_type.Equals(other_param_type)) {
+      return false;
+    }
+  }
+  // Check the names and types of optional named parameters.
+  if (num_opt_named_params == 0) {
+    return true;
+  }
+  for (intptr_t i = num_fixed_params; i < num_params; i++) {
+    if (sig_fun.ParameterNameAt(i) != other_sig_fun.ParameterNameAt(i)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool FunctionType::IsRecursive() const {
+  return TypeArguments::Handle(arguments()).IsRecursive();
+}
+
+
+RawAbstractType* FunctionType::CloneUnfinalized() const {
+  ASSERT(IsResolved());
+  if (IsFinalized()) {
+    return raw();
+  }
+  ASSERT(!IsMalformed());  // Malformed types are finalized.
+  ASSERT(!IsBeingFinalized());  // Cloning must occur prior to finalization.
+  TypeArguments& type_args = TypeArguments::Handle(arguments());
+  type_args = type_args.CloneUnfinalized();
+  const FunctionType& clone = FunctionType::Handle(
+      FunctionType::New(Class::Handle(scope_class()),
+                        type_args,
+                        Function::Handle(signature()),
+                        token_pos()));
+  clone.SetIsResolved();
+  return clone.raw();
+}
+
+
+RawAbstractType* FunctionType::CloneUninstantiated(const Class& new_owner,
+                                                   TrailPtr trail) const {
+  ASSERT(IsFinalized());
+  ASSERT(!IsMalformed());
+  if (IsInstantiated()) {
+    return raw();
+  }
+  // We may recursively encounter a type already being cloned, because we clone
+  // the upper bounds of its uninstantiated type arguments in the same pass.
+  FunctionType& clone = FunctionType::Handle();
+  clone ^= OnlyBuddyInTrail(trail);
+  if (!clone.IsNull()) {
+    return clone.raw();
+  }
+  clone = FunctionType::New(Class::Handle(scope_class()),
+                            TypeArguments::Handle(),
+                            Function::Handle(signature()),
+                            token_pos());
+  TypeArguments& type_args = TypeArguments::Handle(arguments());
+  // Upper bounds of uninstantiated type arguments may form a cycle.
+  if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
+    AddOnlyBuddyToTrail(&trail, clone);
+  }
+  type_args = type_args.CloneUninstantiated(new_owner, trail);
+  clone.set_arguments(type_args);
+  clone.SetIsFinalized();
+  return clone.raw();
+}
+
+
+RawAbstractType* FunctionType::Canonicalize(TrailPtr trail) const {
+  ASSERT(IsFinalized());
+  if (IsCanonical() || IsMalformed()) {
+    ASSERT(IsMalformed() || TypeArguments::Handle(arguments()).IsOld());
+    return this->raw();
+  }
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  AbstractType& type = Type::Handle(zone);
+  const Class& scope_cls = Class::Handle(zone, type_class());
+  Array& canonical_types = Array::Handle(zone);
+  canonical_types ^= scope_cls.canonical_types();
+  if (canonical_types.IsNull()) {
+    canonical_types = empty_array().raw();
+  }
+  intptr_t length = canonical_types.Length();
+  // Linear search to see whether this type is already present in the
+  // list of canonicalized types.
+  // TODO(asiva): Try to re-factor this lookup code to make sharing
+  // easy between the 4 versions of this loop.
+  intptr_t index = 1;  // Slot 0 is reserved for CanonicalType().
+  while (index < length) {
+    type ^= canonical_types.At(index);
+    if (type.IsNull()) {
+      break;
+    }
+    ASSERT(type.IsFinalized());
+    if (this->Equals(type)) {
+      ASSERT(type.IsCanonical());
+      return type.raw();
+    }
+    index++;
+  }
+  // The type was not found in the table. It is not canonical yet.
+
+  // Canonicalize the type arguments.
+  TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
+  // In case the type is first canonicalized at runtime, its type argument
+  // vector may be longer than necessary. This is not an issue.
+  ASSERT(type_args.IsNull() ||
+         (type_args.Length() >= scope_cls.NumTypeArguments()));
+  type_args = type_args.Canonicalize(trail);
+  set_arguments(type_args);
+
+  // Replace the actual function by a signature function.
+  const Function& fun = Function::Handle(zone, signature());
+  if (!fun.IsSignatureFunction()) {
+    Function& sig_fun =
+        Function::Handle(zone,
+                         Function::NewSignatureFunction(scope_cls,
+                                                        Token::kNoSourcePos));
+    type = fun.result_type();
+    type = type.Canonicalize(trail);
+    sig_fun.set_result_type(type);
+    const intptr_t num_params = fun.NumParameters();
+    sig_fun.set_num_fixed_parameters(fun.num_fixed_parameters());
+    sig_fun.SetNumOptionalParameters(fun.NumOptionalParameters(),
+                                     fun.HasOptionalPositionalParameters());
+    sig_fun.set_parameter_types(Array::Handle(Array::New(num_params,
+                                                         Heap::kOld)));
+    for (intptr_t i = 0; i < num_params; i++) {
+      type = fun.ParameterTypeAt(i);
+      type = type.Canonicalize(trail);
+      sig_fun.SetParameterTypeAt(i, type);
+    }
+    sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names()));
+    set_signature(sig_fun);
+  }
+
+  // Canonicalizing the type arguments and the signature may have changed the
+  // index, may have grown the table, or may even have canonicalized this type.
+  canonical_types ^= scope_cls.canonical_types();
+  if (canonical_types.IsNull()) {
+    canonical_types = empty_array().raw();
+  }
+  length = canonical_types.Length();
+  while (index < length) {
+    type ^= canonical_types.At(index);
+    if (type.IsNull()) {
+      break;
+    }
+    ASSERT(type.IsFinalized());
+    if (this->Equals(type)) {
+      ASSERT(type.IsCanonical());
+      return type.raw();
+    }
+    index++;
+  }
+
+  // The type needs to be added to the list. Grow the list if it is full.
+  if (index >= length) {
+    ASSERT((index == length) || ((index == 1) && (length == 0)));
+    const intptr_t new_length = (length > 64) ?
+        (length + 64) :
+        ((length == 0) ? 2 : (length * 2));
+    const Array& new_canonical_types = Array::Handle(
+        zone, Array::Grow(canonical_types, new_length, Heap::kOld));
+    scope_cls.set_canonical_types(new_canonical_types);
+    canonical_types = new_canonical_types.raw();
+  }
+  canonical_types.SetAt(index, *this);
+  ASSERT(IsOld());
+  ASSERT(type_args.IsNull() || type_args.IsOld());
+  SetCanonical();
+  return this->raw();
+}
+
+
+intptr_t FunctionType::Hash() const {
+  ASSERT(IsFinalized());
+  uint32_t result = 1;
+  if (IsMalformed()) return result;
+  result = CombineHashes(result, Class::Handle(scope_class()).id());
+  result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash());
+  const Function& sig_fun = Function::Handle(signature());
+  AbstractType& type = AbstractType::Handle(sig_fun.result_type());
+  result = CombineHashes(result, type.Hash());
+  result = CombineHashes(result, sig_fun.NumOptionalPositionalParameters());
+  const intptr_t num_params = sig_fun.NumParameters();
+  for (intptr_t i = 0; i < num_params; i++) {
+    type = sig_fun.ParameterTypeAt(i);
+    result = CombineHashes(result, type.Hash());
+  }
+  if (sig_fun.NumOptionalNamedParameters() > 0) {
+    String& param_name = String::Handle();
+    for (intptr_t i = sig_fun.num_fixed_parameters(); i < num_params; i++) {
+      param_name = sig_fun.ParameterNameAt(i);
+      result = CombineHashes(result, param_name.Hash());
+    }
+  }
+  return FinalizeHash(result);
+}
+
+
+void FunctionType::set_scope_class(const Class& value) const {
+  ASSERT(!value.IsNull());
+  StorePointer(&raw_ptr()->scope_class_, value.raw());
+}
+
+
+void FunctionType::set_arguments(const TypeArguments& value) const {
+  StorePointer(&raw_ptr()->arguments_, value.raw());
+}
+
+
+void FunctionType::set_signature(const Function& value) const {
+  StorePointer(&raw_ptr()->signature_, value.raw());
+}
+
+
+RawFunctionType* FunctionType::New(Heap::Space space) {
+  RawObject* raw = Object::Allocate(FunctionType::kClassId,
+                                    FunctionType::InstanceSize(),
+                                    space);
+  return reinterpret_cast<RawFunctionType*>(raw);
+}
+
+
+RawFunctionType* FunctionType::New(const Class& clazz,
+                                   const TypeArguments& arguments,
+                                   const Function& signature,
+                                   intptr_t token_pos,
+                                   Heap::Space space) {
+  const FunctionType& result = FunctionType::Handle(FunctionType::New(space));
+  result.set_scope_class(clazz);
+  result.set_arguments(arguments);
+  result.set_signature(signature);
+  result.set_token_pos(token_pos);
+  result.StoreNonPointer(&result.raw_ptr()->type_state_,
+                         RawFunctionType::kAllocated);
+  return result.raw();
+}
+
+
+void FunctionType::set_token_pos(intptr_t token_pos) const {
+  ASSERT(!Token::IsClassifying(token_pos));
+  StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
+}
+
+
+void FunctionType::set_type_state(int8_t state) const {
+  ASSERT((state >= RawFunctionType::kAllocated) &&
+         (state <= RawFunctionType::kFinalizedUninstantiated));
+  StoreNonPointer(&raw_ptr()->type_state_, state);
+}
+
+
+const char* FunctionType::ToCString() const {
+  const char* unresolved = IsResolved() ? "" : "Unresolved ";
+  const Class& scope_cls = Class::Handle(scope_class());
+  const TypeArguments& type_arguments = TypeArguments::Handle(arguments());
+  const Function& signature_function = Function::Handle(signature());
+  const String& signature_string = String::Handle(
+      signature_function.InstantiatedSignatureFrom(type_arguments,
+                                                   kInternalName));
+  if (scope_cls.IsClosureClass()) {
+    ASSERT(arguments() == TypeArguments::null());
+    return OS::SCreate(
+        Thread::Current()->zone(),
+        "%sFunctionType: %s", unresolved, signature_string.ToCString());
+  }
+  const char* class_name = String::Handle(scope_cls.Name()).ToCString();
+  const char* args_cstr =
+      type_arguments.IsNull() ? "null" : type_arguments.ToCString();
+  return OS::SCreate(
+      Thread::Current()->zone(),
+      "%s FunctionType: %s (scope_cls: %s, args: %s)",
+      unresolved,
+      signature_string.ToCString(),
+      class_name,
+      args_cstr);
+}
+
+
+void FunctionType::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  JSONObject jsobj(stream);
+  PrintSharedInstanceJSON(&jsobj, ref);
+  jsobj.AddProperty("kind", "FunctionType");
+  if (IsCanonical()) {
+    const Class& scope_cls = Class::Handle(scope_class());
+    intptr_t id = scope_cls.FindCanonicalTypeIndex(*this);
+    ASSERT(id >= 0);
+    intptr_t cid = scope_cls.id();
+    jsobj.AddFixedServiceId("classes/%" Pd "/types/%" Pd "", cid, id);
+    jsobj.AddProperty("scopeClass", scope_cls);
+  } else {
+    jsobj.AddServiceId(*this);
+  }
+  const String& user_name = String::Handle(PrettyName());
+  const String& vm_name = String::Handle(Name());
+  AddNameProperties(&jsobj, user_name, vm_name);
+  if (ref) {
+    return;
+  }
+  const TypeArguments& typeArgs = TypeArguments::Handle(arguments());
+  if (!typeArgs.IsNull()) {
+    jsobj.AddProperty("typeArguments", typeArgs);
+  }
+}
+
+
 bool TypeRef::IsInstantiated(TrailPtr trail) const {
   if (TestAndAddToTrail(&trail)) {
     return true;
@@ -16528,7 +17251,7 @@
 
 
 void TypeRef::set_type(const AbstractType& value) const {
-  ASSERT(value.HasResolvedTypeClass());
+  ASSERT(value.IsFunctionType() || value.HasResolvedTypeClass());
   ASSERT(!value.IsTypeRef());
   StorePointer(&raw_ptr()->type_, value.raw());
 }
@@ -16640,7 +17363,7 @@
 }
 
 
-void TypeParameter::set_is_finalized() const {
+void TypeParameter::SetIsFinalized() const {
   ASSERT(!IsFinalized());
   set_type_state(RawTypeParameter::kFinalizedUninstantiated);
 }
@@ -16747,6 +17470,7 @@
           *bound_error,
           script,
           token_pos(),
+          Report::AtLocation,
           Report::kMalboundedType,
           Heap::kNew,
           "type parameter '%s' of class '%s' must extend bound '%s', "
@@ -16789,7 +17513,7 @@
                          String::Handle(name()),
                          upper_bound,
                          token_pos()));
-  clone.set_is_finalized();
+  clone.SetIsFinalized();
   return clone.raw();
 }
 
@@ -16830,7 +17554,7 @@
 
 
 void TypeParameter::set_token_pos(intptr_t token_pos) const {
-  ASSERT(Scanner::ValidSourcePosition(token_pos));
+  ASSERT(!Token::IsClassifying(token_pos));
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -21466,8 +22190,8 @@
 }
 
 
-const char* Closure::ToCString(const Instance& closure) {
-  const Function& fun = Function::Handle(Closure::function(closure));
+const char* Closure::ToCString() const {
+  const Function& fun = Function::Handle(function());
   const bool is_implicit_closure = fun.IsImplicitClosureFunction();
   const char* fun_sig = String::Handle(fun.UserVisibleSignature()).ToCString();
   const char* from = is_implicit_closure ? " from " : "";
@@ -21477,23 +22201,36 @@
 }
 
 
-RawInstance* Closure::New(const Function& function,
-                          const Context& context,
-                          Heap::Space space) {
-  const Class& cls = Class::Handle(function.signature_class());
-  ASSERT(cls.instance_size() == Closure::InstanceSize());
-  Instance& result = Instance::Handle();
+void Closure::PrintJSONImpl(JSONStream* stream, bool ref) const {
+  Instance::PrintJSONImpl(stream, ref);
+}
+
+
+RawClosure* Closure::New(const Function& function,
+                         const Context& context,
+                         Heap::Space space) {
+  Closure& result = Closure::Handle();
   {
-    RawObject* raw = Object::Allocate(cls.id(), Closure::InstanceSize(), space);
+    RawObject* raw = Object::Allocate(Closure::kClassId,
+                                      Closure::InstanceSize(),
+                                      space);
     NoSafepointScope no_safepoint;
     result ^= raw;
+    result.StorePointer(&result.raw_ptr()->function_, function.raw());
+    result.StorePointer(&result.raw_ptr()->context_, context.raw());
   }
-  Closure::set_function(result, function);
-  Closure::set_context(result, context);
   return result.raw();
 }
 
 
+RawClosure* Closure::New() {
+  RawObject* raw = Object::Allocate(Closure::kClassId,
+                                    Closure::InstanceSize(),
+                                    Heap::kOld);
+  return reinterpret_cast<RawClosure*>(raw);
+}
+
+
 intptr_t Stacktrace::Length() const {
   const Array& code_array = Array::Handle(raw_ptr()->code_array_);
   return code_array.Length();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d67b06a..5ce318c 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -507,6 +507,7 @@
   static RawClass* instructions_class() { return instructions_class_; }
   static RawClass* object_pool_class() { return object_pool_class_; }
   static RawClass* pc_descriptors_class() { return pc_descriptors_class_; }
+  static RawClass* code_source_map_class() { return code_source_map_class_; }
   static RawClass* stackmap_class() { return stackmap_class_; }
   static RawClass* var_descriptors_class() { return var_descriptors_class_; }
   static RawClass* exception_handlers_class() {
@@ -768,6 +769,7 @@
   static RawClass* instructions_class_;  // Class of the Instructions vm object.
   static RawClass* object_pool_class_;  // Class of the ObjectPool vm object.
   static RawClass* pc_descriptors_class_;  // Class of PcDescriptors vm object.
+  static RawClass* code_source_map_class_;  // Class of CodeSourceMap vm object.
   static RawClass* stackmap_class_;  // Class of Stackmap vm object.
   static RawClass* var_descriptors_class_;  // Class of LocalVarDescriptors.
   static RawClass* exception_handlers_class_;  // Class of ExceptionHandlers.
@@ -941,26 +943,11 @@
 
   intptr_t ComputeEndTokenPos() const;
 
-  // This class represents the signature class of a closure function if
-  // signature_function() is not null.
-  // The associated function may be a closure function (with code) or a
-  // signature function (without code) solely describing the result type and
-  // parameter types of the signature.
+  // This class represents a typedef if the signature function is not null.
   RawFunction* signature_function() const {
     return raw_ptr()->signature_function_;
   }
-  static intptr_t signature_function_offset() {
-    return OFFSET_OF(RawClass, signature_function_);
-  }
-
-  // Return the signature type of this signature class.
-  // For example, if this class represents a signature of the form
-  // 'F<T, R>(T, [b: B, c: C]) => R', then its signature type is a parameterized
-  // type with this class as the type class and type parameters 'T' and 'R'
-  // as its type argument vector.
-  // SignatureType is used as the type of formal parameters representing a
-  // function.
-  RawType* SignatureType() const;
+  void set_signature_function(const Function& value) const;
 
   // Return the Type with type parameters declared by this class filled in with
   // dynamic and type parameters declared in superclasses filled in as declared
@@ -1004,6 +991,7 @@
   // not overlapping with the type arguments of the super class of this class.
   intptr_t NumOwnTypeArguments() const;
 
+  // Return true if this class declares type parameters.
   bool IsGeneric() const;
 
   // If this class is parameterized, each instance has a type_arguments field.
@@ -1094,22 +1082,23 @@
   // Check if this class represents the 'Function' class.
   bool IsFunctionClass() const;
 
-  // Check if this class represents a signature class.
-  bool IsSignatureClass() const {
+  // Check if this class represents the 'Closure' class.
+  bool IsClosureClass() const  { return id() == kClosureCid; }
+  static bool IsClosureClass(RawClass* cls) {
+    NoSafepointScope no_safepoint;
+    return cls->ptr()->id_ == kClosureCid;
+  }
+
+  // Check if this class represents a typedef class.
+  bool IsTypedefClass() const {
     return signature_function() != Object::null();
   }
-  static bool IsSignatureClass(RawClass* cls) {
-    return cls->ptr()->signature_function_ != Object::null();
-  }
+
   static bool IsInFullSnapshot(RawClass* cls) {
     NoSafepointScope no_safepoint;
     return cls->ptr()->library_->ptr()->is_in_fullsnapshot_;
   }
 
-  // Check if this class represents a canonical signature class, i.e. not an
-  // alias as defined in a typedef.
-  bool IsCanonicalSignatureClass() const;
-
   // Check the subtype relationship.
   bool IsSubtypeOf(const TypeArguments& type_arguments,
                    const Class& other,
@@ -1184,8 +1173,8 @@
 
   void InsertCanonicalConstant(intptr_t index, const Instance& constant) const;
 
-  intptr_t FindCanonicalTypeIndex(const Type& needle) const;
-  RawType* CanonicalTypeFromIndex(intptr_t idx) const;
+  intptr_t FindCanonicalTypeIndex(const AbstractType& needle) const;
+  RawAbstractType* CanonicalTypeFromIndex(intptr_t idx) const;
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawClass));
@@ -1334,21 +1323,6 @@
   // Allocate the raw ExternalTypedData classes.
   static RawClass* NewExternalTypedDataClass(intptr_t class_id);
 
-  // Allocate a class representing a function signature described by
-  // signature_function, which must be a closure function or a signature
-  // function.
-  // The class may be type parameterized unless the signature_function is in a
-  // static scope. In that case, the type parameters are copied from the owner
-  // class of signature_function.
-  // A null signature function may be passed in and patched later. See below.
-  static RawClass* NewSignatureClass(const String& name,
-                                     const Function& signature_function,
-                                     const Script& script,
-                                     intptr_t token_pos);
-
-  // Patch the signature function of a signature class allocated without it.
-  void PatchSignatureFunction(const Function& signature_function) const;
-
   // Register code that has used CHA for optimization.
   // TODO(srdjan): Also register kind of CHA optimization (e.g.: leaf class,
   // leaf method, ...).
@@ -1409,8 +1383,6 @@
   void set_user_name(const String& value) const;
   RawString* GeneratePrettyName() const;
   RawString* GenerateUserVisibleName() const;
-  void set_signature_function(const Function& value) const;
-  void set_signature_type(const AbstractType& value) const;
   void set_state_bits(intptr_t bits) const;
 
   void set_constants(const Array& value) const;
@@ -1483,6 +1455,7 @@
   friend class Instance;
   friend class Object;
   friend class Type;
+  friend class FunctionType;
   friend class Intrinsifier;
   friend class Precompiler;
 };
@@ -2108,6 +2081,17 @@
 
   RawString* GetSource() const;
 
+  // Return the type of this function's signature. It may not be canonical yet.
+  // For example, if this function has a signature of the form
+  // '(T, [b: B, c: C]) => R', where 'T' and 'R' are type parameters of the
+  // owner class of this function, then its signature type is a parameterized
+  // FunctionType with uninstantiated type arguments 'T' and 'R' as elements of
+  // its type argument vector.
+  RawFunctionType* SignatureType() const;
+
+  // Update the signature type (with a canonical version).
+  void SetSignatureType(const FunctionType& value) const;
+
   // Build a string of the form 'C<T, R>(T, {b: B, c: C}) => R' representing the
   // internal signature of the given function. In this example, T and R are
   // type parameters of class C, the owner of the function.
@@ -2124,9 +2108,10 @@
 
   // Build a string of the form '(T, {b: B, c: C}) => R' representing the
   // user visible signature of the given function. In this example, T and R are
-  // type parameters of class C, the owner of the function.
+  // type parameters of class C, the owner of the function, also called the
+  // scope class of the function type.
   // Implicit parameters are hidden, as well as the prefix denoting the
-  // signature class and its type parameters.
+  // scope class and its type parameters.
   RawString* UserVisibleSignature() const {
     const bool instantiate = false;
     return BuildSignature(
@@ -2219,10 +2204,6 @@
   // Enclosing function of this local function.
   RawFunction* parent_function() const;
 
-  // Signature class of this closure function or signature function.
-  RawClass* signature_class() const;
-  void set_signature_class(const Class& value) const;
-
   void set_extracted_method_closure(const Function& function) const;
   RawFunction* extracted_method_closure() const;
 
@@ -2494,6 +2475,14 @@
                     space);
   }
 
+  // Check the subtype or 'more specific' relationship.
+  bool TypeTest(TypeTestKind test_kind,
+                const TypeArguments& type_arguments,
+                const Function& other,
+                const TypeArguments& other_type_arguments,
+                Error* bound_error,
+                Heap::Space space) const;
+
   // Returns true if this function represents an explicit getter function.
   bool IsGetterFunction() const {
     return kind() == RawFunction::kGetterFunction;
@@ -2557,6 +2546,11 @@
   bool IsSignatureFunction() const {
     return kind() == RawFunction::kSignatureFunction;
   }
+  static bool IsSignatureFunction(RawFunction* function) {
+    NoSafepointScope no_safepoint;
+    return KindBits::decode(function->ptr()->kind_tag_) ==
+        RawFunction::kSignatureFunction;
+  }
 
   bool IsAsyncFunction() const {
     return modifier() == RawFunction::kAsync;
@@ -2612,14 +2606,16 @@
                           const Object& owner,
                           intptr_t token_pos);
 
-  // Allocates a new Function object representing a closure function, as well as
-  // a new associated Class object representing the signature class of the
-  // function.
-  // The function and the class share the same given name.
+  // Allocates a new Function object representing a closure function.
   static RawFunction* NewClosureFunction(const String& name,
                                          const Function& parent,
                                          intptr_t token_pos);
 
+  // Allocates a new Function object representing a signature function.
+  // The owner is the scope class of the function type.
+  static RawFunction* NewSignatureFunction(const Class& owner,
+                                           intptr_t token_pos);
+
   static RawFunction* NewEvalFunction(const Class& owner,
                                       const Script& script,
                                       bool is_static);
@@ -2775,14 +2771,6 @@
                             NameVisibility name_visibility,
                             const TypeArguments& instantiator) const;
 
-  // Check the subtype or 'more specific' relationship.
-  bool TypeTest(TypeTestKind test_kind,
-                const TypeArguments& type_arguments,
-                const Function& other,
-                const TypeArguments& other_type_arguments,
-                Error* bound_error,
-                Heap::Space space) const;
-
   // Checks the type of the formal parameter at the given position for
   // subtyping or 'more specific' relationship between the type of this function
   // and the type of the other function.
@@ -2819,9 +2807,9 @@
   RawFunction* parent_function() const { return raw_ptr()->parent_function_; }
   void set_parent_function(const Function& value) const;
 
-  // Signature class of this closure function or signature function.
-  RawClass* signature_class() const { return raw_ptr()->signature_class_; }
-  void set_signature_class(const Class& value) const;
+  // Signature type of this closure function.
+  RawFunctionType* signature_type() const { return raw_ptr()->signature_type_; }
+  void set_signature_type(const FunctionType& value) const;
 
   RawInstance* implicit_static_closure() const {
     return raw_ptr()->closure_;
@@ -3601,7 +3589,8 @@
   void InitClassDictionary() const;
 
   RawArray* resolved_names() const { return raw_ptr()->resolved_names_; }
-  void InitResolvedNamesCache(intptr_t size) const;
+  void InitResolvedNamesCache(intptr_t size,
+                              SnapshotReader* reader = NULL) const;
   void GrowResolvedNamesCache() const;
   bool LookupResolvedNamesCache(const String& name, Object* obj) const;
   void AddToResolvedNamesCache(const String& name, const Object& obj) const;
@@ -3986,6 +3975,77 @@
 };
 
 
+class CodeSourceMap : public Object {
+ public:
+  static const intptr_t kBytesPerElement = 1;
+  static const intptr_t kMaxElements = kMaxInt32 / kBytesPerElement;
+
+  static intptr_t InstanceSize() {
+    ASSERT(sizeof(RawCodeSourceMap) ==
+           OFFSET_OF_RETURNED_VALUE(RawCodeSourceMap, data));
+    return 0;
+  }
+  static intptr_t InstanceSize(intptr_t len) {
+    ASSERT(0 <= len && len <= kMaxElements);
+    return RoundedAllocationSize(sizeof(RawCodeSourceMap) + len);
+  }
+
+  static RawCodeSourceMap* New(GrowableArray<uint8_t>* delta_encoded_data);
+
+  void PrintToJSONObject(JSONObject* jsobj, bool ref) const;
+
+  // Encode integer in SLEB128 format.
+  static void EncodeInteger(GrowableArray<uint8_t>* data, intptr_t value);
+
+  // Decode SLEB128 encoded integer. Update byte_index to the next integer.
+  intptr_t DecodeInteger(intptr_t* byte_index) const;
+
+  class Iterator : ValueObject {
+   public:
+    explicit Iterator(const CodeSourceMap& code_source_map)
+        : code_source_map_(code_source_map),
+          byte_index_(0),
+          cur_pc_offset_(0),
+          cur_token_pos_(0) {
+    }
+
+    bool MoveNext() {
+      // Moves to the next record.
+      while (byte_index_ < code_source_map_.Length()) {
+        cur_pc_offset_ += code_source_map_.DecodeInteger(&byte_index_);
+        cur_token_pos_ += code_source_map_.DecodeInteger(&byte_index_);
+
+        return true;
+      }
+      return false;
+    }
+
+    uword PcOffset() const { return cur_pc_offset_; }
+    intptr_t TokenPos() const { return cur_token_pos_; }
+
+   private:
+    friend class CodeSourceMap;
+
+    const CodeSourceMap& code_source_map_;
+    intptr_t byte_index_;
+
+    intptr_t cur_pc_offset_;
+    intptr_t cur_token_pos_;
+  };
+
+ private:
+  static RawCodeSourceMap* New(intptr_t length);
+
+  intptr_t Length() const;
+  void SetLength(intptr_t value) const;
+  void CopyData(GrowableArray<uint8_t>* data);
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap, Object);
+  friend class Class;
+  friend class Object;
+};
+
+
 class Stackmap : public Object {
  public:
   static const intptr_t kNoMaximum = -1;
@@ -4216,6 +4276,15 @@
     StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw());
   }
 
+  RawCodeSourceMap* code_source_map() const {
+    return raw_ptr()->code_source_map_;
+  }
+
+  void set_code_source_map(const CodeSourceMap& code_source_map) const {
+    ASSERT(code_source_map.IsOld());
+    StorePointer(&raw_ptr()->code_source_map_, code_source_map.raw());
+  }
+
   // Array of DeoptInfo objects.
   RawArray* deopt_info_array() const {
     return raw_ptr()->deopt_info_array_;
@@ -4726,7 +4795,7 @@
 class SubtypeTestCache : public Object {
  public:
   enum Entries {
-    kInstanceClassId = 0,
+    kInstanceClassIdOrFunction = 0,
     kInstanceTypeArguments = 1,
     kInstantiatorTypeArguments = 2,
     kTestResult = 3,
@@ -4734,12 +4803,12 @@
   };
 
   intptr_t NumberOfChecks() const;
-  void AddCheck(intptr_t class_id,
+  void AddCheck(const Object& instance_class_id_or_function,
                 const TypeArguments& instance_type_arguments,
                 const TypeArguments& instantiator_type_arguments,
                 const Bool& test_result) const;
   void GetCheck(intptr_t ix,
-                intptr_t* class_id,
+                Object* instance_class_id_or_function,
                 TypeArguments* instance_type_arguments,
                 TypeArguments* instantiator_type_arguments,
                 Bool* test_result) const;
@@ -4817,14 +4886,16 @@
   static RawLanguageError* NewFormatted(const Error& prev_error,
                                         const Script& script,
                                         intptr_t token_pos,
+                                        bool report_after_token,
                                         Report::Kind kind,
                                         Heap::Space space,
                                         const char* format, ...)
-    PRINTF_ATTRIBUTE(6, 7);
+    PRINTF_ATTRIBUTE(7, 8);
 
   static RawLanguageError* NewFormattedV(const Error& prev_error,
                                          const Script& script,
                                          intptr_t token_pos,
+                                         bool report_after_token,
                                          Report::Kind kind,
                                          Heap::Space space,
                                          const char* format, va_list args);
@@ -4847,6 +4918,9 @@
   intptr_t token_pos() const { return raw_ptr()->token_pos_; }
   void set_token_pos(intptr_t value) const;
 
+  bool report_after_token() const { return raw_ptr()->report_after_token_; }
+  void set_report_after_token(bool value);
+
   void set_kind(uint8_t value) const;
 
   RawString* message() const { return raw_ptr()->message_; }
@@ -4957,7 +5031,7 @@
     StorePointer(FieldAddr(field), value.raw());
   }
 
-  RawType* GetType() const;
+  RawAbstractType* GetType() const;
 
   virtual RawTypeArguments* GetTypeArguments() const;
   virtual void SetTypeArguments(const TypeArguments& value) const;
@@ -4984,9 +5058,6 @@
 
   void SetNativeField(int index, intptr_t value) const;
 
-  // Returns true if the instance is a closure object.
-  bool IsClosure() const;
-
   // If the instance is a callable object, i.e. a closure or the instance of a
   // class implementing a 'call' method, return true and set the function
   // (if not NULL) to call.
@@ -5113,17 +5184,21 @@
 class AbstractType : public Instance {
  public:
   virtual bool IsFinalized() const;
+  virtual void SetIsFinalized() const;
   virtual bool IsBeingFinalized() const;
+  virtual void SetIsBeingFinalized() const;
   virtual bool IsMalformed() const;
   virtual bool IsMalbounded() const;
   virtual bool IsMalformedOrMalbounded() const;
   virtual RawLanguageError* error() const;
   virtual void set_error(const LanguageError& value) const;
   virtual bool IsResolved() const;
+  virtual void SetIsResolved() const;
   virtual bool HasResolvedTypeClass() const;
   virtual RawClass* type_class() const;
   virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawTypeArguments* arguments() const;
+  virtual void set_arguments(const TypeArguments& value) const;
   virtual intptr_t token_pos() const;
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
   virtual bool CanonicalizeEquals(const Instance& other) const {
@@ -5238,8 +5313,8 @@
   // Check if this type represents the 'String' type.
   bool IsStringType() const;
 
-  // Check if this type represents the 'Function' type.
-  bool IsFunctionType() const;
+  // Check if this type represents the Dart 'Function' type.
+  bool IsDartFunctionType() const;
 
   // Check the subtype relationship.
   bool IsSubtypeOf(const AbstractType& other,
@@ -5291,12 +5366,11 @@
         (raw_ptr()->type_state_ == RawType::kFinalizedInstantiated) ||
         (raw_ptr()->type_state_ == RawType::kFinalizedUninstantiated);
   }
-  void SetIsFinalized() const;
-  void ResetIsFinalized() const;  // Ignore current state and set again.
+  virtual void SetIsFinalized() const;
   virtual bool IsBeingFinalized() const {
     return raw_ptr()->type_state_ == RawType::kBeingFinalized;
   }
-  void set_is_being_finalized() const;
+  virtual void SetIsBeingFinalized() const;
   virtual bool IsMalformed() const;
   virtual bool IsMalbounded() const;
   virtual bool IsMalformedOrMalbounded() const;
@@ -5305,13 +5379,13 @@
   virtual bool IsResolved() const {
     return raw_ptr()->type_state_ >= RawType::kResolved;
   }
-  void set_is_resolved() const;
+  virtual void SetIsResolved() const;
   virtual bool HasResolvedTypeClass() const;  // Own type class resolved.
   virtual RawClass* type_class() const;
   void set_type_class(const Object& value) const;
   virtual RawUnresolvedClass* unresolved_class() const;
-  virtual RawTypeArguments* arguments() const;
-  void set_arguments(const TypeArguments& value) const;
+  virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
+  virtual void set_arguments(const TypeArguments& value) const;
   virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
   virtual bool IsEquivalent(const Instance& other, TrailPtr trail = NULL) const;
@@ -5401,6 +5475,104 @@
 };
 
 
+// TODO(regis): FunctionType is very similar to Type. Instead of a separate
+// class FunctionType, we could consider an object of class Type as representing
+// a function type if it has a non-null function (signature) field.
+// In order to save space, we could reuse the error_ field? A malformed or
+// malbounded function type would lose its function reference, but the error
+// string would contain relevant info.
+
+// A FunctionType describes the signature of a function, i.e. the result type
+// and formal parameter types of the function, as well as the names of optional
+// named formal parameters.
+// If these types refer to type parameters of a class in scope, the function
+// type is generic. A generic function type may be instantiated by a type
+// argument vector.
+// Therefore, a FunctionType consists of a scope class, a type argument vector,
+// and a signature.
+// The scope class is either a generic class (or generic typedef) declaring the
+// type parameters referred to by the signature, or class _Closure in the
+// non-generic case (including the non-generic typedef case).
+// The type arguments specify an instantiation of the generic signature (null in
+// the non-generic case).
+// The signature is a reference to an actual closure function (kClosureFunction)
+// or to a signature function (kSignatureFunction).
+// Since typedefs cannot refer to themselves, directly or indirectly, a
+// FunctionType cannot be recursive. Only individual formal parameter types can.
+class FunctionType : public AbstractType {
+ public:
+  virtual bool IsFinalized() const {
+    return
+        (raw_ptr()->type_state_ == RawFunctionType::kFinalizedInstantiated) ||
+        (raw_ptr()->type_state_ == RawFunctionType::kFinalizedUninstantiated);
+  }
+  virtual void SetIsFinalized() const;
+  void ResetIsFinalized() const;  // Ignore current state and set again.
+  virtual bool IsBeingFinalized() const {
+    return raw_ptr()->type_state_ == RawFunctionType::kBeingFinalized;
+  }
+  virtual void SetIsBeingFinalized() const;
+  virtual bool IsMalformed() const;
+  virtual bool IsMalbounded() const;
+  virtual bool IsMalformedOrMalbounded() const;
+  virtual RawLanguageError* error() const { return raw_ptr()->error_; }
+  virtual void set_error(const LanguageError& value) const;
+  virtual bool IsResolved() const {
+    return raw_ptr()->type_state_ >= RawFunctionType::kResolved;
+  }
+  virtual void SetIsResolved() const;
+  // The scope class of a FunctionType is always resolved. It has no actual
+  // type class. Returning false is important for the type testers to work, e.g.
+  // IsDynamicType(), IsBoolType(), etc...
+  virtual bool HasResolvedTypeClass() const { return false; }
+  // Return scope_class from virtual type_class() to factorize finalization
+  // with Type, also a parameterized type.
+  virtual RawClass* type_class() const { return scope_class(); }
+  RawClass* scope_class() const { return raw_ptr()->scope_class_; }
+  void set_scope_class(const Class& value) const;
+  virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
+  virtual void set_arguments(const TypeArguments& value) const;
+  RawFunction* signature() const { return raw_ptr()->signature_; }
+  virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  virtual bool IsInstantiated(TrailPtr trail = NULL) const;
+  virtual bool IsEquivalent(const Instance& other, TrailPtr trail = NULL) const;
+  virtual bool IsRecursive() const;
+  virtual RawAbstractType* InstantiateFrom(
+      const TypeArguments& instantiator_type_arguments,
+      Error* malformed_error,
+      TrailPtr trail = NULL,
+      Heap::Space space = Heap::kNew) const;
+  virtual RawAbstractType* CloneUnfinalized() const;
+  virtual RawAbstractType* CloneUninstantiated(
+      const Class& new_owner,
+      TrailPtr trail = NULL) const;
+  virtual RawAbstractType* Canonicalize(TrailPtr trail = NULL) const;
+
+  virtual intptr_t Hash() const;
+
+  static intptr_t InstanceSize() {
+    return RoundedAllocationSize(sizeof(RawFunctionType));
+  }
+
+  static RawFunctionType* New(const Class& scope_class,
+                              const TypeArguments& arguments,
+                              const Function& signature,
+                              intptr_t token_pos,
+                              Heap::Space space = Heap::kOld);
+
+ private:
+  void set_signature(const Function& value) const;
+  void set_token_pos(intptr_t token_pos) const;
+  void set_type_state(int8_t state) const;
+
+  static RawFunctionType* New(Heap::Space space = Heap::kOld);
+
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(FunctionType, AbstractType);
+  friend class Class;
+  friend class TypeArguments;
+};
+
+
 // A TypeRef is used to break cycles in the representation of recursive types.
 // Its only field is the recursive AbstractType it refers to.
 // Note that the cycle always involves type arguments.
@@ -5422,7 +5594,10 @@
     return AbstractType::Handle(type()).IsMalformedOrMalbounded();
   }
   virtual bool IsResolved() const { return true; }
-  virtual bool HasResolvedTypeClass() const { return true; }
+  virtual bool HasResolvedTypeClass() const {
+    // Returns false if the ref type is a function type.
+    return AbstractType::Handle(type()).HasResolvedTypeClass();
+  }
   RawAbstractType* type() const { return raw_ptr()->type_; }
   void set_type(const AbstractType& value) const;
   virtual RawClass* type_class() const {
@@ -5491,7 +5666,7 @@
     ASSERT(raw_ptr()->type_state_ != RawTypeParameter::kFinalizedInstantiated);
     return raw_ptr()->type_state_ == RawTypeParameter::kFinalizedUninstantiated;
   }
-  void set_is_finalized() const;
+  virtual void SetIsFinalized() const;
   virtual bool IsBeingFinalized() const { return false; }
   virtual bool IsMalformed() const { return false; }
   virtual bool IsMalbounded() const { return false; }
@@ -7667,86 +7842,45 @@
 };
 
 
-class Closure : public AllStatic {
+class Closure : public Instance {
  public:
-  static RawFunction* function(const Instance& closure) {
-    return *FunctionAddr(closure);
+  RawFunction* function() const { return raw_ptr()->function_; }
+  void set_function(const Function& function) const {
+    // TODO(regis): Only used from deferred_objects.cc. Remove once fixed.
+    StorePointer(&raw_ptr()->function_, function.raw());
   }
-  static intptr_t function_offset() {
-    return static_cast<intptr_t>(kFunctionOffset * kWordSize);
-  }
+  static intptr_t function_offset() { return OFFSET_OF(RawClosure, function_); }
 
-  static RawContext* context(const Instance& closure) {
-    return *ContextAddr(closure);
+  RawContext* context() const { return raw_ptr()->context_; }
+  void set_context(const Context& context) const {
+    // TODO(regis): Only used from deferred_objects.cc. Remove once fixed.
+    StorePointer(&raw_ptr()->context_, context.raw());
   }
-  static intptr_t context_offset() {
-    return static_cast<intptr_t>(kContextOffset * kWordSize);
-  }
+  static intptr_t context_offset() { return OFFSET_OF(RawClosure, context_); }
 
-  static RawTypeArguments* GetTypeArguments(const Instance& closure) {
-    return *TypeArgumentsAddr(closure);
-  }
-  static void SetTypeArguments(const Instance& closure,
-                               const TypeArguments& value) {
-    ASSERT(value.IsNull() || value.IsCanonical());
-    closure.StorePointer(TypeArgumentsAddr(closure), value.raw());
-  }
   static intptr_t type_arguments_offset() {
-    return static_cast<intptr_t>(kTypeArgumentsOffset * kWordSize);
+    return OFFSET_OF(RawClosure, type_arguments_);
   }
 
-  static const char* ToCString(const Instance& closure);
-
   static intptr_t InstanceSize() {
-    intptr_t size = sizeof(RawInstance) + (kNumFields * kWordSize);
-    ASSERT(size == Object::RoundedAllocationSize(size));
-    return size;
+    return RoundedAllocationSize(sizeof(RawClosure));
   }
 
-  static RawInstance* New(const Function& function,
-                          const Context& context,
-                          Heap::Space space = Heap::kNew);
+  // Returns true if all elements are OK for canonicalization.
+  virtual bool CheckAndCanonicalizeFields(const char** error_str) const {
+    // None of the fields of a closure are instances.
+    return true;
+  }
+
+  static RawClosure* New(const Function& function,
+                         const Context& context,
+                         Heap::Space space = Heap::kNew);
 
  private:
-  static const int kTypeArgumentsOffset = 1;
-  static const int kFunctionOffset = 2;
-  static const int kContextOffset = 3;
-  static const int kNumFields = 3;
+  static RawClosure* New();
 
-  static RawTypeArguments** TypeArgumentsAddr(const Instance& obj) {
-    ASSERT(obj.IsClosure());
-    return reinterpret_cast<RawTypeArguments**>(
-        reinterpret_cast<intptr_t>(obj.raw_ptr()) + type_arguments_offset());
-  }
-  static RawFunction** FunctionAddr(const Instance& obj) {
-    ASSERT(obj.IsClosure());
-    return reinterpret_cast<RawFunction**>(
-        reinterpret_cast<intptr_t>(obj.raw_ptr()) + function_offset());
-  }
-  static RawContext** ContextAddr(const Instance& obj) {
-    ASSERT(obj.IsClosure());
-    return reinterpret_cast<RawContext**>(
-        reinterpret_cast<intptr_t>(obj.raw_ptr()) + context_offset());
-  }
-  static void set_function(const Instance& closure,
-                           const Function& value) {
-    closure.StorePointer(FunctionAddr(closure), value.raw());
-  }
-  static void set_context(const Instance& closure,
-                          const Context& value) {
-    closure.StorePointer(ContextAddr(closure), value.raw());
-  }
-  static intptr_t NextFieldOffset() {
-    // Indicates this class cannot be extended by dart code.
-    return -kWordSize;
-  }
-  static RawFunction* GetFunction(RawObject* obj) {
-    return *(reinterpret_cast<RawFunction**>(
-        reinterpret_cast<intptr_t>(obj->ptr()) + function_offset()));
-  }
-
+  FINAL_HEAP_OBJECT_IMPLEMENTATION(Closure, Instance);
   friend class Class;
-  friend class SnapshotWriter;
 };
 
 
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index 624e1fe..c5a6be6 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -20,7 +20,7 @@
     null_class_(Class::null()),
     null_type_(Type::null()),
     function_type_(Type::null()),
-    function_impl_type_(Type::null()),
+    closure_class_(Class::null()),
     number_type_(Type::null()),
     int_type_(Type::null()),
     integer_implementation_class_(Class::null()),
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index db57663..2b68902 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -67,9 +67,9 @@
     function_type_ = value.raw();
   }
 
-  RawType* function_impl_type() const { return function_impl_type_; }
-  void set_function_impl_type(const Type& value) {
-    function_impl_type_ = value.raw();
+  RawClass* closure_class() const { return closure_class_; }
+  void set_closure_class(const Class& value) {
+    closure_class_ = value.raw();
   }
 
   RawType* number_type() const { return number_type_; }
@@ -504,7 +504,7 @@
   RawClass* null_class_;
   RawType* null_type_;
   RawType* function_type_;
-  RawType* function_impl_type_;
+  RawClass* closure_class_;
   RawType* number_type_;
   RawType* int_type_;
   RawClass* integer_implementation_class_;
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 422121e..9f31fee 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -29,7 +29,7 @@
 static RawClass* CreateDummyClass(const String& class_name,
                                   const Script& script) {
   const Class& cls = Class::Handle(
-      Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::New(class_name, script, Token::kNoSourcePos));
   cls.set_is_synthesized_class();  // Dummy class for testing.
   return cls.raw();
 }
@@ -2537,17 +2537,17 @@
   const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
   const String& a = String::ZoneHandle(Symbols::New("a"));
   LocalVariable* var_a =
-      new LocalVariable(Scanner::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
   parent_scope->AddVariable(var_a);
 
   const String& b = String::ZoneHandle(Symbols::New("b"));
   LocalVariable* var_b =
-      new LocalVariable(Scanner::kNoSourcePos, b, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, b, dynamic_type);
   local_scope->AddVariable(var_b);
 
   const String& c = String::ZoneHandle(Symbols::New("c"));
   LocalVariable* var_c =
-      new LocalVariable(Scanner::kNoSourcePos, c, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, c, dynamic_type);
   parent_scope->AddVariable(var_c);
 
   bool test_only = false;  // Please, insert alias.
@@ -2630,18 +2630,13 @@
   Function& function = Function::Handle();
   const String& function_name = String::Handle(Symbols::New("foo"));
   function = Function::NewClosureFunction(function_name, parent, 0);
-  const Class& signature_class = Class::Handle(
-      Class::NewSignatureClass(function_name, function, script, 0));
-  const Instance& closure = Instance::Handle(Closure::New(function, context));
+  const Closure& closure = Closure::Handle(Closure::New(function, context));
   const Class& closure_class = Class::Handle(closure.clazz());
-  EXPECT(closure_class.IsSignatureClass());
-  EXPECT(closure_class.IsCanonicalSignatureClass());
-  EXPECT_EQ(closure_class.raw(), signature_class.raw());
-  const Function& signature_function =
-    Function::Handle(signature_class.signature_function());
-  EXPECT_EQ(signature_function.raw(), function.raw());
-  const Context& closure_context = Context::Handle(Closure::context(closure));
-  EXPECT_EQ(closure_context.raw(), closure_context.raw());
+  EXPECT_EQ(closure_class.id(), kClosureCid);
+  const Function& closure_function = Function::Handle(closure.function());
+  EXPECT_EQ(closure_function.raw(), function.raw());
+  const Context& closure_context = Context::Handle(closure.context());
+  EXPECT_EQ(closure_context.raw(), context.raw());
 }
 
 
@@ -3092,16 +3087,18 @@
   SubtypeTestCache& cache = SubtypeTestCache::Handle(SubtypeTestCache::New());
   EXPECT(!cache.IsNull());
   EXPECT_EQ(0, cache.NumberOfChecks());
+  const Object& class_id_or_fun = Object::Handle(Smi::New(empty_class.id()));
   const TypeArguments& targ_0 = TypeArguments::Handle(TypeArguments::New(2));
   const TypeArguments& targ_1 = TypeArguments::Handle(TypeArguments::New(3));
-  cache.AddCheck(empty_class.id(), targ_0, targ_1, Bool::True());
+  cache.AddCheck(class_id_or_fun, targ_0, targ_1, Bool::True());
   EXPECT_EQ(1, cache.NumberOfChecks());
-  intptr_t test_class_id = -1;
+  Object& test_class_id_or_fun = Object::Handle();
   TypeArguments& test_targ_0 = TypeArguments::Handle();
   TypeArguments& test_targ_1 = TypeArguments::Handle();
   Bool& test_result = Bool::Handle();
-  cache.GetCheck(0, &test_class_id, &test_targ_0, &test_targ_1, &test_result);
-  EXPECT_EQ(empty_class.id(), test_class_id);
+  cache.GetCheck(
+      0, &test_class_id_or_fun, &test_targ_0, &test_targ_1, &test_result);
+  EXPECT_EQ(class_id_or_fun.raw(), test_class_id_or_fun.raw());
   EXPECT_EQ(targ_0.raw(), test_targ_0.raw());
   EXPECT_EQ(targ_1.raw(), test_targ_1.raw());
   EXPECT_EQ(Bool::True().raw(), test_result.raw());
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 47cb001..5440dfb 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -5,7 +5,7 @@
 #include "vm/parser.h"
 #include "vm/flags.h"
 
-#ifndef DART_PRECOMPILED
+#ifndef DART_PRECOMPILED_RUNTIME
 
 #include "lib/invocation_mirror.h"
 #include "platform/utils.h"
@@ -66,6 +66,8 @@
 #define I (isolate())
 #define Z (zone())
 
+// Quick synthetic token position.
+#define ST(token_pos) Token::ToSynthetic(token_pos)
 
 #if defined(DEBUG)
 class TraceParser : public ValueObject {
@@ -125,6 +127,27 @@
 };
 
 
+class RecursionChecker : public ValueObject {
+ public:
+  explicit RecursionChecker(Parser* p) : parser_(p) {
+    parser_->recursion_counter_++;
+    // No need to check the stack unless the parser is in an unusually deep
+    // recurive state. Thus, we omit the more expensive stack checks in
+    // the common case.
+    const int kMaxUncheckedDepth = 100;  // Somewhat arbitrary.
+    if (parser_->recursion_counter_ > kMaxUncheckedDepth) {
+      parser_->CheckStack();
+    }
+  }
+  ~RecursionChecker() {
+    parser_->recursion_counter_--;
+  }
+
+ private:
+  Parser* parser_;
+};
+
+
 static RawTypeArguments* NewTypeArguments(
     const GrowableArray<AbstractType*>& objs) {
   const TypeArguments& a =
@@ -239,7 +262,7 @@
 
 struct CatchParamDesc {
   CatchParamDesc()
-      : token_pos(Scanner::kNoSourcePos), type(NULL), name(NULL), var(NULL) { }
+      : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { }
   intptr_t token_pos;
   const AbstractType* type;
   const String* name;
@@ -347,7 +370,8 @@
       last_used_try_index_(0),
       unregister_pending_function_(false),
       async_temp_scope_(NULL),
-      trace_indent_(0) {
+      trace_indent_(0),
+      recursion_counter_(0) {
   ASSERT(tokens_iterator_.IsValid());
   ASSERT(!library.IsNull());
 }
@@ -381,7 +405,8 @@
       last_used_try_index_(0),
       unregister_pending_function_(false),
       async_temp_scope_(NULL),
-      trace_indent_(0) {
+      trace_indent_(0),
+      recursion_counter_(0) {
   ASSERT(tokens_iterator_.IsValid());
   ASSERT(!current_function().IsNull());
   EnsureExpressionTemp();
@@ -449,6 +474,7 @@
 void Parser::SetPosition(intptr_t position) {
   tokens_iterator_.SetCurrentPosition(position);
   token_kind_ = Token::kILLEGAL;
+  prev_token_pos_ = position;
 }
 
 
@@ -518,7 +544,7 @@
 struct ParamDesc {
   ParamDesc()
       : type(NULL),
-        name_pos(Scanner::kNoSourcePos),
+        name_pos(Token::kNoSourcePos),
         name(NULL),
         default_value(NULL),
         metadata(NULL),
@@ -623,10 +649,10 @@
     has_factory = false;
     has_operator = false;
     has_native = false;
-    metadata_pos = Scanner::kNoSourcePos;
+    metadata_pos = Token::kNoSourcePos;
     operator_token = Token::kILLEGAL;
     type = NULL;
-    name_pos = Scanner::kNoSourcePos;
+    name_pos = Token::kNoSourcePos;
     name = NULL;
     redirect_name = NULL;
     dict_name = NULL;
@@ -970,7 +996,7 @@
       if (!func.IsImplicitConstructor()) {
         parser.SkipFunctionPreamble();
       }
-      node_sequence = parser.ParseFunc(func);
+      node_sequence = parser.ParseFunc(func, false);
       break;
     case RawFunction::kImplicitGetter:
       ASSERT(!func.is_static());
@@ -1311,7 +1337,7 @@
   LoadInstanceFieldNode* load_field =
       new LoadInstanceFieldNode(ident_pos, load_receiver, field);
 
-  ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field);
+  ReturnNode* return_node = new ReturnNode(ST(ident_pos), load_field);
   current_block_->statements->Add(return_node);
   return CloseBlock();
 }
@@ -1355,7 +1381,7 @@
   StoreInstanceFieldNode* store_field =
       new StoreInstanceFieldNode(ident_pos, receiver, field, value);
   current_block_->statements->Add(store_field);
-  current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
+  current_block_->statements->Add(new ReturnNode(ST(ident_pos)));
   return CloseBlock();
 }
 
@@ -1483,7 +1509,7 @@
   ParamList params;
 
   const intptr_t ident_pos = func.token_pos();
-  ASSERT(func.token_pos() == 0);
+  ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor);
   ASSERT(current_class().raw() == func.Owner());
   params.AddReceiver(ReceiverType(current_class()), ident_pos);
   ASSERT(func.num_fixed_parameters() == 1);  // Receiver.
@@ -1503,7 +1529,7 @@
       load_receiver,
       NULL);
 
-  ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure);
+  ReturnNode* return_node = new ReturnNode(ident_pos, closure);
   current_block_->statements->Add(return_node);
   return CloseBlock();
 }
@@ -1624,14 +1650,14 @@
   ArgumentListNode* no_args = new ArgumentListNode(token_pos);
   LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0));
 
-  const Class& function_impl = Class::Handle(Type::Handle(
-      Isolate::Current()->object_store()->function_impl_type()).type_class());
+  const Class& closure_cls = Class::Handle(
+      Isolate::Current()->object_store()->closure_class());
 
   const Class& owner = Class::Handle(Z, func.Owner());
   ASSERT(!owner.IsNull());
   const String& name = String::Handle(Z, func.name());
   AstNode* function_object = NULL;
-  if (owner.raw() == function_impl.raw() && name.Equals(Symbols::Call())) {
+  if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) {
     function_object = receiver;
   } else {
     const String& getter_name = String::ZoneHandle(Z,
@@ -1658,7 +1684,7 @@
   args->set_names(names);
 
   AstNode* result = NULL;
-  if (owner.raw() == function_impl.raw() && name.Equals(Symbols::Call())) {
+  if (owner.raw() == closure_cls.raw() && name.Equals(Symbols::Call())) {
     result = new ClosureCallNode(token_pos, function_object, args);
   } else {
     result = BuildClosureCall(token_pos, function_object, args);
@@ -1735,7 +1761,8 @@
   if (!is_match) {
     const Error& error = Error::Handle(
         LanguageError::NewFormatted(Error::Handle(),
-            script_, opening_pos, Report::kWarning, Heap::kNew,
+            script_, opening_pos, Report::AtLocation,
+            Report::kWarning, Heap::kNew,
             "unbalanced '%s' opens here", Token::Str(opening_token)));
     ReportErrors(error, script_, token_pos,
                  "unbalanced '%s'", Token::Str(token));
@@ -1879,55 +1906,22 @@
       ParseFormalParameterList(no_explicit_default_values, false, &func_params);
 
       // In top-level and mixin functions, the source may be in a different
-      // script than the script of the current class.
-      Object& sig_func_owner = Object::Handle(Z, current_class().raw());
-      if (current_class().script() != script_.raw()) {
-        sig_func_owner = PatchClass::New(current_class(), script_);
-      }
-
-      // The field 'is_static' has no meaning for signature functions.
+      // script than the script of the current class. However, we never reparse
+      // signature functions (except typedef signature functions), therefore
+      // we do not need to keep the correct script via a patch class. Use the
+      // actual current class as owner of the signature function.
       const Function& signature_function = Function::Handle(Z,
-          Function::New(*parameter.name,
-                        RawFunction::kSignatureFunction,
-                        /* is_static = */ false,
-                        /* is_const = */ false,
-                        /* is_abstract = */ false,
-                        /* is_external = */ false,
-                        /* is_native = */ false,
-                        sig_func_owner,
-                        parameter.name_pos));
+          Function::NewSignatureFunction(current_class(),
+                                         Token::kNoSourcePos));
       signature_function.set_result_type(result_type);
-      signature_function.set_is_debuggable(false);
       AddFormalParamsToFunction(&func_params, signature_function);
-      const String& signature =
-          String::Handle(Z, signature_function.Signature());
-      // Lookup the signature class, i.e. the class whose name is the signature.
-      // We only lookup in the current library, but not in its imports, and only
-      // create a new canonical signature class if it does not exist yet.
-      Class& signature_class =
-          Class::ZoneHandle(Z, library_.LookupLocalClass(signature));
-      if (signature_class.IsNull()) {
-        signature_class = Class::NewSignatureClass(signature,
-                                                   signature_function,
-                                                   script_,
-                                                   parameter.name_pos);
-        // Record the function signature class in the current library, unless
-        // we are currently skipping a formal parameter list, in which case
-        // the signature class could remain unfinalized.
-        if (!params->skipped) {
-          library_.AddClass(signature_class);
-        }
-      } else {
-        signature_function.set_signature_class(signature_class);
-      }
-      ASSERT(signature_function.signature_class() == signature_class.raw());
+      FunctionType& signature_type =
+          FunctionType::ZoneHandle(Z, signature_function.SignatureType());
       if (!is_top_level_) {
-        // Finalize types in signature class here, so that the
-        // signature type is not computed twice.
-        ClassFinalizer::FinalizeTypesInClass(signature_class);
+        signature_type ^= ClassFinalizer::FinalizeType(
+            current_class(), signature_type, ClassFinalizer::kCanonicalize);
+        signature_function.SetSignatureType(signature_type);
       }
-      const Type& signature_type =
-          Type::ZoneHandle(Z, signature_class.SignatureType());
       ASSERT(is_top_level_ || signature_type.IsFinalized());
       // A signature type itself cannot be malformed or malbounded, only its
       // signature function's result type or parameter types may be.
@@ -2312,9 +2306,10 @@
     // parameterized class, make sure that the receiver is captured as
     // instantiator.
     if (current_block_->scope->function_level() > 0) {
-      const Class& signature_class = Class::Handle(Z,
-          implicit_closure_function.signature_class());
-      if (signature_class.NumTypeParameters() > 0) {
+      const FunctionType& signature_type = FunctionType::Handle(Z,
+          implicit_closure_function.SignatureType());
+      const Class& scope_class = Class::Handle(Z, signature_type.type_class());
+      if (scope_class.IsGeneric()) {
         CaptureInstantiator();
       }
     }
@@ -2877,7 +2872,7 @@
   OpenFunctionBlock(func);
 
   LocalVariable* receiver = new LocalVariable(
-      Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class()));
+      Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class()));
   current_block_->scope->InsertParameterAt(0, receiver);
 
   // Parse expressions of instance fields that have an explicit
@@ -2920,20 +2915,20 @@
 
     // Prepare user-defined arguments to be forwarded to super call.
     // The first user-defined argument is at position 1.
-    forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos);
+    forwarding_args = new ArgumentListNode(ST(ctor_pos));
     for (int i = 1; i < func.NumParameters(); i++) {
       LocalVariable* param = new LocalVariable(
-          Scanner::kNoSourcePos,
+          Token::kNoSourcePos,
           String::ZoneHandle(Z, func.ParameterNameAt(i)),
           Object::dynamic_type());
       current_block_->scope->InsertParameterAt(i, param);
-      forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param));
+      forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param));
     }
   }
 
   AstNode* super_call = GenerateSuperConstructorCall(
       current_class(),
-      Scanner::kNoSourcePos,
+      ctor_pos,
       receiver,
       forwarding_args);
   if (super_call != NULL) {
@@ -2942,7 +2937,7 @@
   CheckFieldsInitialized(current_class());
 
   // Empty constructor body.
-  current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos));
+  current_block_->statements->Add(new ReturnNode(ST(ctor_pos)));
   SequenceNode* statements = CloseBlock();
   return statements;
 }
@@ -3142,7 +3137,7 @@
 // Parser is at the opening parenthesis of the formal parameter
 // declaration of the function or constructor.
 // Parse the formal parameters and code.
-SequenceNode* Parser::ParseFunc(const Function& func) {
+SequenceNode* Parser::ParseFunc(const Function& func, bool check_semicolon) {
   TRACE_PARSER("ParseFunc");
   Function& saved_innermost_function =
       Function::Handle(Z, innermost_function().raw());
@@ -3319,7 +3314,7 @@
 
   BoolScope allow_await(&this->await_is_keyword_,
                         func.IsAsyncOrGenerator() || func.is_generated_body());
-  intptr_t end_token_pos = Scanner::kNoSourcePos;
+  intptr_t end_token_pos = Token::kNoSourcePos;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
     if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
@@ -3349,6 +3344,9 @@
     ASSERT(expr != NULL);
     current_block_->statements->Add(new ReturnNode(expr_pos, expr));
     end_token_pos = TokenPos();
+    if (check_semicolon) {
+      ExpectSemicolon();
+    }
   } else if (IsSymbol(Symbols::Native())) {
     if (String::Handle(Z, func.name()).Equals(
         Symbols::EqualOperator())) {
@@ -3409,24 +3407,24 @@
 
 void Parser::AddEqualityNullCheck() {
   AstNode* argument =
-      new LoadLocalNode(Scanner::kNoSourcePos,
+      new LoadLocalNode(Token::kNoSourcePos,
                         current_block_->scope->parent()->VariableAt(1));
   LiteralNode* null_operand =
-      new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(Z));
+      new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z));
   ComparisonNode* check_arg =
-      new ComparisonNode(Scanner::kNoSourcePos,
+      new ComparisonNode(Token::kNoSourcePos,
                          Token::kEQ_STRICT,
                          argument,
                          null_operand);
   ComparisonNode* result =
-      new ComparisonNode(Scanner::kNoSourcePos,
+      new ComparisonNode(Token::kNoSourcePos,
                          Token::kEQ_STRICT,
-                         LoadReceiver(Scanner::kNoSourcePos),
+                         LoadReceiver(Token::kNoSourcePos),
                          null_operand);
-  SequenceNode* arg_is_null = new SequenceNode(Scanner::kNoSourcePos,
+  SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos,
                                                current_block_->scope);
-  arg_is_null->Add(new ReturnNode(Scanner::kNoSourcePos, result));
-  IfNode* if_arg_null = new IfNode(Scanner::kNoSourcePos,
+  arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result));
+  IfNode* if_arg_null = new IfNode(Token::kNoSourcePos,
                                    check_arg,
                                    arg_is_null,
                                    NULL);
@@ -4114,7 +4112,8 @@
     member.has_var = true;
     // The member type is the 'dynamic' type.
     member.type = &Object::dynamic_type();
-  } else if (CurrentToken() == Token::kFACTORY) {
+  } else if ((CurrentToken() == Token::kFACTORY) &&
+      (LookaheadToken(1) != Token::kLPAREN)) {
     ConsumeToken();
     if (member.has_static) {
       ReportError("factory method cannot be explicitly marked static");
@@ -4380,10 +4379,6 @@
       // Preserve and reuse the original type parameters and bounds since the
       // ones defined in the patch class will not be finalized.
       orig_type_parameters = cls.type_parameters();
-      // A patch class must be given the same name as the class it is patching,
-      // otherwise the generic signature classes it defines will not match the
-      // patched generic signature classes. Therefore, new signature classes
-      // will be introduced and the original ones will not get finalized.
       cls = Class::New(class_name, script_, declaration_pos);
       cls.set_library(library_);
     } else {
@@ -4967,15 +4962,15 @@
                 "'%s' is already defined", alias_name->ToCString());
   }
 
-  // Create the function type alias signature class. It will be linked to its
+  // Create the function type alias scope class. It will be linked to its
   // signature function after it has been parsed. The type parameters, in order
-  // to be properly finalized, need to be associated to this signature class as
+  // to be properly finalized, need to be associated to this scope class as
   // they are parsed.
   const Class& function_type_alias = Class::Handle(Z,
-      Class::NewSignatureClass(*alias_name,
-                               Function::Handle(Z),
-                               script_,
-                               declaration_pos));
+      Class::New(*alias_name, script_, declaration_pos));
+  function_type_alias.set_is_synthesized_class();
+  function_type_alias.set_is_abstract();
+  function_type_alias.set_is_prefinalized();
   library_.AddClass(function_type_alias);
   set_current_class(function_type_alias);
   // Parse the type parameters of the function type.
@@ -5000,52 +4995,21 @@
   const bool no_explicit_default_values = false;
   ParseFormalParameterList(no_explicit_default_values, false, &func_params);
   ExpectSemicolon();
-  // The field 'is_static' has no meaning for signature functions.
-  Function& signature_function = Function::Handle(Z,
-      Function::New(*alias_name,
-                    RawFunction::kSignatureFunction,
-                    /* is_static = */ false,
-                    /* is_const = */ false,
-                    /* is_abstract = */ false,
-                    /* is_external = */ false,
-                    /* is_native = */ false,
-                    function_type_alias,
-                    alias_name_pos));
+  Function& signature_function =
+      Function::Handle(Z, Function::NewSignatureFunction(function_type_alias,
+                                                         alias_name_pos));
   signature_function.set_result_type(result_type);
-  signature_function.set_is_debuggable(false);
   AddFormalParamsToFunction(&func_params, signature_function);
 
-  // Patch the signature function in the signature class.
-  function_type_alias.PatchSignatureFunction(signature_function);
+  // Set the signature function in the function type alias class.
+  function_type_alias.set_signature_function(signature_function);
 
-  const String& signature = String::Handle(Z,
-                                           signature_function.Signature());
   if (FLAG_trace_parser) {
     OS::Print("TopLevel parsing function type alias '%s'\n",
-              signature.ToCString());
+              String::Handle(Z, signature_function.Signature()).ToCString());
   }
-  // Lookup the signature class, i.e. the class whose name is the signature.
-  // We only lookup in the current library, but not in its imports, and only
-  // create a new canonical signature class if it does not exist yet.
-  Class& signature_class =
-      Class::ZoneHandle(Z, library_.LookupLocalClass(signature));
-  if (signature_class.IsNull()) {
-    signature_class = Class::NewSignatureClass(signature,
-                                               signature_function,
-                                               script_,
-                                               alias_name_pos);
-    // Record the function signature class in the current library.
-    library_.AddClass(signature_class);
-  } else {
-    // Forget the just created signature function and use the existing one.
-    signature_function = signature_class.signature_function();
-    function_type_alias.PatchSignatureFunction(signature_function);
-  }
-  ASSERT(signature_function.signature_class() == signature_class.raw());
-
   // The alias should not be marked as finalized yet, since it needs to be
   // checked in the class finalizer for illegal self references.
-  ASSERT(!function_type_alias.IsCanonicalSignatureClass());
   ASSERT(!function_type_alias.is_finalized());
   pending_classes.Add(function_type_alias, Heap::kOld);
   if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
@@ -5073,7 +5037,7 @@
 
 intptr_t Parser::SkipMetadata() {
   if (CurrentToken() != Token::kAT) {
-    return Scanner::kNoSourcePos;
+    return Token::kNoSourcePos;
   }
   intptr_t metadata_pos = TokenPos();
   while (CurrentToken() == Token::kAT) {
@@ -5832,7 +5796,7 @@
     CheckToken(Token::kAS, "'as' expected");
   }
   String& prefix = String::Handle(Z);
-  intptr_t prefix_pos = Scanner::kNoSourcePos;
+  intptr_t prefix_pos = Token::kNoSourcePos;
   if (is_import && (CurrentToken() == Token::kAS)) {
     ConsumeToken();
     prefix_pos = TokenPos();
@@ -6107,6 +6071,18 @@
 }
 
 
+void Parser::CheckStack() {
+  volatile uword c_stack_pos = Isolate::GetCurrentStackPointer();
+  volatile uword c_stack_base = OSThread::Current()->stack_base();
+  volatile uword c_stack_limit =
+      c_stack_base - OSThread::GetSpecifiedStackSize();
+  // Note: during early initialization the stack_base() can return 0.
+  if ((c_stack_base > 0) && (c_stack_pos < c_stack_limit)) {
+    ReportError("stack overflow while parsing");
+  }
+}
+
+
 void Parser::ChainNewBlock(LocalScope* outer_scope) {
   Block* block = new(Z) Block(
       current_block_,
@@ -6188,10 +6164,10 @@
   // Add the exception and stack trace parameters to the scope.
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
-  exception_param.token_pos = Scanner::kNoSourcePos;
+  exception_param.token_pos = Token::kNoSourcePos;
   exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
-  stack_trace_param.token_pos = Scanner::kNoSourcePos;
+  stack_trace_param.token_pos = Token::kNoSourcePos;
   stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
@@ -6211,9 +6187,9 @@
     // Generate code to load the exception object (:exception_var) into
     // the exception variable specified in this block.
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        Token::kNoSourcePos,
         exception_param.var,
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
+        new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
   }
 
   LocalVariable* stack_trace_var =
@@ -6224,9 +6200,9 @@
     // to load the stack trace object (:stack_trace_var) into the stack
     // trace variable specified in this block.
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        Token::kNoSourcePos,
         stack_trace_param.var,
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
+        new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
   }
   LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
       Symbols::SavedExceptionVar());
@@ -6245,15 +6221,15 @@
       current_block_->scope->LookupVariable(Symbols::Controller(), false);
   ASSERT(controller != NULL);
   ArgumentListNode* args =
-      new(Z) ArgumentListNode(Scanner::kNoSourcePos);
-  args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
-  args->Add(new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
+      new(Z) ArgumentListNode(Token::kNoSourcePos);
+  args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var));
+  args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var));
   current_block_->statements->Add(
       new(Z) InstanceCallNode(try_end_pos,
-          new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
+          new(Z) LoadLocalNode(Token::kNoSourcePos, controller),
           Symbols::AddError(),
           args));
-  ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos);
+  ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos);
   AddNodeForFinallyInlining(return_node);
   current_block_->statements->Add(return_node);
   AstNode* catch_block = CloseBlock();
@@ -6278,10 +6254,10 @@
   do {
     OpenBlock();
     ArgumentListNode* no_args =
-        new(Z) ArgumentListNode(Scanner::kNoSourcePos);
+        new(Z) ArgumentListNode(Token::kNoSourcePos);
     current_block_->statements->Add(
         new(Z) InstanceCallNode(try_end_pos,
-            new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller),
+            new(Z) LoadLocalNode(Token::kNoSourcePos, controller),
             Symbols::Close(),
             no_args));
 
@@ -6289,7 +6265,7 @@
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Scanner::kNoSourcePos);
+                               Token::kNoSourcePos);
     current_block_->statements->Add(await_marker);
     ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
     continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
@@ -6320,7 +6296,7 @@
   handler_types.Add(Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       catch_handler_list,
       Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
       context_var,
@@ -6334,7 +6310,7 @@
   const intptr_t try_index = try_statement->try_index();
 
   AstNode* try_catch_node =
-      new(Z) TryCatchNode(Scanner::kNoSourcePos,
+      new(Z) TryCatchNode(Token::kNoSourcePos,
                           body,
                           context_var,
                           catch_clause,
@@ -6359,10 +6335,10 @@
   OpenBlock();  // Catch block.
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
-  exception_param.token_pos = Scanner::kNoSourcePos;
+  exception_param.token_pos = Token::kNoSourcePos;
   exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
-  stack_trace_param.token_pos = Scanner::kNoSourcePos;
+  stack_trace_param.token_pos = Token::kNoSourcePos;
   stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
@@ -6380,9 +6356,9 @@
     // the exception variable specified in this block.
     ASSERT(exception_var != NULL);
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        Token::kNoSourcePos,
         exception_param.var,
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
+        new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
   }
 
   LocalVariable* stack_trace_var =
@@ -6393,9 +6369,9 @@
     // trace variable specified in this block.
     ASSERT(stack_trace_var != NULL);
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        Token::kNoSourcePos,
         stack_trace_param.var,
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
+        new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
   }
   LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
       Symbols::SavedExceptionVar());
@@ -6413,17 +6389,17 @@
       Symbols::AsyncCompleter(), false);
   ASSERT(async_completer != NULL);
   ArgumentListNode* completer_args =
-      new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+      new (Z) ArgumentListNode(Token::kNoSourcePos);
   completer_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var));
+      new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var));
   completer_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var));
+      new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var));
   current_block_->statements->Add(new (Z) InstanceCallNode(
       TokenPos(),
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_completer),
+      new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer),
       Symbols::CompleterCompleteError(),
       completer_args));
-  ReturnNode* return_node = new (Z) ReturnNode(Scanner::kNoSourcePos);
+  ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos);
   // Behavior like a continuation return, i.e,. don't call a completer.
   return_node->set_return_type(ReturnNode::kContinuation);
   current_block_->statements->Add(return_node);
@@ -6440,7 +6416,7 @@
   const intptr_t try_index = try_statement->try_index();
 
   CatchClauseNode* catch_clause = new (Z) CatchClauseNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       catch_handler_list,
       Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
       context_var,
@@ -6451,7 +6427,7 @@
       CatchClauseNode::kInvalidTryIndex,
       true);
   AstNode* try_catch_node = new (Z) TryCatchNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       try_block,
       context_var,
       catch_clause,
@@ -6551,19 +6527,12 @@
     // Add the parameters to the newly created closure.
     AddFormalParamsToFunction(&closure_params, body);
 
-    // Create and set the signature class of the closure.
-    const String& sig = String::Handle(Z, body.Signature());
-    Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
-    if (sig_cls.IsNull()) {
-      sig_cls = Class::NewSignatureClass(sig, body, script_, body.token_pos());
-      library_.AddClass(sig_cls);
-    }
-    body.set_signature_class(sig_cls);
-    // Finalize types in signature class here, so that the
-    // signature type is not computed twice.
-    ClassFinalizer::FinalizeTypesInClass(sig_cls);
-    const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
-    ASSERT(sig_type.IsFinalized());
+    // Finalize function type.
+    FunctionType& signature_type =
+        FunctionType::Handle(Z, body.SignatureType());
+    signature_type ^= ClassFinalizer::FinalizeType(
+        current_class(), signature_type, ClassFinalizer::kCanonicalize);
+    body.SetSignatureType(signature_type);
     ASSERT(AbstractType::Handle(Z, body.result_type()).IsResolved());
     ASSERT(body.NumParameters() == closure_params.parameters->length());
   }
@@ -6589,9 +6558,9 @@
   LocalVariable* jump_var =
       current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
   LiteralNode* init_value =
-      new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
+      new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
   current_block_->statements->Add(
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
+      new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value));
 
   // return new SyncIterable(body_closure);
   const Class& iterable_class =
@@ -6605,17 +6574,17 @@
   const String& closure_name = String::Handle(Z, closure.name());
   ASSERT(closure_name.IsSymbol());
 
-  ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
+  ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos);
   ClosureNode* closure_obj = new(Z) ClosureNode(
-      Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
+      Token::kNoSourcePos, closure, NULL, closure_body->scope());
   arguments->Add(closure_obj);
   ConstructorCallNode* new_iterable =
-      new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
+      new(Z) ConstructorCallNode(Token::kNoSourcePos,
           TypeArguments::ZoneHandle(Z),
           iterable_constructor,
           arguments);
   ReturnNode* return_node =
-      new (Z) ReturnNode(Scanner::kNoSourcePos, new_iterable);
+      new (Z) ReturnNode(Token::kNoSourcePos, new_iterable);
   current_block_->statements->Add(return_node);
   return CloseBlock();
 }
@@ -6688,20 +6657,12 @@
     // Add the parameters to the newly created closure.
     AddFormalParamsToFunction(&closure_params, closure);
 
-    // Create and set the signature class of the closure.
-    const String& sig = String::Handle(Z, closure.Signature());
-    Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
-    if (sig_cls.IsNull()) {
-      sig_cls =
-          Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
-      library_.AddClass(sig_cls);
-    }
-    closure.set_signature_class(sig_cls);
-    // Finalize types in signature class here, so that the
-    // signature type is not computed twice.
-    ClassFinalizer::FinalizeTypesInClass(sig_cls);
-    const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
-    ASSERT(sig_type.IsFinalized());
+    // Finalize function type.
+    FunctionType& signature_type =
+        FunctionType::Handle(Z, closure.SignatureType());
+    signature_type ^= ClassFinalizer::FinalizeType(
+        current_class(), signature_type, ClassFinalizer::kCanonicalize);
+    closure.SetSignatureType(signature_type);
     ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
     ASSERT(closure.NumParameters() == closure_params.parameters->length());
   }
@@ -6717,10 +6678,10 @@
   //   var :await_jump_var;
   //   var :await_ctx_var;
   LocalVariable* await_jump_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type());
+      Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type());
   current_block_->scope->AddVariable(await_jump_var);
   LocalVariable* await_ctx_var = new (Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AwaitContextVar(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(await_ctx_var);
@@ -6734,20 +6695,20 @@
   //   var :async_catch_error_callback;
   //   var :async_completer;
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
+      Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AsyncThenCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AsyncCatchErrorCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
   LocalVariable* async_completer = new(Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AsyncCompleter(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_completer);
@@ -6766,18 +6727,18 @@
   // These variables are used to store the async generator closure containing
   // the body of the async* function. They are used by the await operator.
   LocalVariable* controller_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::Controller(), Object::dynamic_type());
+      Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type());
   current_block_->scope->AddVariable(controller_var);
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
+      Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AsyncThenCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       Symbols::AsyncCatchErrorCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
@@ -6823,20 +6784,12 @@
     // Add the parameters to the newly created closure.
     AddFormalParamsToFunction(&closure_params, closure);
 
-    // Create and set the signature class of the closure.
-    const String& sig = String::Handle(Z, closure.Signature());
-    Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
-    if (sig_cls.IsNull()) {
-      sig_cls =
-          Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
-      library_.AddClass(sig_cls);
-    }
-    closure.set_signature_class(sig_cls);
-    // Finalize types in signature class here, so that the
-    // signature type is not computed twice.
-    ClassFinalizer::FinalizeTypesInClass(sig_cls);
-    const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
-    ASSERT(sig_type.IsFinalized());
+    // Finalize function type.
+    FunctionType& signature_type =
+        FunctionType::Handle(Z, closure.SignatureType());
+    signature_type ^= ClassFinalizer::FinalizeType(
+        current_class(), signature_type, ClassFinalizer::kCanonicalize);
+    closure.SetSignatureType(signature_type);
     ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved());
     ASSERT(closure.NumParameters() == closure_params.parameters->length());
   }
@@ -6904,18 +6857,18 @@
   LocalVariable* jump_var =
       current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
   LiteralNode* init_value =
-      new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
+      new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
   current_block_->statements->Add(
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
+      new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value));
 
   // Add to AST:
   //   :async_op = <closure>;  (containing the original body)
   LocalVariable* async_op_var =
       current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
   ClosureNode* closure_obj = new(Z) ClosureNode(
-      Scanner::kNoSourcePos, closure_func, NULL, closure_body->scope());
+      Token::kNoSourcePos, closure_func, NULL, closure_body->scope());
   StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_op_var,
       closure_obj);
 
@@ -6927,18 +6880,18 @@
           Symbols::AsyncThenWrapperHelper()));
   ASSERT(!async_then_wrapper_helper.IsNull());
   ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode(
-      Scanner::kNoSourcePos);
+      Token::kNoSourcePos);
   async_then_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
   StaticCallNode* then_wrapper_call = new (Z) StaticCallNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_then_wrapper_helper,
       async_then_wrapper_helper_args);
   LocalVariable* async_then_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncThenCallback(), false);
   StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_then_callback_var,
       then_wrapper_call);
 
@@ -6951,43 +6904,43 @@
           Symbols::AsyncErrorWrapperHelper()));
   ASSERT(!async_error_wrapper_helper.IsNull());
   ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode(
-      Scanner::kNoSourcePos);
+      Token::kNoSourcePos);
   async_error_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
   StaticCallNode* error_wrapper_call = new (Z) StaticCallNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_error_wrapper_helper,
       async_error_wrapper_helper_args);
   LocalVariable* async_catch_error_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncCatchErrorCallback(), false);
   StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_catch_error_callback_var,
       error_wrapper_call);
 
   current_block_->statements->Add(store_async_catch_error_callback);
 
   // :controller = new _AsyncStarStreamController(body_closure);
-  ArgumentListNode* arguments = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
-  arguments->Add(new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var));
+  ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos);
+  arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
   ConstructorCallNode* controller_constructor_call =
-      new(Z) ConstructorCallNode(Scanner::kNoSourcePos,
+      new(Z) ConstructorCallNode(Token::kNoSourcePos,
                                  TypeArguments::ZoneHandle(Z),
                                  controller_constructor,
                                  arguments);
   LocalVariable* controller_var =
      current_block_->scope->LookupVariable(Symbols::Controller(), false);
   StoreLocalNode* store_controller =
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos,
+      new(Z) StoreLocalNode(Token::kNoSourcePos,
                             controller_var,
                             controller_constructor_call);
   current_block_->statements->Add(store_controller);
 
   // return :controller.stream;
-  ReturnNode* return_node = new(Z) ReturnNode(Scanner::kNoSourcePos,
-      new(Z) InstanceGetterNode(Scanner::kNoSourcePos,
-          new(Z) LoadLocalNode(Scanner::kNoSourcePos,
+  ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos,
+      new(Z) InstanceGetterNode(Token::kNoSourcePos,
+          new(Z) LoadLocalNode(Token::kNoSourcePos,
               controller_var),
               Symbols::Stream()));
   current_block_->statements->Add(return_node);
@@ -7081,17 +7034,18 @@
   LocalVariable* async_completer = current_block_->scope->LookupVariable(
       Symbols::AsyncCompleter(), false);
 
+  const intptr_t token_pos = ST(closure_body->token_pos());
   // Add to AST:
   //   :async_completer = new Completer.sync();
   ArgumentListNode* empty_args =
-      new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+      new (Z) ArgumentListNode(token_pos);
   ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       TypeArguments::ZoneHandle(Z),
       completer_constructor,
       empty_args);
   StoreLocalNode* store_completer = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_completer,
       completer_constructor_node);
   current_block_->statements->Add(store_completer);
@@ -7100,18 +7054,19 @@
   LocalVariable* jump_var =
       current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
   LiteralNode* init_value =
-      new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
+      new(Z) LiteralNode(token_pos,
+                         Smi::ZoneHandle(Smi::New(-1)));
   current_block_->statements->Add(
-      new(Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value));
+      new(Z) StoreLocalNode(token_pos, jump_var, init_value));
 
   // Add to AST:
   //   :async_op = <closure>;  (containing the original body)
   LocalVariable* async_op_var = current_block_->scope->LookupVariable(
       Symbols::AsyncOperation(), false);
   ClosureNode* cn = new(Z) ClosureNode(
-      Scanner::kNoSourcePos, closure, NULL, closure_body->scope());
+      token_pos, closure, NULL, closure_body->scope());
   StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_op_var,
       cn);
   current_block_->statements->Add(store_async_op);
@@ -7123,18 +7078,18 @@
           Symbols::AsyncThenWrapperHelper()));
   ASSERT(!async_then_wrapper_helper.IsNull());
   ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode(
-      Scanner::kNoSourcePos);
+      token_pos);
   async_then_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(token_pos, async_op_var));
   StaticCallNode* then_wrapper_call = new (Z) StaticCallNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_then_wrapper_helper,
       async_then_wrapper_helper_args);
   LocalVariable* async_then_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncThenCallback(), false);
   StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_then_callback_var,
       then_wrapper_call);
 
@@ -7147,18 +7102,18 @@
           Symbols::AsyncErrorWrapperHelper()));
   ASSERT(!async_error_wrapper_helper.IsNull());
   ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode(
-      Scanner::kNoSourcePos);
+      token_pos);
   async_error_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(token_pos, async_op_var));
   StaticCallNode* error_wrapper_call = new (Z) StaticCallNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_error_wrapper_helper,
       async_error_wrapper_helper_args);
   LocalVariable* async_catch_error_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncCatchErrorCallback(), false);
   StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       async_catch_error_callback_var,
       error_wrapper_call);
 
@@ -7166,22 +7121,22 @@
 
   // Add to AST:
   //   new Future.microtask(:async_op);
-  ArgumentListNode* arguments = new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+  ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
   arguments->Add(new (Z) LoadLocalNode(
-      Scanner::kNoSourcePos, async_op_var));
+      token_pos, async_op_var));
   ConstructorCallNode* future_node = new (Z) ConstructorCallNode(
-      Scanner::kNoSourcePos, TypeArguments::ZoneHandle(Z), constructor,
+      token_pos, TypeArguments::ZoneHandle(Z), constructor,
       arguments);
   current_block_->statements->Add(future_node);
 
   // Add to AST:
   //   return :async_completer.future;
   ReturnNode* return_node = new (Z) ReturnNode(
-      Scanner::kNoSourcePos,
+      token_pos,
       new (Z) InstanceGetterNode(
-          Scanner::kNoSourcePos,
+          token_pos,
           new (Z) LoadLocalNode(
-              Scanner::kNoSourcePos,
+              token_pos,
               async_completer),
           Symbols::CompleterFuture()));
   current_block_->statements->Add(return_node);
@@ -7231,7 +7186,8 @@
   if (!Utils::IsInt(16, params->num_fixed_parameters) ||
       !Utils::IsInt(16, params->num_optional_parameters)) {
     const Script& script = Script::Handle(Class::Handle(func.Owner()).script());
-    Report::MessageF(Report::kError, script, func.token_pos(),
+    Report::MessageF(Report::kError,
+                     script, func.token_pos(), Report::AtLocation,
                      "too many formal parameters");
   }
   func.set_num_fixed_parameters(params->num_fixed_parameters);
@@ -7513,7 +7469,7 @@
   result_type = Type::DynamicType();
 
   const intptr_t function_pos = TokenPos();
-  intptr_t metadata_pos = Scanner::kNoSourcePos;
+  intptr_t metadata_pos = Token::kNoSourcePos;
   if (is_literal) {
     ASSERT(CurrentToken() == Token::kLPAREN);
     function_name = &Symbols::AnonymousClosure();
@@ -7553,7 +7509,6 @@
   // Note that we cannot share the same closure function between the closurized
   // and non-closurized versions of the same parent function.
   Function& function = Function::ZoneHandle(Z);
-  bool is_new_closure = false;
   // TODO(hausner): There could be two different closures at the given
   // function_pos, one enclosed in a closurized function and one enclosed in the
   // non-closurized version of this same function.
@@ -7562,7 +7517,6 @@
     // The function will be registered in the lookup table by the
     // EffectGraphVisitor::VisitClosureNode when the newly allocated closure
     // function has been properly setup.
-    is_new_closure = true;
     function = Function::NewClosureFunction(*function_name,
                                             innermost_function(),
                                             function_pos);
@@ -7577,17 +7531,19 @@
   // passed as a function argument, or returned as a function result.
 
   LocalVariable* function_variable = NULL;
-  Type& function_type = Type::ZoneHandle(Z);
+  FunctionType& function_type = FunctionType::ZoneHandle(Z);
   if (variable_name != NULL) {
     // Since the function type depends on the signature of the closure function,
     // it cannot be determined before the formal parameter list of the closure
     // function is parsed. Therefore, we set the function type to a new
-    // parameterized type to be patched after the actual type is known.
-    // We temporarily use the class of the Function interface.
-    const Class& unknown_signature_class = Class::Handle(Z,
-        Type::Handle(Z, Type::Function()).type_class());
-    function_type = Type::New(unknown_signature_class,
-                              TypeArguments::Handle(Z), function_pos);
+    // function type to be patched after the actual type is known.
+    // We temporarily use the Closure class as scope class.
+    const Class& unknown_scope_class = Class::Handle(Z,
+        I->object_store()->closure_class());
+    function_type = FunctionType::New(unknown_scope_class,
+                                      TypeArguments::Handle(Z),
+                                      function,
+                                      function_pos);
     function_type.SetIsFinalized();  // No finalization needed.
 
     // Add the function variable to the scope before parsing the function in
@@ -7611,52 +7567,28 @@
   }
 
   // Parse the local function.
-  SequenceNode* statements = Parser::ParseFunc(function);
+  SequenceNode* statements = Parser::ParseFunc(function, !is_literal);
   INC_STAT(thread(), num_functions_parsed, 1);
 
   // Now that the local function has formal parameters, lookup the signature
-  // class in the current library (but not in its imports) and only create a new
-  // canonical signature class if it does not exist yet.
-  const String& signature = String::Handle(Z, function.Signature());
-  Class& signature_class = Class::ZoneHandle(Z);
-  if (!is_new_closure) {
-    signature_class = function.signature_class();
-  }
-  if (signature_class.IsNull()) {
-    signature_class = library_.LookupLocalClass(signature);
-  }
-  if (signature_class.IsNull()) {
-    // If we don't have a signature class yet, this must be a closure we
-    // have not parsed before.
-    ASSERT(is_new_closure);
-    signature_class = Class::NewSignatureClass(signature,
-                                               function,
-                                               script_,
-                                               function.token_pos());
-    // Record the function signature class in the current library.
-    library_.AddClass(signature_class);
-  } else if (is_new_closure) {
-    function.set_signature_class(signature_class);
-  }
-  ASSERT(function.signature_class() == signature_class.raw());
+  FunctionType& signature_type =
+      FunctionType::ZoneHandle(Z, function.SignatureType());
+  signature_type ^= ClassFinalizer::FinalizeType(
+      current_class(), signature_type, ClassFinalizer::kCanonicalize);
+  function.SetSignatureType(signature_type);
 
   // Local functions are registered in the enclosing class, but
   // ignored during class finalization. The enclosing class has
   // already been finalized.
   ASSERT(current_class().is_finalized());
+  ASSERT(signature_type.IsFinalized());
 
   // Make sure that the instantiator is captured.
-  if ((signature_class.NumTypeParameters() > 0) &&
-      (current_block_->scope->function_level() > 0)) {
+  if ((current_block_->scope->function_level() > 0) &&
+      Class::Handle(signature_type.type_class()).IsGeneric()) {
     CaptureInstantiator();
   }
 
-  // Finalize types in signature class here, so that the
-  // signature type is not computed twice.
-  ClassFinalizer::FinalizeTypesInClass(signature_class);
-  const Type& signature_type = Type::Handle(Z, signature_class.SignatureType());
-  ASSERT(signature_type.IsFinalized());
-
   // A signature type itself cannot be malformed or malbounded, only its
   // signature function's result type or parameter types may be.
   ASSERT(!signature_type.IsMalformed());
@@ -7664,9 +7596,11 @@
 
   if (variable_name != NULL) {
     // Patch the function type of the variable now that the signature is known.
-    function_type.set_type_class(signature_class);
+    function_type.set_scope_class(
+        Class::Handle(Z, signature_type.scope_class()));
     function_type.set_arguments(
         TypeArguments::Handle(Z, signature_type.arguments()));
+    ASSERT(function_type.signature() == function.raw());
 
     // The function type was initially marked as instantiated, but it may
     // actually be uninstantiated.
@@ -8052,6 +7986,7 @@
   TRACE_PARSER("ParseStatementSequence");
   const bool dead_code_allowed = true;
   bool abrupt_completing_seen = false;
+  RecursionChecker rc(this);
   while (CurrentToken() != Token::kRBRACE) {
     const intptr_t statement_pos = TokenPos();
     AstNode* statement = ParseStatement();
@@ -8091,6 +8026,7 @@
     ParseStatementSequence();
     ExpectToken(Token::kRBRACE);
   } else {
+    RecursionChecker rc(this);
     AstNode* statement = ParseStatement();
     if (statement != NULL) {
       current_block_->statements->Add(statement);
@@ -8514,11 +8450,11 @@
   const Function& print_fn = Function::ZoneHandle(
       Z, lib.LookupFunctionAllowPrivate(Symbols::print()));
   ASSERT(!print_fn.IsNull());
-  ArgumentListNode* one_arg = new(Z) ArgumentListNode(Scanner::kNoSourcePos);
+  ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos);
   String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str));
-  one_arg->Add(new(Z) LiteralNode(Scanner::kNoSourcePos, msg));
+  one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg));
   AstNode* print_call =
-      new(Z) StaticCallNode(Scanner::kNoSourcePos, print_fn, one_arg);
+      new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg);
   return print_call;
 }
 
@@ -8723,9 +8659,9 @@
 
   if (outer_saved_try_ctx != NULL) {
     catch_block->Add(new (Z) StoreLocalNode(
-        Scanner::kNoSourcePos,
+        Token::kNoSourcePos,
         outer_saved_try_ctx,
-        new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+        new (Z) LoadLocalNode(Token::kNoSourcePos,
                               outer_async_saved_try_ctx)));
   }
 
@@ -8757,17 +8693,17 @@
   do {
     OpenBlock();
     ArgumentListNode* no_args =
-        new(Z) ArgumentListNode(Scanner::kNoSourcePos);
+        new(Z) ArgumentListNode(Token::kNoSourcePos);
     current_block_->statements->Add(
-        new(Z) InstanceCallNode(Scanner::kNoSourcePos,
-            new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_var),
+        new(Z) InstanceCallNode(Token::kNoSourcePos,
+            new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var),
             Symbols::Cancel(),
             no_args));
     finally_clause = CloseBlock();
     AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
     if (node_to_inline != NULL) {
       InlinedFinallyNode* node =
-          new(Z) InlinedFinallyNode(Scanner::kNoSourcePos,
+          new(Z) InlinedFinallyNode(Token::kNoSourcePos,
                                     finally_clause,
                                     context_var,
                                     outer_try_index);
@@ -8823,7 +8759,7 @@
     ReportError("Loop variable cannot be 'const'");
   }
   const String* loop_var_name = NULL;
-  intptr_t loop_var_pos = Scanner::kNoSourcePos;
+  intptr_t loop_var_pos = Token::kNoSourcePos;
   bool new_loop_var = false;
   AbstractType& loop_var_type =  AbstractType::ZoneHandle(Z);
   if (LookaheadToken(1) == Token::kIN) {
@@ -9124,16 +9060,16 @@
   ASSERT(saved_exception_var != NULL);
   ASSERT(exception_var != NULL);
   statements->Add(new(Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       saved_exception_var,
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var)));
+      new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
 
   ASSERT(saved_stack_trace_var != NULL);
   ASSERT(stack_trace_var != NULL);
   statements->Add(new(Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       saved_stack_trace_var,
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var)));
+      new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
 }
 
 
@@ -9168,9 +9104,9 @@
                                           try_stack_->try_index());
         current_block_->statements->Add(
             new (Z) StoreLocalNode(
-                Scanner::kNoSourcePos,
+                Token::kNoSourcePos,
                 saved_try_ctx,
-                new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+                new (Z) LoadLocalNode(Token::kNoSourcePos,
                                       async_saved_try_ctx)));
       }
     }
@@ -9441,9 +9377,9 @@
                                           try_block->try_index());
         async_code->Add(
             new (Z) StoreLocalNode(
-                Scanner::kNoSourcePos,
+                Token::kNoSourcePos,
                 saved_try_ctx,
-                new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+                new (Z) LoadLocalNode(Token::kNoSourcePos,
                                       async_saved_try_ctx)));
       }
     }
@@ -9470,16 +9406,16 @@
                            Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
                            last_used_try_index_ - 1));
   LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_saved_try_ctx_name,
       Object::dynamic_type());
   ASSERT(async_temp_scope_ != NULL);
   async_temp_scope_->AddVariable(async_saved_try_ctx);
   ASSERT(saved_try_context != NULL);
   current_block_->statements->Add(new(Z) StoreLocalNode(
-      Scanner::kNoSourcePos,
+      Token::kNoSourcePos,
       async_saved_try_ctx,
-      new(Z) LoadLocalNode(Scanner::kNoSourcePos, saved_try_context)));
+      new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context)));
 }
 
 
@@ -9808,9 +9744,9 @@
     ASSERT(iterator_param != NULL);
     // Generate :iterator.current = expr;
     AstNode* iterator =
-        new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_param);
+        new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param);
     AstNode* store_current =
-        new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
+        new(Z) InstanceSetterNode(Token::kNoSourcePos,
                                   iterator,
                                   String::ZoneHandle(Symbols::Current().raw()),
                                   expr);
@@ -9818,7 +9754,7 @@
     if (is_yield_each) {
       // Generate :iterator.isYieldEach = true;
       AstNode* set_is_yield_each =
-          new(Z) InstanceSetterNode(Scanner::kNoSourcePos,
+          new(Z) InstanceSetterNode(Token::kNoSourcePos,
               iterator,
               String::ZoneHandle(Symbols::IsYieldEach().raw()),
               new(Z) LiteralNode(TokenPos(), Bool::True()));
@@ -9827,7 +9763,7 @@
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Scanner::kNoSourcePos);
+                               Token::kNoSourcePos);
     yield->AddNode(await_marker);
     // Return true to indicate that a value has been generated.
     ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
@@ -9848,15 +9784,15 @@
                            &outer_async_saved_try_ctx);
     if (saved_try_ctx != NULL) {
       yield->AddNode(new (Z) StoreLocalNode(
-          Scanner::kNoSourcePos,
+          Token::kNoSourcePos,
           saved_try_ctx,
-          new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+          new (Z) LoadLocalNode(Token::kNoSourcePos,
                                 async_saved_try_ctx)));
       if (outer_saved_try_ctx != NULL) {
         yield->AddNode(new (Z) StoreLocalNode(
-            Scanner::kNoSourcePos,
+            Token::kNoSourcePos,
             outer_saved_try_ctx,
-            new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+            new (Z) LoadLocalNode(Token::kNoSourcePos,
                                   outer_async_saved_try_ctx)));
       }
     } else {
@@ -9874,7 +9810,7 @@
     add_args->Add(expr);
     AstNode* add_call =
         new(Z) InstanceCallNode(yield_pos,
-            new(Z) LoadLocalNode(Scanner::kNoSourcePos, controller_var),
+            new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var),
             is_yield_each ? Symbols::AddStream() : Symbols::add(),
             add_args);
 
@@ -9886,18 +9822,18 @@
     // restore saved_try_context
 
     SequenceNode* true_branch =
-        new(Z) SequenceNode(Scanner::kNoSourcePos, NULL);
+        new(Z) SequenceNode(Token::kNoSourcePos, NULL);
     AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
     true_branch->Add(return_from_generator);
     AddNodeForFinallyInlining(return_from_generator);
     AstNode* if_is_cancelled =
-       new(Z) IfNode(Scanner::kNoSourcePos, add_call, true_branch, NULL);
+       new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL);
     yield->AddNode(if_is_cancelled);
 
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Scanner::kNoSourcePos);
+                               Token::kNoSourcePos);
     yield->AddNode(await_marker);
     ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
     continuation_return->set_return_type(ReturnNode::kContinuationTarget);
@@ -9916,15 +9852,15 @@
                            &outer_async_saved_try_ctx);
     if (saved_try_ctx != NULL) {
       yield->AddNode(new (Z) StoreLocalNode(
-          Scanner::kNoSourcePos,
+          Token::kNoSourcePos,
           saved_try_ctx,
-          new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+          new (Z) LoadLocalNode(Token::kNoSourcePos,
                                 async_saved_try_ctx)));
       if (outer_saved_try_ctx != NULL) {
         yield->AddNode(new (Z) StoreLocalNode(
-            Scanner::kNoSourcePos,
+            Token::kNoSourcePos,
             outer_saved_try_ctx,
-            new (Z) LoadLocalNode(Scanner::kNoSourcePos,
+            new (Z) LoadLocalNode(Token::kNoSourcePos,
                                   outer_async_saved_try_ctx)));
       }
     } else {
@@ -9938,7 +9874,7 @@
 AstNode* Parser::ParseStatement() {
   TRACE_PARSER("ParseStatement");
   AstNode* statement = NULL;
-  intptr_t label_pos = Scanner::kNoSourcePos;
+  intptr_t label_pos = Token::kNoSourcePos;
   String* label_name = NULL;
   if (IsIdentifier()) {
     if (LookaheadToken(1) == Token::kCOLON) {
@@ -10098,7 +10034,19 @@
 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const {
   va_list args;
   va_start(args, format);
-  Report::MessageV(Report::kError, script_, token_pos, format, args);
+  Report::MessageV(Report::kError,
+                   script_, token_pos, Report::AtLocation, format, args);
+  va_end(args);
+  UNREACHABLE();
+}
+
+
+void Parser::ReportErrorBefore(const char* format, ...) {
+  va_list args;
+  va_start(args, format);
+  Report::MessageV(Report::kError,
+                   script_, PrevTokenPos(), Report::AfterLocation,
+                   format, args);
   va_end(args);
   UNREACHABLE();
 }
@@ -10107,7 +10055,8 @@
 void Parser::ReportError(const char* format, ...) const {
   va_list args;
   va_start(args, format);
-  Report::MessageV(Report::kError, script_, TokenPos(), format, args);
+  Report::MessageV(Report::kError,
+                   script_, TokenPos(), Report::AtLocation, format, args);
   va_end(args);
   UNREACHABLE();
 }
@@ -10116,7 +10065,8 @@
 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const {
   va_list args;
   va_start(args, format);
-  Report::MessageV(Report::kWarning, script_, token_pos, format, args);
+  Report::MessageV(Report::kWarning,
+                   script_, token_pos, Report::AtLocation, format, args);
   va_end(args);
 }
 
@@ -10124,7 +10074,8 @@
 void Parser::ReportWarning(const char* format, ...) const {
   va_list args;
   va_start(args, format);
-  Report::MessageV(Report::kWarning, script_, TokenPos(), format, args);
+  Report::MessageV(Report::kWarning,
+                   script_, TokenPos(), Report::AtLocation, format, args);
   va_end(args);
 }
 
@@ -10150,7 +10101,7 @@
 
 void Parser::ExpectSemicolon() {
   if (CurrentToken() != Token::kSEMICOLON) {
-    ReportError("semicolon expected");
+    ReportErrorBefore("semicolon expected");
   }
   ConsumeToken();
 }
@@ -10282,8 +10233,8 @@
       func->is_external() && !func->is_static()) {
     arguments->Add(LoadReceiver(func->token_pos()));
   } else {
-    Type& type = Type::ZoneHandle(Z,
-        Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld));
+    AbstractType& type = AbstractType::ZoneHandle(Z);
+    type ^= Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld);
     type ^= ClassFinalizer::FinalizeType(
         current_class(), type, ClassFinalizer::kCanonicalize);
     arguments->Add(new(Z) LiteralNode(call_pos, type));
@@ -10510,9 +10461,22 @@
   }
   if (binary_op == Token::kIFNULL) {
     // Handle a ?? b.
+    if ((lhs->EvalConstExpr() != NULL) && (rhs->EvalConstExpr() != NULL)) {
+      Instance& expr_value = Instance::ZoneHandle(Z);
+      if (!GetCachedConstant(op_pos, &expr_value)) {
+        expr_value = EvaluateConstExpr(lhs->token_pos(), lhs).raw();
+        if (expr_value.IsNull()) {
+          expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw();
+        }
+        CacheConstantValue(op_pos, expr_value);
+      }
+      return new(Z) LiteralNode(op_pos, expr_value);
+    }
+
     LetNode* result = new(Z) LetNode(op_pos);
     LocalVariable* left_temp = result->AddInitializer(lhs);
-    const intptr_t no_pos = Scanner::kNoSourcePos;
+    left_temp->set_is_final();
+    const intptr_t no_pos = Token::kNoSourcePos;
     LiteralNode* null_operand =
         new(Z) LiteralNode(no_pos, Object::null_instance());
     LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp);
@@ -10814,6 +10778,8 @@
       Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
   const intptr_t expr_pos = TokenPos();
 
+  RecursionChecker rc(this);
+
   if (CurrentToken() == Token::kTHROW) {
     if (require_compiletime_const) {
       ReportError("'throw expr' is not a valid compile-time constant");
@@ -11861,16 +11827,15 @@
 
 const AbstractType* Parser::ReceiverType(const Class& cls) {
   ASSERT(!cls.IsNull());
+  ASSERT(!cls.IsTypedefClass());
+  // Note that if cls is _Closure, the returned type will be _Closure,
+  // and not the signature type.
   Type& type = Type::ZoneHandle(Z, cls.CanonicalType());
   if (!type.IsNull()) {
     return &type;
   }
-  if (cls.IsSignatureClass()) {
-    type = cls.SignatureType();
-  } else {
-    type = Type::New(cls,
-        TypeArguments::Handle(Z, cls.type_parameters()), cls.token_pos());
-  }
+  type = Type::New(cls,
+      TypeArguments::Handle(Z, cls.type_parameters()), cls.token_pos());
   if (cls.is_type_finalized()) {
     type ^= ClassFinalizer::FinalizeType(
         cls, type, ClassFinalizer::kCanonicalizeWellFormed);
@@ -11887,7 +11852,7 @@
       !current_function().IsInFactoryScope()) {
     return false;
   }
-  return current_class().NumTypeParameters() > 0;
+  return current_class().IsGeneric();
 }
 
 // We cache computed compile-time constants in a map so we can look them
@@ -12447,7 +12412,7 @@
     bool consume_unresolved_prefix) {
   LibraryPrefix& prefix = LibraryPrefix::Handle(Z);
   return ParseType(finalization, allow_deferred_type,
-                         consume_unresolved_prefix, &prefix);
+                   consume_unresolved_prefix, &prefix);
 }
 
 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and
@@ -13132,19 +13097,12 @@
   closure.set_result_type(Object::dynamic_type());
   AddFormalParamsToFunction(&params, closure);
 
-  // Create and set the signature class of the closure.
-  const String& sig = String::Handle(Z, closure.Signature());
-  Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig));
-  if (sig_cls.IsNull()) {
-    sig_cls = Class::NewSignatureClass(sig, closure, script_, token_pos);
-    library_.AddClass(sig_cls);
-  }
-  closure.set_signature_class(sig_cls);
-  // Finalize types in signature class here, so that the
-  // signature type is not computed twice.
-  ClassFinalizer::FinalizeTypesInClass(sig_cls);
-  const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType());
-  ASSERT(sig_type.IsFinalized());
+  // Finalize function type.
+  FunctionType& signature_type =
+      FunctionType::Handle(Z, closure.SignatureType());
+  signature_type ^= ClassFinalizer::FinalizeType(
+      current_class(), signature_type, ClassFinalizer::kCanonicalize);
+  closure.SetSignatureType(signature_type);
   // Finalization would be premature when top-level parsing.
   ASSERT(!is_top_level_);
   return closure.raw();
@@ -14318,7 +14276,7 @@
 }  // namespace dart
 
 
-#else  // DART_PRECOMPILED
+#else  // DART_PRECOMPILED_RUNTIME
 
 
 namespace dart {
@@ -14402,4 +14360,4 @@
 
 }  // namespace dart
 
-#endif  // DART_PRECOMPILED
+#endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 1be0f50..9d9e503 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -36,6 +36,7 @@
 struct ParamList;
 struct QualIdent;
 class TopLevel;
+class RecursionChecker;
 
 // The class ParsedFunction holds the result of parsing a function.
 class ParsedFunction : public ZoneAllocated {
@@ -294,6 +295,7 @@
   }
 
   intptr_t TokenPos() const { return tokens_iterator_.CurrentPosition(); }
+  intptr_t PrevTokenPos() const { return prev_token_pos_; }
 
   Token::Kind CurrentToken() {
     if (token_kind_ == Token::kILLEGAL) {
@@ -316,6 +318,7 @@
 
   void ConsumeToken() {
     // Reset cache and advance the token.
+    prev_token_pos_ = tokens_iterator_.CurrentPosition();
     token_kind_ = Token::kILLEGAL;
     tokens_iterator_.Advance();
     INC_STAT(thread(), num_tokens_consumed, 1);
@@ -363,6 +366,9 @@
                                          const Function& constructor,
                                          const TypeArguments& type_arguments);
 
+  // Report error if parsed code is too deeply nested; avoid stack overflow.
+  void CheckStack();
+
   // Report already formatted error.
   static void ReportError(const Error& error);
 
@@ -374,6 +380,8 @@
   // Report error message at location of current token in current script.
   void ReportError(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);
 
+  void ReportErrorBefore(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
+
   // Report error message at given location in current script.
   void ReportError(intptr_t token_pos,
                    const char* msg, ...) const PRINTF_ATTRIBUTE(3, 4);
@@ -533,7 +541,7 @@
   void AddFormalParamsToScope(const ParamList* params, LocalScope* scope);
 
   SequenceNode* ParseConstructor(const Function& func);
-  SequenceNode* ParseFunc(const Function& func);
+  SequenceNode* ParseFunc(const Function& func, bool check_semicolon);
 
   void ParseNativeFunctionBlock(const ParamList* params, const Function& func);
 
@@ -833,6 +841,7 @@
   Script& script_;
   TokenStream::Iterator tokens_iterator_;
   Token::Kind token_kind_;  // Cached token kind for current token.
+  intptr_t prev_token_pos_;
   Block* current_block_;
 
   // is_top_level_ is true if parsing the "top level" of a compilation unit,
@@ -889,6 +898,9 @@
   // Indentation of parser trace.
   intptr_t trace_indent_;
 
+  intptr_t recursion_counter_;
+  friend class RecursionChecker;
+
   DISALLOW_COPY_AND_ASSIGN(Parser);
 };
 
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index e7450b7..a5e6f2e 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -270,7 +270,7 @@
       "   name=:current_context_var\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -309,7 +309,7 @@
       "   name=:current_context_var\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -325,7 +325,7 @@
       " 3 StackVar      scope=2   begin=18  end=38  name=c\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -368,7 +368,7 @@
       "   name=:current_context_var\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -384,7 +384,7 @@
       " 3 StackVar      scope=2   begin=30  end=52  name=bb\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -397,7 +397,7 @@
       " 2 StackVar      scope=2   begin=18  end=62  name=aa\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -450,7 +450,7 @@
       "   name=:current_context_var\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -495,7 +495,7 @@
       "   name=:current_context_var\n"
 
       // Closure call saves current context.
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -536,7 +536,7 @@
       " 0 ContextVar    level=0   begin=50  end=62  name=x\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
@@ -551,7 +551,7 @@
       " 4 ContextVar    level=1   begin=22  end=47  name=i\n"
       " 5 StackVar      scope=4   begin=32  end=47  name=d\n"
 
-      "_FunctionImpl.call\n"
+      "_Closure.call\n"
       " 0 StackVar      scope=1   begin=0   end=4   name=this\n"
       " 1 CurrentCtx    scope=0   begin=0   end=0"
       "   name=:current_context_var\n"
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 97f90c3..2131faf 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -63,6 +63,7 @@
     class_count_(0),
     selector_count_(0),
     dropped_function_count_(0),
+    dropped_field_count_(0),
     libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
     pending_functions_(
         GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
@@ -111,6 +112,7 @@
   }
 
   DropUncompiledFunctions();
+  DropFields();
 
   // TODO(rmacnak): DropEmptyClasses();
 
@@ -120,14 +122,18 @@
 
   if (FLAG_trace_precompiler) {
     THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
-              " %" Pd " dynamic selectors.\n Dropped %" Pd " functions.\n",
+              " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd
+              " fields.\n",
               function_count_,
               class_count_,
               selector_count_,
-              dropped_function_count_);
+              dropped_function_count_,
+              dropped_field_count_);
   }
 
   I->set_compilation_allowed(false);
+  I->object_store()->set_compile_time_constants(Array::null_array());
+  I->object_store()->set_unique_dynamic_targets(Array::null_array());
 }
 
 
@@ -154,6 +160,7 @@
   static const intptr_t kExternallyAllocatedCids[] = {
     kBoolCid,
     kNullCid,
+    kClosureCid,
 
     kSmiCid,
     kMintCid,
@@ -201,6 +208,7 @@
     kFloat64x2Cid,
 
     kTypeCid,
+    kFunctionTypeCid,
     kTypeRefCid,
     kTypeParameterCid,
     kBoundedTypeCid,
@@ -224,6 +232,7 @@
   }
 
   Dart_QualifiedFunctionName vm_entry_points[] = {
+    // Functions
     { "dart:async", "::", "_setScheduleImmediateClosure" },
     { "dart:core", "::", "_completeDeferredLoads"},
     { "dart:core", "AbstractClassInstantiationError",
@@ -262,6 +271,9 @@
     { "dart:_vmservice", "::", "_registerIsolate" },
     { "dart:_vmservice", "::", "boot" },
     { "dart:developer", "Metrics", "_printMetrics" },
+    // Fields
+    { "dart:core", "Error", "_stackTrace" },
+    { "dart:math", "_Random", "_state" },
     { NULL, NULL, NULL }  // Must be terminated with NULL entries.
   };
 
@@ -274,6 +286,7 @@
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
   Function& func = Function::Handle(Z);
+  Field& field = Field::Handle(Z);
   String& library_uri = String::Handle(Z);
   String& class_name = String::Handle(Z);
   String& function_name = String::Handle(Z);
@@ -293,6 +306,7 @@
 
     if (class_name.raw() == Symbols::TopLevel().raw()) {
       func = lib.LookupFunctionAllowPrivate(function_name);
+      field = lib.LookupFieldAllowPrivate(function_name);
     } else {
       cls = lib.LookupClassAllowPrivate(class_name);
       if (cls.IsNull()) {
@@ -306,25 +320,31 @@
 
       ASSERT(!cls.IsNull());
       func = cls.LookupFunctionAllowPrivate(function_name);
+      field = cls.LookupField(function_name);
     }
 
-    if (func.IsNull()) {
+    if (func.IsNull() && field.IsNull()) {
       if (FLAG_trace_precompiler) {
         THR_Print("WARNING: Missing %s %s %s\n",
                   entry_points[i].library_uri,
                   entry_points[i].class_name,
                   entry_points[i].function_name);
       }
-      continue;
     }
 
-    AddFunction(func);
-    if (func.IsGenerativeConstructor()) {
-      // Allocation stubs are referenced from the call site of the constructor,
-      // not in the constructor itself. So compiling the constructor isn't
-      // enough for us to discover the class is instantiated if the class isn't
-      // otherwise instantiated from Dart code and only instantiated from C++.
-      AddInstantiatedClass(cls);
+    if (!func.IsNull()) {
+      AddFunction(func);
+      if (func.IsGenerativeConstructor()) {
+        // Allocation stubs are referenced from the call site of the
+        // constructor, not in the constructor itself. So compiling the
+        // constructor isn't enough for us to discover the class is
+        // instantiated if the class isn't otherwise instantiated from Dart
+        // code and only instantiated from C++.
+        AddInstantiatedClass(cls);
+      }
+    }
+    if (!field.IsNull()) {
+      AddField(field);
     }
   }
 }
@@ -468,7 +488,8 @@
 
   if (instance.IsClosure()) {
     // An implicit static closure.
-    const Function& func = Function::Handle(Z, Closure::function(instance));
+    const Function& func =
+        Function::Handle(Z, Closure::Cast(instance).function());
     ASSERT(func.is_static());
     AddFunction(func);
     return;
@@ -511,10 +532,8 @@
 void Precompiler::AddClosureCall(const ICData& call_site) {
   const Array& arguments_descriptor =
       Array::Handle(Z, call_site.arguments_descriptor());
-  const Type& function_impl =
-      Type::Handle(Z, I->object_store()->function_impl_type());
   const Class& cache_class =
-      Class::Handle(Z, function_impl.type_class());
+      Class::Handle(Z, I->object_store()->closure_class());
   const Function& dispatcher = Function::Handle(Z,
       cache_class.GetInvocationDispatcher(Symbols::Call(),
                                           arguments_descriptor,
@@ -525,6 +544,8 @@
 
 
 void Precompiler::AddField(const Field& field) {
+  fields_to_retain_.Insert(&Field::ZoneHandle(Z, field.raw()));
+
   if (field.is_static()) {
     const Object& value = Object::Handle(Z, field.StaticValue());
     if (value.IsInstance()) {
@@ -906,12 +927,12 @@
         }
       }
 
-      functions = Array::New(retained_functions.Length(), Heap::kOld);
-      for (intptr_t j = 0; j < retained_functions.Length(); j++) {
-        function ^= retained_functions.At(j);
-        functions.SetAt(j, function);
+      if (retained_functions.Length() > 0) {
+        functions = Array::MakeArray(retained_functions);
+        cls.SetFunctions(functions);
+      } else {
+        cls.SetFunctions(Object::empty_array());
       }
-      cls.SetFunctions(functions);
     }
   }
 
@@ -933,6 +954,49 @@
 }
 
 
+void Precompiler::DropFields() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Array& fields = Array::Handle(Z);
+  Field& field = Field::Handle(Z);
+  GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+
+      fields = cls.fields();
+      retained_fields = GrowableObjectArray::New();
+      for (intptr_t j = 0; j < fields.Length(); j++) {
+        field ^= fields.At(j);
+        bool drop = fields_to_retain_.Lookup(&field) == NULL;
+        if (drop) {
+          dropped_field_count_++;
+          if (FLAG_trace_precompiler) {
+            THR_Print("Precompilation dropping %s\n",
+                      field.ToCString());
+          }
+        } else {
+          retained_fields.Add(field);
+        }
+      }
+
+      if (retained_fields.Length() > 0) {
+        fields = Array::MakeArray(retained_fields);
+        cls.SetFields(fields);
+      } else {
+        cls.SetFields(Object::empty_array());
+      }
+    }
+  }
+}
+
+
 void Precompiler::BindStaticCalls() {
   class BindStaticCallsVisitor : public FunctionVisitor {
    public:
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index 50f9551..fe7ec2d 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -87,6 +87,29 @@
 typedef DirectChainedHashMap<FunctionKeyValueTrait> FunctionSet;
 
 
+class FieldKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const Field* Key;
+  typedef const Field* Value;
+  typedef const Field* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->token_pos();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<FieldKeyValueTrait> FieldSet;
+
+
 class Precompiler : public ValueObject {
  public:
   static RawError* CompileAll(
@@ -125,6 +148,7 @@
   void CheckForNewDynamicFunctions();
 
   void DropUncompiledFunctions();
+  void DropFields();
   void CollectDynamicFunctionNames();
   void BindStaticCalls();
   void DedupStackmaps();
@@ -155,11 +179,13 @@
   intptr_t class_count_;
   intptr_t selector_count_;
   intptr_t dropped_function_count_;
+  intptr_t dropped_field_count_;
 
   const GrowableObjectArray& libraries_;
   const GrowableObjectArray& pending_functions_;
   SymbolSet sent_selectors_;
   FunctionSet enqueued_functions_;
+  FieldSet fields_to_retain_;
   Error& error_;
 };
 
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 63ac759..4c30971 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -853,7 +853,7 @@
 }
 
 
-TEST_CASE(Profiler_ClassAllocation) {
+TEST_CASE(Profiler_ClosureAllocation) {
   DisableNativeProfileScope dnps;
   const char* kScript =
       "var msg1 = 'a';\n"
@@ -875,12 +875,12 @@
   root_library ^= Api::UnwrapHandle(lib);
   Isolate* isolate = thread->isolate();
 
-  const Class& class_class =
-      Class::Handle(Object::class_class());
-  EXPECT(!class_class.IsNull());
-  class_class.SetTraceAllocation(true);
+  const Class& closure_class =
+      Class::Handle(Isolate::Current()->object_store()->closure_class());
+  EXPECT(!closure_class.IsNull());
+  closure_class.SetTraceAllocation(true);
 
-  // Invoke "foo" which during compilation, triggers a closure class allocation.
+  // Invoke "foo" which during compilation, triggers a closure allocation.
   Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL);
   EXPECT_VALID(result);
 
@@ -888,7 +888,7 @@
     StackZone zone(thread);
     HANDLESCOPE(thread);
     Profile profile(isolate);
-    AllocationFilter filter(isolate, class_class.id());
+    AllocationFilter filter(isolate, closure_class.id());
     filter.set_enable_vm_ticks(true);
     profile.Build(thread, &filter, Profile::kNoTags);
     // We should have one allocation sample.
@@ -897,19 +897,14 @@
 
     walker.Reset(Profile::kExclusiveCode);
     EXPECT(walker.Down());
-#if defined(TARGET_OS_WINDOWS)
-    // TODO(johnmccutchan): Hookup native symbol resolver on Windows.
-    EXPECT_SUBSTRING("[Native]", walker.CurrentName());
-#else
-    EXPECT_SUBSTRING("dart::Profiler::SampleAllocation", walker.CurrentName());
-#endif
+    EXPECT_SUBSTRING("foo", walker.CurrentName());
     EXPECT(!walker.Down());
   }
 
-  // Disable allocation tracing for Class.
-  class_class.SetTraceAllocation(false);
+  // Disable allocation tracing for Closure.
+  closure_class.SetTraceAllocation(false);
 
-  // Invoke "bar" which during compilation, triggers a closure class allocation.
+  // Invoke "bar" which during compilation, triggers a closure allocation.
   result = Dart_Invoke(lib, NewString("bar"), 0, NULL);
   EXPECT_VALID(result);
 
@@ -917,7 +912,7 @@
     StackZone zone(thread);
     HANDLESCOPE(thread);
     Profile profile(isolate);
-    AllocationFilter filter(isolate, class_class.id());
+    AllocationFilter filter(isolate, closure_class.id());
     filter.set_enable_vm_ticks(true);
     profile.Build(thread, &filter, Profile::kNoTags);
     // We should still only have one allocation sample.
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index ba53d37..d32b5ab 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -144,6 +144,13 @@
       instance_size = PcDescriptors::InstanceSize(length);
       break;
     }
+    case kCodeSourceMapCid: {
+      const RawCodeSourceMap* raw_code_source_map =
+          reinterpret_cast<const RawCodeSourceMap*>(this);
+      intptr_t length = raw_code_source_map->ptr()->length_;
+      instance_size = CodeSourceMap::InstanceSize(length);
+      break;
+    }
     case kStackmapCid: {
       const RawStackmap* map = reinterpret_cast<const RawStackmap*>(this);
       intptr_t length = map->ptr()->length_;
@@ -336,6 +343,13 @@
 }
 
 
+intptr_t RawFunctionType::VisitFunctionTypePointers(
+    RawFunctionType* raw_obj, ObjectPointerVisitor* visitor) {
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return FunctionType::InstanceSize();
+}
+
+
 intptr_t RawTypeRef::VisitTypeRefPointers(
     RawTypeRef* raw_obj, ObjectPointerVisitor* visitor) {
   visitor->VisitPointers(raw_obj->from(), raw_obj->to());
@@ -379,6 +393,13 @@
 }
 
 
+intptr_t RawClosure::VisitClosurePointers(
+    RawClosure* raw_obj, ObjectPointerVisitor* visitor) {
+  visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+  return Closure::InstanceSize();
+}
+
+
 intptr_t RawClosureData::VisitClosureDataPointers(
     RawClosureData* raw_obj, ObjectPointerVisitor* visitor) {
   visitor->VisitPointers(raw_obj->from(), raw_obj->to());
@@ -575,6 +596,12 @@
 }
 
 
+intptr_t RawCodeSourceMap::VisitCodeSourceMapPointers(
+    RawCodeSourceMap* raw_obj, ObjectPointerVisitor* visitor) {
+  return CodeSourceMap::InstanceSize(raw_obj->ptr()->length_);
+}
+
+
 intptr_t RawStackmap::VisitStackmapPointers(RawStackmap* raw_obj,
                                             ObjectPointerVisitor* visitor) {
   return Stackmap::InstanceSize(raw_obj->ptr()->length_);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ee5450d..35be68a 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -33,6 +33,7 @@
   V(Instructions)                                                              \
   V(ObjectPool)                                                                \
   V(PcDescriptors)                                                             \
+  V(CodeSourceMap)                                                             \
   V(Stackmap)                                                                  \
   V(LocalVarDescriptors)                                                       \
   V(ExceptionHandlers)                                                         \
@@ -50,10 +51,12 @@
     V(LibraryPrefix)                                                           \
     V(AbstractType)                                                            \
       V(Type)                                                                  \
+      V(FunctionType)                                                          \
       V(TypeRef)                                                               \
       V(TypeParameter)                                                         \
       V(BoundedType)                                                           \
       V(MixinAppType)                                                          \
+    V(Closure)                                                                 \
     V(Number)                                                                  \
       V(Integer)                                                               \
         V(Smi)                                                                 \
@@ -145,9 +148,10 @@
 #define DEFINE_OBJECT_KIND(clazz)                                              \
   kTypedData##clazz##ViewCid,
 CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
-  kByteDataViewCid,
 #undef DEFINE_OBJECT_KIND
 
+  kByteDataViewCid,
+
 #define DEFINE_OBJECT_KIND(clazz)                                              \
   kExternalTypedData##clazz##Cid,
 CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
@@ -590,8 +594,8 @@
   friend class Array;
   friend class Bigint;
   friend class ByteBuffer;
-  friend class Code;
   friend class Closure;
+  friend class Code;
   friend class Double;
   friend class FreeListElement;
   friend class Function;
@@ -659,7 +663,7 @@
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
   RawAbstractType* super_type_;
   RawType* mixin_;  // Generic mixin type, e.g. M<T>, not M<int>.
-  RawFunction* signature_function_;  // Associated function for signature class.
+  RawFunction* signature_function_;  // Associated function for typedef class.
   RawArray* constants_;  // Canonicalized values of this class.
   RawObject* canonical_types_;  // An array of canonicalized types of this class
                                 // or the canonical type.
@@ -830,7 +834,7 @@
   }
   RawContextScope* context_scope_;
   RawFunction* parent_function_;  // Enclosing function of this local function.
-  RawClass* signature_class_;
+  RawFunctionType* signature_type_;
   RawInstance* closure_;  // Closure object for static implicit closures.
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->closure_);
@@ -1052,6 +1056,7 @@
   RawObject* owner_;  // Function, Null, or a Class.
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
+  RawCodeSourceMap* code_source_map_;
   RawArray* stackmaps_;
   RawObject** to_snapshot() {
     return reinterpret_cast<RawObject**>(&ptr()->stackmaps_);
@@ -1199,6 +1204,23 @@
 };
 
 
+// CodeSourceMap stores a mapping between code PC ranges and source token
+// positions.
+class RawCodeSourceMap : public RawObject {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(CodeSourceMap);
+
+  int32_t length_;  // Number of entries.
+
+  // Variable length data follows here.
+  uint8_t* data() { OPEN_ARRAY_START(uint8_t, intptr_t); }
+  const uint8_t* data() const { OPEN_ARRAY_START(uint8_t, intptr_t); }
+
+  friend class Object;
+  friend class SnapshotReader;
+};
+
+
 // Stackmap is an immutable representation of the layout of the stack at a
 // PC. The stack map representation consists of a bit map which marks each
 // live object index starting from the base of the frame.
@@ -1471,6 +1493,7 @@
     return reinterpret_cast<RawObject**>(&ptr()->formatted_message_);
   }
   int32_t token_pos_;  // Source position in script_.
+  bool report_after_token_;  // Report message at or after the token.
   int8_t kind_;  // Of type LanguageError::Kind.
 };
 
@@ -1562,6 +1585,25 @@
 };
 
 
+class RawFunctionType : public RawAbstractType {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(FunctionType);
+
+  RawObject** from() {
+    return reinterpret_cast<RawObject**>(&ptr()->scope_class_);
+  }
+  RawClass* scope_class_;
+  RawTypeArguments* arguments_;
+  RawFunction* signature_;
+  RawLanguageError* error_;  // Error object if type is malformed or malbounded.
+  RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->error_);
+  }
+  int32_t token_pos_;
+  int8_t type_state_;
+};
+
+
 class RawTypeRef : public RawAbstractType {
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeRef);
@@ -1624,6 +1666,24 @@
 };
 
 
+class RawClosure : public RawInstance {
+ private:
+  RAW_HEAP_OBJECT_IMPLEMENTATION(Closure);
+
+  RawObject** from() {
+    return reinterpret_cast<RawObject**>(&ptr()->type_arguments_);
+  }
+
+  RawTypeArguments* type_arguments_;
+  RawFunction* function_;
+  RawContext* context_;
+
+  RawObject** to() {
+    return reinterpret_cast<RawObject**>(&ptr()->context_);
+  }
+};
+
+
 class RawNumber : public RawInstance {
   RAW_OBJECT_IMPLEMENTATION(Number);
 };
@@ -2245,6 +2305,7 @@
          (index == kInstructionsCid) ||
          (index == kObjectPoolCid) ||
          (index == kPcDescriptorsCid) ||
+         (index == kCodeSourceMapCid) ||
          (index == kStackmapCid) ||
          (index == kLocalVarDescriptorsCid) ||
          (index == kExceptionHandlersCid) ||
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 87305ba..3a934d5 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -237,7 +237,7 @@
   READ_OBJECT_FIELDS(type, type.raw()->from(), type.raw()->to(), kAsReference);
 
   // Set the canonical bit.
-  if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
+  if (!defer_canonicalization && is_canonical) {
     type.SetCanonical();
   }
 
@@ -275,15 +275,89 @@
   writer->Write<int32_t>(ptr()->token_pos_);
   writer->Write<int8_t>(ptr()->type_state_);
 
-  // Write out all the object pointer fields. Since we will be canonicalizing
-  // the type object when reading it back we should write out all the fields
-  // inline and not as references.
+  // Write out all the object pointer fields.
   ASSERT(ptr()->type_class_ != Object::null());
   SnapshotWriterVisitor visitor(writer, kAsReference);
   visitor.VisitPointers(from(), to());
 }
 
 
+RawFunctionType* FunctionType::ReadFrom(SnapshotReader* reader,
+                                        intptr_t object_id,
+                                        intptr_t tags,
+                                        Snapshot::Kind kind,
+                                        bool as_reference) {
+  ASSERT(reader != NULL);
+
+  // Determine if the scope class of this function type is in the full snapshot.
+  bool scopeclass_is_in_fullsnapshot = reader->Read<bool>();
+
+  // Allocate function type object.
+  FunctionType& function_type =
+      FunctionType::ZoneHandle(reader->zone(), NEW_OBJECT(FunctionType));
+  bool is_canonical = RawObject::IsCanonical(tags);
+  bool defer_canonicalization = is_canonical &&
+      (kind != Snapshot::kFull && scopeclass_is_in_fullsnapshot);
+  reader->AddBackRef(object_id,
+                     &function_type,
+                     kIsDeserialized,
+                     defer_canonicalization);
+
+  // Set all non object fields.
+  function_type.set_token_pos(reader->Read<int32_t>());
+  function_type.set_type_state(reader->Read<int8_t>());
+
+  // Set all the object fields.
+  READ_OBJECT_FIELDS(function_type,
+                     function_type.raw()->from(), function_type.raw()->to(),
+                     kAsReference);
+
+  // Set the canonical bit.
+  if (!defer_canonicalization && is_canonical) {
+    function_type.SetCanonical();
+  }
+
+  return function_type.raw();
+}
+
+
+void RawFunctionType::WriteTo(SnapshotWriter* writer,
+                              intptr_t object_id,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
+  ASSERT(writer != NULL);
+
+  // Only resolved and finalized function types should be written to a snapshot.
+  ASSERT((ptr()->type_state_ == RawFunctionType::kFinalizedInstantiated) ||
+         (ptr()->type_state_ == RawFunctionType::kFinalizedUninstantiated));
+  ASSERT(ptr()->scope_class_ != Object::null());
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(kFunctionTypeCid);
+  writer->WriteTags(writer->GetObjectTags(this));
+
+  // Write out scopeclass_is_in_fullsnapshot first as this will
+  // help the reader decide on how to canonicalize the type object.
+  intptr_t tags = writer->GetObjectTags(ptr()->scope_class_);
+  bool scopeclass_is_in_fullsnapshot =
+      (ClassIdTag::decode(tags) == kClassCid) &&
+      Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(ptr()->scope_class_));
+  writer->Write<bool>(scopeclass_is_in_fullsnapshot);
+
+  // Write out all the non object pointer fields.
+  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int8_t>(ptr()->type_state_);
+
+  // Write out all the object pointer fields.
+  ASSERT(ptr()->scope_class_ != Object::null());
+  SnapshotWriterVisitor visitor(writer, kAsReference);
+  visitor.VisitPointers(from(), to());
+}
+
+
 RawTypeRef* TypeRef::ReadFrom(SnapshotReader* reader,
                               intptr_t object_id,
                               intptr_t tags,
@@ -472,7 +546,7 @@
   }
 
   // Set the canonical bit.
-  if (!defer_canonicalization && RawObject::IsCanonical(tags)) {
+  if (!defer_canonicalization && is_canonical) {
     type_arguments.SetCanonical();
   }
 
@@ -548,6 +622,57 @@
 }
 
 
+RawClosure* Closure::ReadFrom(SnapshotReader* reader,
+                              intptr_t object_id,
+                              intptr_t tags,
+                              Snapshot::Kind kind,
+                              bool as_reference) {
+  ASSERT(reader != NULL);
+  ASSERT(kind == Snapshot::kFull);
+
+  // Allocate closure object.
+  Closure& closure = Closure::ZoneHandle(
+      reader->zone(), NEW_OBJECT(Closure));
+  reader->AddBackRef(object_id, &closure, kIsDeserialized);
+
+  // Set all the object fields.
+  READ_OBJECT_FIELDS(closure,
+                     closure.raw()->from(), closure.raw()->to(),
+                     kAsReference);
+
+  return closure.raw();
+}
+
+
+void RawClosure::WriteTo(SnapshotWriter* writer,
+                         intptr_t object_id,
+                         Snapshot::Kind kind,
+                         bool as_reference) {
+  ASSERT(writer != NULL);
+  if ((kind == Snapshot::kMessage) || (kind == Snapshot::kScript)) {
+    // Check if closure is serializable, throw an exception otherwise.
+    RawFunction* func = writer->IsSerializableClosure(this);
+    if (func != Function::null()) {
+      writer->WriteStaticImplicitClosure(object_id,
+                                         func,
+                                         writer->GetObjectTags(this));
+      return;
+    }
+  }
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+
+  // Write out the class and tags information.
+  writer->WriteIndexedObject(kClosureCid);
+  writer->WriteTags(writer->GetObjectTags(this));
+
+  // Write out all the object pointer fields.
+  SnapshotWriterVisitor visitor(writer, kAsReference);
+  visitor.VisitPointers(from(), to());
+}
+
+
 RawClosureData* ClosureData::ReadFrom(SnapshotReader* reader,
                                       intptr_t object_id,
                                       intptr_t tags,
@@ -599,8 +724,8 @@
   // Parent function.
   writer->WriteObjectImpl(ptr()->parent_function_, kAsInlinedObject);
 
-  // Signature class.
-  writer->WriteObjectImpl(ptr()->signature_class_, kAsInlinedObject);
+  // Signature type.
+  writer->WriteObjectImpl(ptr()->signature_type_, kAsInlinedObject);
 
   // Static closure/Closure allocation stub.
   // We don't write the closure or allocation stub in the snapshot.
@@ -665,12 +790,15 @@
         reader->zone(), NEW_OBJECT(Function));
     reader->AddBackRef(object_id, &func, kIsDeserialized);
 
-    // Set all the non object fields.
-    func.set_token_pos(reader->Read<int32_t>());
-    func.set_end_token_pos(reader->Read<int32_t>());
+    // Set all the non object fields. Read the token positions now but
+    // don't set them until after setting the kind.
+    const int32_t token_pos = reader->Read<int32_t>();
+    const int32_t end_token_pos = reader->Read<uint32_t>();
     func.set_num_fixed_parameters(reader->Read<int16_t>());
     func.set_num_optional_parameters(reader->Read<int16_t>());
     func.set_kind_tag(reader->Read<uint32_t>());
+    func.set_token_pos(token_pos);
+    func.set_end_token_pos(end_token_pos);
     if (reader->snapshot_code()) {
       func.set_usage_counter(0);
       func.set_deoptimization_counter(0);
@@ -720,7 +848,7 @@
   ASSERT((kind == Snapshot::kScript) || (kind == Snapshot::kFull));
   bool is_in_fullsnapshot = false;
   bool owner_is_class = false;
-  if (kind == Snapshot::kScript) {
+  if ((kind == Snapshot::kScript) && !Function::IsSignatureFunction(this)) {
     intptr_t tags = writer->GetObjectTags(ptr()->owner_);
     intptr_t cid = ClassIdTag::decode(tags);
     owner_is_class = (cid == kClassCid);
@@ -1107,26 +1235,27 @@
     // The native resolver and symbolizer are not serialized.
     library.set_native_entry_resolver(NULL);
     library.set_native_entry_symbol_resolver(NULL);
-    // The cache of loaded scripts is not serialized.
-    library.StorePointer(&library.raw_ptr()->loaded_scripts_, Array::null());
 
     // Set all the object fields.
     // TODO(5411462): Need to assert No GC can happen here, even though
     // allocations may happen.
-    RawObject** toobj = (kind == Snapshot::kFull) ?
-        library.raw()->to() : library.raw()->to_snapshot();
-    intptr_t num_flds = (toobj - library.raw()->from());
+    intptr_t num_flds = (library.raw()->to_snapshot() - library.raw()->from());
     for (intptr_t i = 0; i <= num_flds; i++) {
       (*reader->PassiveObjectHandle()) = reader->ReadObjectImpl(kAsReference);
       library.StorePointer((library.raw()->from() + i),
                            reader->PassiveObjectHandle()->raw());
     }
+    // Initialize cache of resolved names.
+    const intptr_t kInitialNameCacheSize = 64;
     if (kind != Snapshot::kFull) {
       // The cache of resolved names in library scope is not serialized.
-      const intptr_t kInitialNameCacheSize = 64;
       library.InitResolvedNamesCache(kInitialNameCacheSize);
       library.Register();
+    } else {
+      library.InitResolvedNamesCache(kInitialNameCacheSize, reader);
     }
+    // Initialize cache of loaded scripts.
+    library.StorePointer(&library.raw_ptr()->loaded_scripts_, Array::null());
   }
   return library.raw();
 }
@@ -1165,14 +1294,13 @@
     writer->Write<bool>(ptr()->debuggable_);
     // We do not serialize the native resolver or symbolizer. These need to be
     // explicitly set after deserialization.
-    // We do not write the loaded_scripts_ cache to the snapshot. It gets
-    // set to NULL when reading the library from the snapshot, and will
-    // be rebuilt lazily.
 
+    // We do not write the loaded_scripts_ and resolved_names_ caches to the
+    // snapshot. They get initialized when reading the library from the
+    // snapshot and will be rebuilt lazily.
     // Write out all the object pointer fields.
-    RawObject** toobj = (kind == Snapshot::kFull) ? to() : to_snapshot();
     SnapshotWriterVisitor visitor(writer, kAsReference);
-    visitor.VisitPointers(from(), toobj);
+    visitor.VisitPointers(from(), to_snapshot());
   }
 }
 
@@ -1548,6 +1676,51 @@
 }
 
 
+RawCodeSourceMap* CodeSourceMap::ReadFrom(SnapshotReader* reader,
+                                          intptr_t object_id,
+                                          intptr_t tags,
+                                          Snapshot::Kind kind,
+                                          bool as_reference) {
+  ASSERT(reader->snapshot_code());
+  ASSERT(kind == Snapshot::kFull);
+
+  const int32_t length = reader->Read<int32_t>();
+  CodeSourceMap& result =
+      CodeSourceMap::ZoneHandle(reader->zone(),
+                                NEW_OBJECT_WITH_LEN(CodeSourceMap, length));
+  reader->AddBackRef(object_id, &result, kIsDeserialized);
+
+  if (result.Length() > 0) {
+    NoSafepointScope no_safepoint;
+    intptr_t len = result.Length();
+    uint8_t* data = result.UnsafeMutableNonPointer(result.raw_ptr()->data());
+    reader->ReadBytes(data, len);
+  }
+
+  return result.raw();
+}
+
+
+void RawCodeSourceMap::WriteTo(SnapshotWriter* writer,
+                               intptr_t object_id,
+                               Snapshot::Kind kind,
+                               bool as_reference) {
+  ASSERT(writer->snapshot_code());
+  ASSERT(kind == Snapshot::kFull);
+
+  // Write out the serialization header value for this object.
+  writer->WriteInlinedObjectHeader(object_id);
+  writer->WriteIndexedObject(kCodeSourceMapCid);
+  writer->WriteTags(writer->GetObjectTags(this));
+  writer->Write<int32_t>(ptr()->length_);
+  if (ptr()->length_ > 0) {
+    intptr_t len = ptr()->length_;
+    uint8_t* data = reinterpret_cast<uint8_t*>(ptr()->data());
+    writer->WriteBytes(data, len);
+  }
+}
+
+
 RawStackmap* Stackmap::ReadFrom(SnapshotReader* reader,
                                 intptr_t object_id,
                                 intptr_t tags,
@@ -2037,6 +2210,7 @@
 
   // Set all non object fields.
   language_error.set_token_pos(reader->Read<int32_t>());
+  language_error.set_report_after_token(reader->Read<bool>());
   language_error.set_kind(reader->Read<uint8_t>());
 
   // Set all the object fields.
@@ -2063,6 +2237,7 @@
 
   // Write out all the non object fields.
   writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<bool>(ptr()->report_after_token_);
   writer->Write<uint8_t>(ptr()->kind_);
 
   // Write out all the object pointer fields.
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index a41db46..40043b7 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -36,7 +36,7 @@
 
 
 static const intptr_t kInvalidTryIndex = CatchClauseNode::kInvalidTryIndex;
-static const intptr_t kNoSourcePos = Scanner::kNoSourcePos;
+static const intptr_t kNoSourcePos = Token::kNoSourcePos;
 static const intptr_t kMinStackSize = 512;
 
 
@@ -588,13 +588,13 @@
 
 
 LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const {
-  return new(Z) LoadLocalInstr(*local);
+  return new(Z) LoadLocalInstr(*local, kNoSourcePos);
 }
 
 
 void IRRegExpMacroAssembler::StoreLocal(LocalVariable* local,
                                         Value* value) {
-  Do(new(Z) StoreLocalInstr(*local, value));
+  Do(new(Z) StoreLocalInstr(*local, value, kNoSourcePos));
 }
 
 
@@ -621,7 +621,7 @@
     return Bind(new(Z) ConstantInstr(*local.ConstValue()));
   }
   ASSERT(!local.is_captured());
-  return Bind(new(Z) LoadLocalInstr(local));
+  return Bind(new(Z) LoadLocalInstr(local, kNoSourcePos));
 }
 
 
@@ -1924,7 +1924,7 @@
       index_val,
       characters,
       specialization_cid_,
-      Scanner::kNoSourcePos));
+      kNoSourcePos));
 }
 
 
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index d09d2a9..e5ab2ec 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -26,6 +26,7 @@
 RawString* Report::PrependSnippet(Kind kind,
                                   const Script& script,
                                   intptr_t token_pos,
+                                  bool report_after_token,
                                   const String& message) {
   const char* message_header;
   switch (kind) {
@@ -41,8 +42,11 @@
   if (!script.IsNull()) {
     const String& script_url = String::Handle(script.url());
     if (token_pos >= 0) {
-      intptr_t line, column;
-      script.GetTokenLocation(token_pos, &line, &column);
+      intptr_t line, column, token_len;
+      script.GetTokenLocation(token_pos, &line, &column, &token_len);
+      if (report_after_token) {
+        column += token_len;
+      }
       // Only report the line position if we have the original source. We still
       // need to get a valid column so that we can report the ^ mark below the
       // snippet.
@@ -120,7 +124,7 @@
                        const Script& script, intptr_t token_pos,
                        const char* format, va_list args) {
   const Error& error = Error::Handle(LanguageError::NewFormattedV(
-      prev_error, script, token_pos,
+      prev_error, script, token_pos, Report::AtLocation,
       kError, Heap::kNew,
       format, args));
   LongJump(error);
@@ -129,15 +133,18 @@
 
 
 void Report::MessageF(Kind kind, const Script& script, intptr_t token_pos,
-                      const char* format, ...) {
+                      bool report_after_token, const char* format, ...) {
   va_list args;
   va_start(args, format);
-  MessageV(kind, script, token_pos, format, args);
+  MessageV(kind, script, token_pos, report_after_token, format, args);
   va_end(args);
 }
 
 
-void Report::MessageV(Kind kind, const Script& script, intptr_t token_pos,
+void Report::MessageV(Kind kind,
+                      const Script& script,
+                      intptr_t token_pos,
+                      bool report_after_token,
                       const char* format, va_list args) {
   if (kind < kError) {
     // Reporting a warning.
@@ -147,7 +154,7 @@
     if (!FLAG_warning_as_error) {
       const String& msg = String::Handle(String::NewFormattedV(format, args));
       const String& snippet_msg = String::Handle(
-          PrependSnippet(kind, script, token_pos, msg));
+          PrependSnippet(kind, script, token_pos, report_after_token, msg));
       OS::Print("%s", snippet_msg.ToCString());
       if (kind == kJSWarning) {
         TraceJSWarning(script, token_pos, msg);
@@ -166,7 +173,7 @@
   // Reporting an error (or a warning as error).
   const Error& error = Error::Handle(
       LanguageError::NewFormattedV(Error::Handle(),  // No previous error.
-                                   script, token_pos,
+                                   script, token_pos, report_after_token,
                                    kind, Heap::kNew,
                                    format, args));
   if (kind == kJSWarning) {
@@ -232,7 +239,7 @@
   const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc);
   const Function& caller = Function::Handle(zone, caller_code.function());
   const Script& script = Script::Handle(zone, caller.script());
-  MessageF(kJSWarning, script, token_pos, "%s", msg);
+  MessageF(kJSWarning, script, token_pos, Report::AtLocation, "%s", msg);
 }
 
 
diff --git a/runtime/vm/report.h b/runtime/vm/report.h
index 8cc50a1..1a8d22a 100644
--- a/runtime/vm/report.h
+++ b/runtime/vm/report.h
@@ -28,6 +28,9 @@
     kBailout,
   };
 
+  static const bool AtLocation = false;
+  static const bool AfterLocation = true;
+
   // Report an already formatted error via a long jump.
   static void LongJump(const Error& error);
 
@@ -41,8 +44,10 @@
 
   // Report a warning/jswarning/error/bailout message.
   static void MessageF(Kind kind, const Script& script, intptr_t token_pos,
-                       const char* format, ...) PRINTF_ATTRIBUTE(4, 5);
+                       bool report_after_token,
+                       const char* format, ...) PRINTF_ATTRIBUTE(5, 6);
   static void MessageV(Kind kind, const Script& script, intptr_t token_pos,
+                       bool report_after_token,
                        const char* format, va_list args);
 
   // Support to report Javascript compatibility warnings. Note that a
@@ -67,6 +72,7 @@
   static RawString* PrependSnippet(Kind kind,
                                    const Script& script,
                                    intptr_t token_pos,
+                                   bool report_after_token,
                                    const String& message);
 
  private:
diff --git a/runtime/vm/report_test.cc b/runtime/vm/report_test.cc
index 6338f5b..95e469e 100644
--- a/runtime/vm/report_test.cc
+++ b/runtime/vm/report_test.cc
@@ -21,7 +21,8 @@
   {
     const intptr_t token_pos = 0;
     const char* message = "High Voltage";
-    Report::MessageF(Report::kJSWarning, script, token_pos, "%s", message);
+    Report::MessageF(Report::kJSWarning,
+                     script, token_pos, Report::AtLocation, "%s", message);
     {
       JSONStream js;
       trace_buffer->PrintToJSONStream(&js);
@@ -45,7 +46,8 @@
   {
     const intptr_t token_pos = 1;
     const char* message = "Low Voltage";
-    Report::MessageF(Report::kJSWarning, script, token_pos, "%s", message);
+    Report::MessageF(Report::kJSWarning,
+                     script, token_pos, Report::AtLocation, "%s", message);
   }
   EXPECT_EQ(2, trace_buffer->Length());
   EXPECT_SUBSTRING("{\"type\":\"JSCompatibilityWarning\",\"script\":{\"type\":"
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index f177a10..6e0b1bb 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -17,7 +17,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   const Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 7a81040..5b35317 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -44,13 +44,6 @@
     const String* literal;    // Identifier, number or string literal.
   };
 
-  // Dummy token index reflecting an unknown source position.
-  static const intptr_t kNoSourcePos = -1;
-
-  static bool ValidSourcePosition(intptr_t token_pos) {
-    return (token_pos >= 0) || (token_pos == kNoSourcePos);
-  }
-
   typedef ZoneGrowableArray<TokenDescriptor> GrowableTokenStream;
 
   // Initializes scanner to scan string source.
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 4c52227..9b609c1 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -29,8 +29,8 @@
       loop_level_(loop_level),
       context_level_(LocalScope::kUnitializedContextLevel),
       num_context_variables_(0),
-      begin_token_pos_(Scanner::kNoSourcePos),
-      end_token_pos_(Scanner::kNoSourcePos),
+      begin_token_pos_(Token::kNoSourcePos),
+      end_token_pos_(Token::kNoSourcePos),
       variables_(),
       labels_(),
       referenced_() {
diff --git a/runtime/vm/scopes_test.cc b/runtime/vm/scopes_test.cc
index 3640937..c3ad21d 100644
--- a/runtime/vm/scopes_test.cc
+++ b/runtime/vm/scopes_test.cc
@@ -14,18 +14,18 @@
   const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
   const String& a = String::ZoneHandle(Symbols::New("a"));
   LocalVariable* var_a =
-      new LocalVariable(Scanner::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
   LocalVariable* inner_var_a =
-      new LocalVariable(Scanner::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
   const String& b = String::ZoneHandle(Symbols::New("b"));
   LocalVariable* var_b =
-      new LocalVariable(Scanner::kNoSourcePos, b, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, b, dynamic_type);
   const String& c = String::ZoneHandle(Symbols::New("c"));
   LocalVariable* var_c =
-      new LocalVariable(Scanner::kNoSourcePos, c, dynamic_type);
+      new LocalVariable(Token::kNoSourcePos, c, dynamic_type);
   const String& L = String::ZoneHandle(Symbols::New("L"));
   SourceLabel* label_L =
-      new SourceLabel(Scanner::kNoSourcePos, L, SourceLabel::kFor);
+      new SourceLabel(Token::kNoSourcePos, L, SourceLabel::kFor);
 
   LocalScope* outer_scope = new LocalScope(NULL, 0, 0);
   LocalScope* inner_scope1 = new LocalScope(outer_scope, 0, 0);
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 631a4ec..8991390 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2311,13 +2311,15 @@
 }
 
 
-static const char* kCallSitesStr = "CallSites";
+static const char* kCallSitesStr = "_CallSites";
 static const char* kCoverageStr = "Coverage";
+static const char* kPossibleBreakpointsStr = "PossibleBreakpoints";
 
 
 static const char* const report_enum_names[] = {
   kCallSitesStr,
   kCoverageStr,
+  kPossibleBreakpointsStr,
   NULL,
 };
 
@@ -2346,6 +2348,8 @@
       report_set |= SourceReport::kCallSites;
     } else if (strcmp(*reports, kCoverageStr) == 0) {
       report_set |= SourceReport::kCoverage;
+    } else if (strcmp(*reports, kPossibleBreakpointsStr) == 0) {
+      report_set |= SourceReport::kPossibleBreakpoints;
     }
     reports++;
   }
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index a57296f..a1c1d5c 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -28,6 +28,9 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, use_field_guards);
+
+
 static const int kNumVmIsolateSnapshotReferences = 32 * KB;
 static const int kNumInitialReferencesInFullSnapshot = 160 * KB;
 static const int kNumInitialReferences = 64;
@@ -480,6 +483,8 @@
     AddBackRef(object_id, result, state);
     cls_ ^= ReadObjectImpl(kAsInlinedObject);
     ASSERT(!cls_.IsNull());
+    // Closure instances are handled by Closure::ReadFrom().
+    ASSERT(!cls_.IsClosureClass());
     instance_size = cls_.instance_size();
     ASSERT(instance_size > 0);
     // Allocate the instance and read in all the fields for the object.
@@ -495,8 +500,7 @@
   }
   if (!as_reference) {
     // Read all the individual fields for inlined objects.
-    intptr_t next_field_offset = Class::IsSignatureClass(cls_.raw())
-        ? Closure::InstanceSize() : cls_.next_field_offset();
+    intptr_t next_field_offset = cls_.next_field_offset();
 
     intptr_t type_argument_field_offset = cls_.type_arguments_field_offset();
     ASSERT(next_field_offset > 0);
@@ -509,7 +513,8 @@
       pobj_ = ReadObjectImpl(read_as_reference);
       result->SetFieldAtOffset(offset, pobj_);
       if ((offset != type_argument_field_offset) &&
-          (kind_ == Snapshot::kMessage)) {
+          (kind_ == Snapshot::kMessage) &&
+          FLAG_use_field_guards) {
         // TODO(fschneider): Consider hoisting these lookups out of the loop.
         // This would involve creating a handle, since cls_ can't be reused
         // across the call to ReadObjectImpl.
@@ -781,6 +786,17 @@
 }
 
 
+RawCodeSourceMap* SnapshotReader::NewCodeSourceMap(intptr_t len) {
+  ASSERT(kind_ == Snapshot::kFull);
+  ASSERT_NO_SAFEPOINT_SCOPE();
+  RawCodeSourceMap* obj = reinterpret_cast<RawCodeSourceMap*>(
+      AllocateUninitialized(kCodeSourceMapCid,
+                            CodeSourceMap::InstanceSize(len)));
+  obj->ptr()->length_ = len;
+  return obj;
+}
+
+
 RawStackmap* SnapshotReader::NewStackmap(intptr_t len) {
   ASSERT(kind_ == Snapshot::kFull);
   ASSERT_NO_SAFEPOINT_SCOPE();
@@ -921,6 +937,11 @@
 }
 
 
+RawFunctionType* SnapshotReader::NewFunctionType() {
+  ALLOC_NEW_OBJECT(FunctionType);
+}
+
+
 RawTypeRef* SnapshotReader::NewTypeRef() {
   ALLOC_NEW_OBJECT(TypeRef);
 }
@@ -946,6 +967,11 @@
 }
 
 
+RawClosure* SnapshotReader::NewClosure() {
+  ALLOC_NEW_OBJECT(Closure);
+}
+
+
 RawClosureData* SnapshotReader::NewClosureData() {
   ALLOC_NEW_OBJECT(ClosureData);
 }
@@ -1389,16 +1415,20 @@
 
 void SnapshotReader::ProcessDeferredCanonicalizations() {
   Type& typeobj = Type::Handle();
+  FunctionType& funtypeobj = FunctionType::Handle();
   TypeArguments& typeargs = TypeArguments::Handle();
   Object& newobj = Object::Handle();
   for (intptr_t i = 0; i < backward_references_->length(); i++) {
     BackRefNode& backref = (*backward_references_)[i];
     if (backref.defer_canonicalization()) {
       Object* objref = backref.reference();
-      // Object should either be an abstract type or a type argument.
+      // Object should either be a type, a function type, or a type argument.
       if (objref->IsType()) {
         typeobj ^= objref->raw();
         newobj = typeobj.Canonicalize();
+      } else if (objref->IsFunctionType()) {
+        funtypeobj ^= objref->raw();
+        newobj = funtypeobj.Canonicalize();
       } else {
         ASSERT(objref->IsTypeArguments());
         typeargs ^= objref->raw();
@@ -2321,33 +2351,28 @@
 }
 
 
-RawFunction* SnapshotWriter::IsSerializableClosure(RawClass* cls,
-                                                   RawObject* obj) {
-  if (Class::IsSignatureClass(cls)) {
-    // 'obj' is a closure as its class is a signature class, extract
-    // the function object to check if this closure can be sent in an
-    // isolate message.
-    RawFunction* func = Closure::GetFunction(obj);
-    // We only allow closure of top level methods or static functions in a
-    // class to be sent in isolate messages.
-    if (can_send_any_object() &&
-        Function::IsImplicitStaticClosureFunction(func)) {
-      return func;
-    }
-    // Not a closure of a top level method or static function, throw an
-    // exception as we do not allow these objects to be serialized.
-    HANDLESCOPE(thread());
-
-    const Class& clazz = Class::Handle(zone(), cls);
-    const Function& errorFunc = Function::Handle(zone(), func);
-    ASSERT(!errorFunc.IsNull());
-
-    // All other closures are errors.
-    char* chars = OS::SCreate(thread()->zone(),
-        "Illegal argument in isolate message : (object is a closure - %s %s)",
-        clazz.ToCString(), errorFunc.ToCString());
-    SetWriteException(Exceptions::kArgument, chars);
+RawFunction* SnapshotWriter::IsSerializableClosure(RawClosure* closure) {
+  // Extract the function object to check if this closure
+  // can be sent in an isolate message.
+  RawFunction* func = closure->ptr()->function_;
+  // We only allow closure of top level methods or static functions in a
+  // class to be sent in isolate messages.
+  if (can_send_any_object() &&
+      Function::IsImplicitStaticClosureFunction(func)) {
+    return func;
   }
+  // Not a closure of a top level method or static function, throw an
+  // exception as we do not allow these objects to be serialized.
+  HANDLESCOPE(thread());
+
+  const Function& errorFunc = Function::Handle(zone(), func);
+  ASSERT(!errorFunc.IsNull());
+
+  // All other closures are errors.
+  char* chars = OS::SCreate(thread()->zone(),
+      "Illegal argument in isolate message : (object is a closure - %s)",
+      errorFunc.ToCString());
+  SetWriteException(Exceptions::kArgument, chars);
   return Function::null();
 }
 
@@ -2393,20 +2418,12 @@
                                    intptr_t tags,
                                    intptr_t object_id,
                                    bool as_reference) {
+  // Closure instances are handled by RawClosure::WriteTo().
+  ASSERT(!Class::IsClosureClass(cls));
+
   // Check if the instance has native fields and throw an exception if it does.
   CheckForNativeFields(cls);
 
-  if ((kind() == Snapshot::kMessage) || (kind() == Snapshot::kScript)) {
-    // Check if object is a closure that is serializable, if the object is a
-    // closure that is not serializable this will throw an exception.
-    RawFunction* func = IsSerializableClosure(cls, raw);
-    if (func != Function::null()) {
-      forward_list_->SetState(object_id, kIsSerialized);
-      WriteStaticImplicitClosure(object_id, func, tags);
-      return;
-    }
-  }
-
   // Object is regular dart instance.
   if (as_reference) {
     // Write out the serialization header value for this object.
@@ -2419,8 +2436,7 @@
     // Write out the class information for this object.
     WriteObjectImpl(cls, kAsInlinedObject);
   } else {
-    intptr_t next_field_offset = Class::IsSignatureClass(cls) ?
-        Closure::InstanceSize() :
+    intptr_t next_field_offset =
         cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2;
     ASSERT(next_field_offset > 0);
 
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 8570a06..f635618 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -22,6 +22,7 @@
 class Array;
 class Class;
 class ClassTable;
+class Closure;
 class Code;
 class ExternalTypedData;
 class GrowableObjectArray;
@@ -40,7 +41,9 @@
 class RawBoundedType;
 class RawCapability;
 class RawClass;
+class RawClosure;
 class RawClosureData;
+class RawCodeSourceMap;
 class RawContext;
 class RawContextScope;
 class RawDouble;
@@ -49,6 +52,7 @@
 class RawFloat32x4;
 class RawFloat64x2;
 class RawFunction;
+class RawFunctionType;
 class RawGrowableObjectArray;
 class RawICData;
 class RawImmutableArray;
@@ -412,17 +416,20 @@
   RawDouble* NewDouble(double value);
   RawUnresolvedClass* NewUnresolvedClass();
   RawType* NewType();
+  RawFunctionType* NewFunctionType();
   RawTypeRef* NewTypeRef();
   RawTypeParameter* NewTypeParameter();
   RawBoundedType* NewBoundedType();
   RawMixinAppType* NewMixinAppType();
   RawPatchClass* NewPatchClass();
+  RawClosure* NewClosure();
   RawClosureData* NewClosureData();
   RawRedirectionData* NewRedirectionData();
   RawFunction* NewFunction();
   RawCode* NewCode(intptr_t pointer_offsets_length);
   RawObjectPool* NewObjectPool(intptr_t length);
   RawPcDescriptors* NewPcDescriptors(intptr_t length);
+  RawCodeSourceMap* NewCodeSourceMap(intptr_t length);
   RawLocalVarDescriptors* NewLocalVarDescriptors(intptr_t num_entries);
   RawExceptionHandlers* NewExceptionHandlers(intptr_t num_entries);
   RawStackmap* NewStackmap(intptr_t length);
@@ -558,6 +565,7 @@
   friend class Bigint;
   friend class BoundedType;
   friend class Class;
+  friend class Closure;
   friend class ClosureData;
   friend class Code;
   friend class Context;
@@ -588,6 +596,7 @@
   friend class SubtypeTestCache;
   friend class TokenStream;
   friend class Type;
+  friend class FunctionType;
   friend class TypeArguments;
   friend class TypeParameter;
   friend class TypeRef;
@@ -921,14 +930,17 @@
 
   void WriteFunctionId(RawFunction* func, bool owner_is_class);
 
+  RawFunction* IsSerializableClosure(RawClosure* closure);
+
+  void WriteStaticImplicitClosure(intptr_t object_id,
+                                  RawFunction* func,
+                                  intptr_t tags);
+
  protected:
   bool CheckAndWritePredefinedObject(RawObject* raw);
   bool HandleVMIsolateObject(RawObject* raw);
 
   void WriteClassId(RawClass* cls);
-  void WriteStaticImplicitClosure(intptr_t object_id,
-                                  RawFunction* func,
-                                  intptr_t tags);
   void WriteObjectImpl(RawObject* raw, bool as_reference);
   void WriteMarkedObjectImpl(RawObject* raw,
                              intptr_t tags,
@@ -942,7 +954,6 @@
                     RawTypeArguments* type_arguments,
                     RawObject* data[],
                     bool as_reference);
-  RawFunction* IsSerializableClosure(RawClass* cls, RawObject* obj);
   RawClass* GetFunctionOwner(RawFunction* func);
   void CheckForNativeFields(RawClass* cls);
   void SetWriteException(Exceptions::ExceptionType type, const char* msg);
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 8c08726..93400bb 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -206,6 +206,44 @@
   }
 }
 
+void SourceReport::PrintPossibleBreakpointsData(JSONObject* jsobj,
+                                                const Function& func,
+                                                const Code& code) {
+  const uint8_t kSafepointKind = (RawPcDescriptors::kIcCall |
+                                  RawPcDescriptors::kUnoptStaticCall |
+                                  RawPcDescriptors::kRuntimeCall);
+  const intptr_t begin_pos = func.token_pos();
+  const intptr_t end_pos = func.end_token_pos();
+
+  const PcDescriptors& descriptors = PcDescriptors::Handle(
+      zone(), code.pc_descriptors());
+
+  intptr_t func_length = (end_pos - begin_pos) + 1;
+  GrowableArray<char> possible(func_length);
+  possible.SetLength(func_length);
+  for (int i = 0; i < func_length; i++) {
+    possible[i] = false;
+  }
+
+  PcDescriptors::Iterator iter(descriptors, kSafepointKind);
+  while (iter.MoveNext()) {
+    const intptr_t token_pos = iter.TokenPos();
+    if ((token_pos < begin_pos) || (token_pos > end_pos)) {
+      // Does not correspond to a valid source position.
+      continue;
+    }
+    intptr_t token_offset = token_pos - begin_pos;
+    possible[token_offset] = true;
+  }
+
+  JSONArray bpts(jsobj, "possibleBreakpoints");
+  for (int i = 0; i < func_length; i++) {
+    if (possible[i]) {
+      bpts.AddValue(begin_pos + i);  // Add the token position.
+    }
+  }
+}
+
 
 void SourceReport::PrintScriptTable(JSONArray* scripts) {
   for (int i = 0; i < script_table_entries_.length(); i++) {
@@ -265,6 +303,9 @@
   if (IsReportRequested(kCoverage)) {
     PrintCoverageData(&range, func, code);
   }
+  if (IsReportRequested(kPossibleBreakpoints)) {
+    PrintPossibleBreakpointsData(&range, func, code);
+  }
 }
 
 
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 09c8092..9b03a23 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -18,8 +18,9 @@
 class SourceReport {
  public:
   enum ReportKind {
-    kCallSites = 0x1,
-    kCoverage  = 0x2,
+    kCallSites           = 0x1,
+    kCoverage            = 0x2,
+    kPossibleBreakpoints = 0x4,
   };
 
   enum CompileMode {
@@ -55,6 +56,8 @@
                           const Function& func, const Code& code);
   void PrintCoverageData(JSONObject* jsobj,
                          const Function& func, const Code& code);
+  void PrintPossibleBreakpointsData(JSONObject* jsobj,
+                                    const Function& func, const Code& code);
   void PrintScriptTable(JSONArray* jsarr);
 
   void VisitFunction(JSONArray* jsarr, const Function& func);
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index 0e1bb79..b213a20 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -458,4 +458,49 @@
       buffer);
 }
 
+
+TEST_CASE(SourceReport_PossibleBreakpoints_Simple) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "helper1() {}\n"
+      "main() {\n"
+      "  if (true) {\n"
+      "    helper0();\n"
+      "  } else {\n"
+      "    helper1();\n"
+      "  }\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kPossibleBreakpoints);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // helper0.
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"possibleBreakpoints\":[1,4]},"
+
+      // One range not compiled (helper1).
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":10,\"compiled\":false},"
+
+      // main.
+      "{\"scriptIndex\":0,\"startPos\":12,\"endPos\":39,\"compiled\":true,"
+      "\"possibleBreakpoints\":[13,23,32,39]}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
 }  // namespace dart
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index ad3c995..d4be5b5 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -45,13 +45,13 @@
 
 
 void StubCode::InitOnce() {
-#if !defined(DART_PRECOMPILED)
+#if !defined(DART_PRECOMPILED_RUNTIME)
   // Generate all the stubs.
   Code& code = Code::Handle();
   VM_STUB_CODE_LIST(STUB_CODE_GENERATE);
 #else
   UNREACHABLE();
-#endif  // DART_PRECOMPILED
+#endif  // DART_PRECOMPILED_RUNTIME
 }
 
 
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 711c901..4cf291b 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1804,8 +1804,12 @@
   // R3: instance class id.
   // R4: instance type arguments.
   __ SmiTag(R3);
+  __ CompareImmediate(R3, Smi::RawValue(kClosureCid));
+  __ ldr(R3, FieldAddress(R0, Closure::function_offset()), EQ);
+  // R3: instance class id as Smi or function.
   __ Bind(&loop);
-  __ ldr(R9, Address(R2, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ ldr(R9,
+         Address(R2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
   __ CompareObject(R9, Object::null_object());
   __ b(&not_found, EQ);
   __ cmp(R9, Operand(R3));
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 0585653..5db34dc 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1865,9 +1865,13 @@
   // R3: instance class id.
   // R4: instance type arguments.
   __ SmiTag(R3);
+  __ CompareImmediate(R3, Smi::RawValue(kClosureCid));
+  __ b(&loop, NE);
+  __ LoadFieldFromOffset(R3, R0, Closure::function_offset());
+  // R3: instance class id as Smi or function.
   __ Bind(&loop);
   __ LoadFromOffset(
-      R5, R2, kWordSize * SubtypeTestCache::kInstanceClassId);
+      R5, R2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction);
   __ CompareObject(R5, Object::null_object());
   __ b(&not_found, EQ);
   __ CompareRegisters(R5, R3);
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index eba3949..a64d6f7 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -23,7 +23,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 39aa9e6..36d703e 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -23,7 +23,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index b6302d3..e1e3fff 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1781,8 +1781,14 @@
   // ECX: instance class id.
   // EBX: instance type arguments.
   __ SmiTag(ECX);
+  __ cmpl(ECX, Immediate(Smi::RawValue(kClosureCid)));
+  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+  __ movl(ECX, FieldAddress(EAX, Closure::function_offset()));
+  // ECX: instance class id as Smi or function.
   __ Bind(&loop);
-  __ movl(EDI, Address(EDX, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ movl(EDI,
+          Address(EDX,
+                  kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
   __ cmpl(EDI, raw_null);
   __ j(EQUAL, &not_found, Assembler::kNearJump);
   __ cmpl(EDI, ECX);
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index 1ab200b..fff4bc7 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -23,7 +23,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 58af418..bd6567d 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1943,8 +1943,12 @@
   // T2: Entry start.
   // T7: null.
   __ SmiTag(T0);
+  __ BranchNotEqual(T0, Immediate(Smi::RawValue(kClosureCid)), &loop);
+  __ lw(T0, FieldAddress(A0, Closure::function_offset()));
+  // T0: instance class id as Smi or function.
   __ Bind(&loop);
-  __ lw(T3, Address(T2, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ lw(T3,
+        Address(T2, kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
   __ beq(T3, T7, &not_found);
 
   if (n == 1) {
diff --git a/runtime/vm/stub_code_mips_test.cc b/runtime/vm/stub_code_mips_test.cc
index 512baaf..21e7768 100644
--- a/runtime/vm/stub_code_mips_test.cc
+++ b/runtime/vm/stub_code_mips_test.cc
@@ -23,7 +23,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 39d8dc9..024fbfa 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1841,8 +1841,14 @@
   // R13: instance type arguments.
   Label loop, found, not_found, next_iteration;
   __ SmiTag(R10);
+  __ cmpq(R10, Immediate(Smi::RawValue(kClosureCid)));
+  __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
+  __ movq(R10, FieldAddress(RAX, Closure::function_offset()));
+  // R10: instance class id as Smi or function.
   __ Bind(&loop);
-  __ movq(RDI, Address(RDX, kWordSize * SubtypeTestCache::kInstanceClassId));
+  __ movq(RDI,
+          Address(RDX,
+                  kWordSize * SubtypeTestCache::kInstanceClassIdOrFunction));
   __ cmpq(RDI, R9);
   __ j(EQUAL, &not_found, Assembler::kNearJump);
   __ cmpq(RDI, R10);
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index ff020e7..2716433 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -23,7 +23,7 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Scanner::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 1c40fb5..eae0796 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -55,6 +55,7 @@
   V(_EnumNames, "_enum_names")                                                 \
   V(ExprTemp, ":expr_temp")                                                    \
   V(AnonymousClosure, "<anonymous closure>")                                   \
+  V(AnonymousSignature, "<anonymous signature>")                               \
   V(ImplicitClosure, "<implicit closure>")                                     \
   V(ClosureParameter, ":closure")                                              \
   V(TypeArgumentsParameter, ":type_arguments")                                 \
@@ -135,6 +136,7 @@
   V(Dynamic, "dynamic")                                                        \
   V(UnresolvedClass, "UnresolvedClass")                                        \
   V(Type, "_Type")                                                             \
+  V(FunctionType, "_FunctionType")                                             \
   V(TypeRef, "_TypeRef")                                                       \
   V(TypeParameter, "_TypeParameter")                                           \
   V(BoundedType, "_BoundedType")                                               \
@@ -143,7 +145,7 @@
   V(Patch, "patch")                                                            \
   V(PatchClass, "PatchClass")                                                  \
   V(Function, "Function")                                                      \
-  V(FunctionImpl, "_FunctionImpl")                                             \
+  V(_Closure, "_Closure")                                                      \
   V(FunctionResult, "function result")                                         \
   V(FactoryResult, "factory result")                                           \
   V(ClosureData, "ClosureData")                                                \
@@ -159,6 +161,7 @@
   V(Instructions, "Instructions")                                              \
   V(ObjectPool, "ObjectPool")                                                  \
   V(PcDescriptors, "PcDescriptors")                                            \
+  V(CodeSourceMap, "CodeSourceMap")                                            \
   V(Stackmap, "Stackmap")                                                      \
   V(LocalVarDescriptors, "LocalVarDescriptors")                                \
   V(ExceptionHandlers, "ExceptionHandlers")                                    \
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 64c7127..76d4729 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -80,12 +80,10 @@
   } else if (use_ring_recorder) {
     recorder_ = new TimelineEventRingRecorder();
   }
-  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_);
+  vm_stream_.Init("VM", EnableStreamByDefault("VM"), NULL);
+  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,12 +97,15 @@
   if (FLAG_timeline_dir != NULL) {
     recorder_->WriteTo(FLAG_timeline_dir);
   }
+  // Disable global streams.
+  vm_stream_.set_enabled(false);
+  vm_api_stream_.set_enabled(false);
+#define ISOLATE_TIMELINE_STREAM_DISABLE(name, not_used)                   \
+  stream_##name##_enabled_ = false;
+  ISOLATE_TIMELINE_STREAM_LIST(ISOLATE_TIMELINE_STREAM_DISABLE)
+#undef ISOLATE_TIMELINE_STREAM_DISABLE
   delete recorder_;
   recorder_ = NULL;
-  delete vm_stream_;
-  vm_stream_ = NULL;
-  delete vm_api_stream_;
-  vm_api_stream_ = NULL;
 }
 
 
@@ -120,14 +121,12 @@
 
 
 TimelineStream* Timeline::GetVMStream() {
-  ASSERT(vm_stream_ != NULL);
-  return vm_stream_;
+  return &vm_stream_;
 }
 
 
 TimelineStream* Timeline::GetVMApiStream() {
-  ASSERT(vm_api_stream_ != NULL);
-  return vm_api_stream_;
+  return &vm_api_stream_;
 }
 
 
@@ -164,8 +163,8 @@
 
 
 TimelineEventRecorder* Timeline::recorder_ = NULL;
-TimelineStream* Timeline::vm_stream_ = NULL;
-TimelineStream* Timeline::vm_api_stream_ = NULL;
+TimelineStream Timeline::vm_stream_;
+TimelineStream Timeline::vm_api_stream_;
 
 #define ISOLATE_TIMELINE_STREAM_DEFINE_FLAG(name, enabled_by_default)          \
   bool Timeline::stream_##name##_enabled_ = enabled_by_default;
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index d0c43e0..168956a 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -69,8 +69,8 @@
 
  private:
   static TimelineEventRecorder* recorder_;
-  static TimelineStream* vm_stream_;
-  static TimelineStream* vm_api_stream_;
+  static TimelineStream vm_stream_;
+  static TimelineStream vm_api_stream_;
 
 #define ISOLATE_TIMELINE_STREAM_DECLARE_FLAG(name, not_used)                   \
   static bool stream_##name##_enabled_;
diff --git a/runtime/vm/token.cc b/runtime/vm/token.cc
index 75872e5..504b6d9 100644
--- a/runtime/vm/token.cc
+++ b/runtime/vm/token.cc
@@ -78,4 +78,21 @@
 }
 
 
+const char* ClassifyingTokenPositions::ToCString(intptr_t token_pos) {
+  ASSERT(token_pos < Token::kMinSourcePos);
+  COMPILE_ASSERT(ClassifyingTokenPositions::kPrivate ==
+                 (Token::kNoSourcePos - 1));
+  COMPILE_ASSERT(kLast < kPrivate);
+  switch (token_pos) {
+    case Token::kNoSourcePos: return "NoSource";
+#define DEFINE_CASE(name, value)                                               \
+    case value: return #name;
+    CLASSIFYING_TOKEN_POSITIONS(DEFINE_CASE);
+#undef DEFINE_CASE
+    default:
+      UNIMPLEMENTED();
+      return NULL;
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index a1018f8..39659d9 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -6,6 +6,7 @@
 #define VM_TOKEN_H_
 
 #include "platform/assert.h"
+#include "vm/allocation.h"
 
 namespace dart {
 
@@ -193,9 +194,55 @@
   KW(kWHILE, "while", 0, kKeyword)                                             \
   KW(kWITH, "with", 0, kKeyword) /* == kLastKeyword */
 
-
 class String;
 
+// The token space is organized as follows:
+//
+// Sentinel values start at -1 and move towards negative infinity:
+// kNoSourcePos                -> -1
+// ClassifyingTokenPositions 1 -> -1 - 1
+// ClassifyingTokenPositions N -> -1 - N
+//
+// Synthetically created AstNodes are given real source positions but encoded
+// as negative numbers from [kSmiMin32, -1 - N]. For example:
+//
+// A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
+// A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
+//
+// All other AstNodes are given real source positions encoded as positive
+// integers.
+//
+// This organization allows for ~1 billion token positions.
+//
+// NOTE: While token positions are passed around as an intptr_t they are encoded
+// into the snapshot as an int32_t.
+
+// These token positions are used to classify instructions that can't be
+// directly tied to an actual source position.
+#define CLASSIFYING_TOKEN_POSITIONS(V)                                         \
+    V(Private, -2)                                                             \
+    V(Box, -3)                                                                 \
+    V(ParallelMove, -4)                                                        \
+    V(TempMove, -5)                                                            \
+    V(Constant, -6)                                                            \
+    V(PushArgument, -7)                                                        \
+    V(ControlFlow, -8)                                                         \
+    V(Context, -9)                                                             \
+    V(MethodExtractor, -10)                                                    \
+    V(Last, -11)   // Always keep this at the end.
+
+
+class ClassifyingTokenPositions : public AllStatic {
+ public:
+#define DEFINE_VALUES(name, value)                                             \
+  static const intptr_t k##name = value;
+  CLASSIFYING_TOKEN_POSITIONS(DEFINE_VALUES);
+#undef DEFINE_VALUES
+
+  static const char* ToCString(intptr_t token_pos);
+};
+
+
 class Token {
  public:
 #define T(t, s, p, a) t,
@@ -212,6 +259,78 @@
     kPseudoKeyword   = 1 << 1,
   };
 
+  // Token position constants.
+  static const intptr_t kNoSourcePos = -1;
+  static const intptr_t kMinSourcePos = 0;
+  static const intptr_t kMaxSourcePos =
+      kSmiMax32 - (-ClassifyingTokenPositions::kLast) - 2;
+
+  // Is |token_pos| a classifying sentinel source position?
+  static bool IsClassifying(intptr_t token_pos) {
+    return (token_pos >= ClassifyingTokenPositions::kPrivate) &&
+           (token_pos <= ClassifyingTokenPositions::kLast);
+  }
+
+  // Is |token_pos| a synthetic source position?
+  static bool IsSynthetic(intptr_t token_pos) {
+    if (token_pos >= kMinSourcePos) {
+      return false;
+    }
+    if (token_pos < ClassifyingTokenPositions::kLast) {
+      return true;
+    }
+    return false;
+  }
+
+  // Is |token_pos| the no source position sentinel?
+  static bool IsNoSource(intptr_t token_pos) {
+    return token_pos == kNoSourcePos;
+  }
+
+  // Is |token_pos| a real source position?
+  static bool IsReal(intptr_t token_pos) {
+    return token_pos >= kMinSourcePos;
+  }
+
+  // Is |token_pos| a source position?
+  static bool IsSourcePosition(intptr_t token_pos) {
+    return IsReal(token_pos) || IsNoSource(token_pos) || IsSynthetic(token_pos);
+  }
+
+  // Is |token_pos| a debug pause source position?
+  static bool IsDebugPause(intptr_t token_pos) {
+    return IsReal(token_pos);
+  }
+
+  // Encode |token_pos| into a synthetic source position.
+  static intptr_t ToSynthetic(intptr_t token_pos) {
+    if (IsClassifying(token_pos) || IsNoSource(token_pos)) {
+      return token_pos;
+    }
+    if (IsSynthetic(token_pos)) {
+      return token_pos;
+    }
+    ASSERT(!IsSynthetic(token_pos));
+    const intptr_t value = (ClassifyingTokenPositions::kLast - 1) - token_pos;
+    ASSERT(IsSynthetic(value));
+    ASSERT(value < ClassifyingTokenPositions::kLast);
+    return value;
+  }
+
+  // Decode |token_pos| from a synthetic source position.
+  static intptr_t FromSynthetic(intptr_t token_pos) {
+    if (IsClassifying(token_pos) || IsNoSource(token_pos)) {
+      return token_pos;
+    }
+    if (!IsSynthetic(token_pos)) {
+      return token_pos;
+    }
+    ASSERT(IsSynthetic(token_pos));
+    const intptr_t value = -token_pos + (ClassifyingTokenPositions::kLast - 1);
+    ASSERT(!IsSynthetic(value));
+    return value;
+  }
+
   static const Kind kFirstKeyword = kABSTRACT;
   static const Kind kLastKeyword = kWITH;
   static const int kNumKeywords = kLastKeyword - kFirstKeyword + 1;
@@ -328,7 +447,6 @@
   static const Attribute attributes_[];
 };
 
-
 }  // namespace dart
 
 #endif  // VM_TOKEN_H_
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index b3df320..c686463 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -96,7 +96,7 @@
         }]],
     },
     {
-      'target_name': 'libdart_vm_precompiled',
+      'target_name': 'libdart_vm_precompiled_runtime',
       'type': 'static_library',
       'toolsets':['host', 'target'],
       'includes': [
@@ -112,7 +112,7 @@
         '..',
       ],
       'defines': [
-        'DART_PRECOMPILED',
+        'DART_PRECOMPILED_RUNTIME',
       ],
       'conditions': [
         ['OS=="linux"', {
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index dfed0df..b5ad1e8 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -106,37 +106,61 @@
 // Patch for Expando implementation.
 @patch
 class Expando<T> {
+  static const String _EXPANDO_PROPERTY_NAME = 'expando\$values';
+
+  // Incremented to make unique keys.
+  static int _keyCount = 0;
+
+  // Stores either a JS WeakMap or a "unique" string key.
+  final Object _jsWeakMapOrKey;
+
   @patch
-  Expando([String name]) : this.name = name;
+  Expando([String name])
+      : this.name = name,
+        _jsWeakMapOrKey = JS('bool', 'typeof WeakMap == "function"')
+            ? JS('=Object|Null', 'new WeakMap()')
+            : _createKey();
 
   @patch
   T operator[](Object object) {
-    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
-    return (values == null) ? null : Primitives.getProperty(values, _getKey());
+    if (_jsWeakMapOrKey is! String) {
+      _checkType(object);  // WeakMap doesn't check on reading, only writing.
+      return JS('', '#.get(#)', _jsWeakMapOrKey, object);
+    }
+    return _getFromObject(_jsWeakMapOrKey, object);
   }
 
   @patch
   void operator[]=(Object object, T value) {
+    if (_jsWeakMapOrKey is! String) {
+      JS('void', '#.set(#, #)', _jsWeakMapOrKey, object, value);
+    } else {
+      _setOnObject(_jsWeakMapOrKey, object, value);
+    }
+  }
+
+  static Object _getFromObject(String key, Object object) {
+    var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
+    return (values == null) ? null : Primitives.getProperty(values, key);
+  }
+
+  static void _setOnObject(String key, Object object, Object value) {
     var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
     if (values == null) {
       values = new Object();
       Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values);
     }
-    Primitives.setProperty(values, _getKey(), value);
+    Primitives.setProperty(values, key, value);
   }
 
-  String _getKey() {
-    String key = Primitives.getProperty(this, _KEY_PROPERTY_NAME);
-    if (key == null) {
-      key = "expando\$key\$${_keyCount++}";
-      Primitives.setProperty(this, _KEY_PROPERTY_NAME, key);
+  static String _createKey() => "expando\$key\$${_keyCount++}";
+
+  static _checkType(object) {
+    if (object == null || object is bool || object is num || object is String) {
+      throw new ArgumentError.value(object,
+          "Expandos are not allowed on strings, numbers, booleans or null");
     }
-    return key;
   }
-
-  static const String _KEY_PROPERTY_NAME = 'expando\$key';
-  static const String _EXPANDO_PROPERTY_NAME = 'expando\$values';
-  static int _keyCount = 0;
 }
 
 @patch
@@ -316,20 +340,11 @@
   static int _now() => Primitives.timerTicks();
 }
 
-class _ListConstructorSentinel extends JSInt {
-  const _ListConstructorSentinel();
-}
-
 // Patch for List implementation.
 @patch
 class List<E> {
   @patch
-  factory List([int length = const _ListConstructorSentinel()]) {
-    if (length == const _ListConstructorSentinel()) {
-      return new JSArray<E>.emptyGrowable();
-    }
-    return new JSArray<E>.fixed(length);
-  }
+  factory List([int length]) = JSArray<E>.list;
 
   @patch
   factory List.filled(int length, E fill, {bool growable: false}) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart
index 78e53b1..004127b 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_array.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_array.dart
@@ -4,6 +4,11 @@
 
 part of _interceptors;
 
+class _Growable {
+  const _Growable();
+}
+const _ListConstructorSentinel = const _Growable();
+
 /**
  * The interceptor class for [List]. The compiler recognizes this
  * class as an interceptor, and changes references to [:this:] to
@@ -14,6 +19,16 @@
 
   const JSArray();
 
+  // This factory constructor is the redirection target of the List() factory
+  // constructor. [length] has no type to permit the sentinel value.
+  factory JSArray.list([length = _ListConstructorSentinel]) {
+    if (_ListConstructorSentinel == length) {
+      return new JSArray<E>.emptyGrowable();
+    }
+    return new JSArray<E>.fixed(length);
+  }
+
+
   /**
    * Returns a fresh JavaScript Array, marked as fixed-length.
    *
@@ -21,7 +36,8 @@
    */
   factory JSArray.fixed(int length)  {
     // Explicit type test is necessary to guard against JavaScript conversions
-    // in unchecked mode.
+    // in unchecked mode, and against `new Array(null)` which creates a single
+    // element Array containing `null`.
     if (length is !int) {
       throw new ArgumentError.value(length, "length", "is not an integer");
     }
diff --git a/sdk/lib/async/broadcast_stream_controller.dart b/sdk/lib/async/broadcast_stream_controller.dart
index 6f4ddab..a926f1d 100644
--- a/sdk/lib/async/broadcast_stream_controller.dart
+++ b/sdk/lib/async/broadcast_stream_controller.dart
@@ -23,7 +23,7 @@
   // TODO(lrn): Use the _state field on _ControllerSubscription to
   // also store this state. Requires that the subscription implementation
   // does not assume that it's use of the state integer is the only use.
-  int _eventState;
+  int _eventState = 0;  // Initialized to help dart2js type inference.
 
   _BroadcastSubscriptionLink _next;
   _BroadcastSubscriptionLink _previous;
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 48f968f..709a73d 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -225,7 +225,7 @@
     _Future result = new _Future<T>();
     new Timer(duration, () {
       try {
-        result._complete(computation == null ? null : computation());
+        result._complete(computation?.call());
       } catch (e, s) {
         _completeWithErrorCallback(result, e, s);
       }
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index c2b6c68..510cccb 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -325,6 +325,10 @@
    * two arguments it is called with the stack trace (which could be `null` if
    * the stream itself received an error without stack trace).
    * Otherwise it is called with just the error object.
+   * If [onError] is omitted, any errors on the stream are considered unhandled,
+   * and will be passed to the current [Zone]'s error handler.
+   * By default unhandled async errors are treated
+   * as if they were uncaught top-level errors.
    *
    * If this stream closes, the [onDone] handler is called.
    *
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index c8a2465..cd69f44 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -68,9 +68,16 @@
    * If [sync] is true, the returned stream controller is a
    * [SynchronousStreamController], and must be used with the care
    * and attention necessary to not break the [Stream] contract.
+   * See [Completer.sync] for some explanations on when a synchronous
+   * dispatching can be used.
+   * If in doubt, keep the controller non-sync.
    *
-   * The controller will buffer all incoming events until the subscriber is
-   * registered.
+   * A Stream should be inert until a subscriber starts listening on it (using
+   * the [onListen] callback to start producing events). Streams should not
+   * leak resources (like websockets) when no user ever listens on the stream.
+   *
+   * The controller buffers all incoming events until a subscriber is
+   * registered, but this feature should only be used in rare circumstances.
    *
    * The [onPause] function is called when the stream becomes
    * paused. [onResume] is called when the stream resumed.
@@ -100,6 +107,12 @@
    * The [Stream] returned by [stream] is a broadcast stream.
    * It can be listened to more than once.
    *
+   * A Stream should be inert until a subscriber starts listening on it (using
+   * the [onListen] callback to start producing events). Streams should not
+   * leak resources (like websockets) when no user ever listens on the stream.
+   *
+   * Broadcast streams do not buffer events when there is no listener.
+   *
    * The controller distributes any events to all currently subscribed
    * listeners at the time when [add], [addError] or [close] is called.
    * It is not allowed to call `add`, `addError`, or `close` before a previous
@@ -116,6 +129,9 @@
    * The returned stream controller is a [SynchronousStreamController],
    * and must be used with the care and attention necessary to not break
    * the [Stream] contract.
+   * See [Completer.sync] for some explanations on when a synchronous
+   * dispatching can be used.
+   * If in doubt, keep the controller non-sync.
    *
    * If [sync] is false, the event will always be fired at a later time,
    * after the code adding the event has completed.
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index d84f01b..5cc4d88 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -135,33 +135,21 @@
               Map zoneValues): null
   }) {
     return new ZoneSpecification(
-      handleUncaughtError: handleUncaughtError != null
-                           ? handleUncaughtError
-                           : other.handleUncaughtError,
-      run: run != null ? run : other.run,
-      runUnary: runUnary != null ? runUnary : other.runUnary,
-      runBinary: runBinary != null ? runBinary : other.runBinary,
-      registerCallback: registerCallback != null
-                        ? registerCallback
-                        : other.registerCallback,
-      registerUnaryCallback: registerUnaryCallback != null
-                         ? registerUnaryCallback
-                         : other.registerUnaryCallback,
-      registerBinaryCallback: registerBinaryCallback != null
-                         ? registerBinaryCallback
-                         : other.registerBinaryCallback,
-      errorCallback: errorCallback != null
-                         ? errorCallback
-                         : other.errorCallback,
-      scheduleMicrotask: scheduleMicrotask != null
-                         ? scheduleMicrotask
-                         : other.scheduleMicrotask,
-      createTimer : createTimer != null ? createTimer : other.createTimer,
-      createPeriodicTimer: createPeriodicTimer != null
-                           ? createPeriodicTimer
-                           : other.createPeriodicTimer,
-      print : print != null ? print : other.print,
-      fork: fork != null ? fork : other.fork);
+      handleUncaughtError: handleUncaughtError ?? other.handleUncaughtError,
+      run: run ?? other.run,
+      runUnary: runUnary ?? other.runUnary,
+      runBinary: runBinary ?? other.runBinary,
+      registerCallback: registerCallback ?? other.registerCallback,
+      registerUnaryCallback: registerUnaryCallback ??
+                             other.registerUnaryCallback,
+      registerBinaryCallback: registerBinaryCallback ??
+                              other.registerBinaryCallback,
+      errorCallback: errorCallback ?? other.errorCallback,
+      scheduleMicrotask: scheduleMicrotask ?? other.scheduleMicrotask,
+      createTimer : createTimer ?? other.createTimer,
+      createPeriodicTimer: createPeriodicTimer ?? other.createPeriodicTimer,
+      print : print ?? other.print,
+      fork: fork ?? other.fork);
   }
 
   HandleUncaughtErrorHandler get handleUncaughtError;
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 0d92345..09874c4 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -28,6 +28,10 @@
  *     RegExp exp = new RegExp(r"(\w+)");
  *     String str = "Parse my string";
  *     Iterable<Match> matches = exp.allMatches(str);
+ * 
+ * Note the use of a _raw string_ (a string prefixed with `r`)
+ * in the example above. Use a raw string to treat each character in a string
+ * as a literal character.
  */
 abstract class RegExp implements Pattern {
   /**
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index e4a31aa..a1a5b5d 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -76,6 +76,7 @@
    * Cache the computed return value of [queryParameters].
    */
   Map<String, String> _queryParameters;
+  Map<String, List<String>> _queryParameterLists;
 
   /// Internal non-verifying constructor. Only call with validated arguments.
   Uri._internal(this.scheme,
@@ -116,39 +117,46 @@
    * default port.
    *
    * If any of `userInfo`, `host` or `port` are provided,
-   * the URI will have an autority according to [hasAuthority].
+   * the URI has an autority according to [hasAuthority].
    *
    * The path component is set through either [path] or
-   * [pathSegments]. When [path] is used, it should be a valid URI path,
+   * [pathSegments].
+   * When [path] is used, it should be a valid URI path,
    * but invalid characters, except the general delimiters ':/@[]?#',
    * will be escaped if necessary.
    * When [pathSegments] is used, each of the provided segments
    * is first percent-encoded and then joined using the forward slash
-   * separator. The percent-encoding of the path segments encodes all
+   * separator.
+   *
+   * The percent-encoding of the path segments encodes all
    * characters except for the unreserved characters and the following
    * list of characters: `!$&'()*+,;=:@`. If the other components
-   * calls for an absolute path a leading slash `/` is prepended if
+   * necessitate an absolute path, a leading slash `/` is prepended if
    * not already there.
    *
-   * The query component is set through either [query] or
-   * [queryParameters]. When [query] is used the provided string should
-   * be a valid URI query, but invalid characters other than general delimiters,
+   * The query component is set through either [query] or [queryParameters].
+   * When [query] is used, the provided string should be a valid URI query,
+   * but invalid characters, other than general delimiters,
    * will be escaped if necessary.
    * When [queryParameters] is used the query is built from the
    * provided map. Each key and value in the map is percent-encoded
-   * and joined using equal and ampersand characters. The
-   * percent-encoding of the keys and values encodes all characters
-   * except for the unreserved characters.
+   * and joined using equal and ampersand characters.
+   * A value in the map must be either a string, or an [Iterable] of strings,
+   * where the latter corresponds to multiple values for the same key.
+   *
+   * The percent-encoding of the keys and values encodes all characters
+   * except for the unreserved characters, and replaces spaces with `+`.
    * If `query` is the empty string, it is equivalent to omitting it.
    * To have an actual empty query part,
    * use an empty list for `queryParameters`.
-   * If both `query` and `queryParameters` are omitted or `null`, the
-   * URI will have no query part.
+   *
+   * If both `query` and `queryParameters` are omitted or `null`,
+   * the URI has no query part.
    *
    * The fragment component is set through [fragment].
    * It should be a valid URI fragment, but invalid characters other than
-   * general delimiters, will be escaped if necessary.
-   * If `fragment` is omitted or `null`, the URI will have no fragment part.
+   * general delimiters, are escaped if necessary.
+   * If `fragment` is omitted or `null`, the URI has no fragment part.
    */
   factory Uri({String scheme : "",
                String userInfo : "",
@@ -157,7 +165,7 @@
                String path,
                Iterable<String> pathSegments,
                String query,
-               Map<String, String> queryParameters,
+               Map<String, dynamic> queryParameters,
                String fragment}) {
     scheme = _makeScheme(scheme, 0, _stringOrNullLength(scheme));
     userInfo = _makeUserInfo(userInfo, 0, _stringOrNullLength(userInfo));
@@ -207,7 +215,7 @@
    *
    * The `userInfo`, `host` and `port` components are set from the
    * [authority] argument. If `authority` is `null` or empty,
-   * the created `Uri` will have no authority, and will not be directly usable
+   * the created `Uri` has no authority, and isn't directly usable
    * as an HTTP URL, which must have a non-empty host.
    *
    * The `path` component is set from the [unencodedPath]
@@ -1104,23 +1112,53 @@
    * Returns the URI query split into a map according to the rules
    * specified for FORM post in the [HTML 4.01 specification section
    * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
-   * Each key and value in the returned map has been decoded. If there is no
-   * query the empty map is returned.
+   * Each key and value in the returned map has been decoded.
+   * If there is no query the empty map is returned.
    *
    * Keys in the query string that have no value are mapped to the
    * empty string.
+   * If a key occurs more than once in the query string, it is mapped to
+   * an arbitrary choice of possible value.
+   * The [queryParametersAll] getter can provide a map
+   * that maps keys to all of their values.
    *
-   * The returned map is unmodifiable and will throw [UnsupportedError] on any
-   * calls that would mutate it.
+   * The returned map is unmodifiable.
    */
   Map<String, String> get queryParameters {
     if (_queryParameters == null) {
-      _queryParameters = new UnmodifiableMapView(splitQueryString(query));
+      _queryParameters =
+          new UnmodifiableMapView<String, String>(splitQueryString(query));
     }
     return _queryParameters;
   }
 
   /**
+   * Returns the URI query split into a map according to the rules
+   * specified for FORM post in the [HTML 4.01 specification section
+   * 17.13.4](http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 "HTML 4.01 section 17.13.4").
+   * Each key and value in the returned map has been decoded. If there is no
+   * query the empty map is returned.
+   *
+   * Keys are mapped to lists of their values. If a key occurs only once,
+   * its value is a singleton list. If a key occurs with no value, the
+   * empty string is used as the value for that occurrence.
+   *
+   * The returned map and the lists it contains are unmodifiable.
+   */
+  Map<String, List<String>> get queryParametersAll {
+    if (_queryParameterLists == null) {
+      Map queryParameterLists = _splitQueryStringAll(query);
+      for (var key in queryParameterLists.keys) {
+        queryParameterLists[key] =
+            new List<String>.unmodifiable(queryParameterLists[key]);
+      }
+      _queryParameterLists =
+          new Map<String, List<String>>.unmodifiable(queryParameterLists);
+    }
+    return _queryParameterLists;
+  }
+
+  /**
    * Returns a URI where the path has been normalized.
    *
    * A normalized path does not contain `.` segments or non-leading `..`
@@ -1344,17 +1382,27 @@
     if (query != null) return _normalize(query, start, end, _queryCharTable);
 
     var result = new StringBuffer();
-    var first = true;
-    queryParameters.forEach((key, value) {
-      if (!first) {
-        result.write("&");
-      }
-      first = false;
+    var separator = "";
+
+    void writeParameter(String key, String value) {
+      result.write(separator);
+      separator = "&";
       result.write(Uri.encodeQueryComponent(key));
-      if (value != null && !value.isEmpty) {
+      if (value != null && value.isNotEmpty) {
         result.write("=");
         result.write(Uri.encodeQueryComponent(value));
       }
+    }
+
+    queryParameters.forEach((key, value) {
+      if (value == null || value is String) {
+        writeParameter(key, value);
+      } else {
+        Iterable values = value;
+        for (String value in values) {
+          writeParameter(key, value);
+        }
+      }
     });
     return result.toString();
   }
@@ -2156,6 +2204,46 @@
     });
   }
 
+  static List _createList() => [];
+
+  static Map _splitQueryStringAll(
+      String query, {Encoding encoding: UTF8}) {
+    Map result = {};
+    int i = 0;
+    int start = 0;
+    int equalsIndex = -1;
+
+    void parsePair(int start, int equalsIndex, int end) {
+      String key;
+      String value;
+      if (start == end) return;
+      if (equalsIndex < 0) {
+        key =  _uriDecode(query, start, end, encoding, true);
+        value = "";
+      } else {
+        key = _uriDecode(query, start, equalsIndex, encoding, true);
+        value = _uriDecode(query, equalsIndex + 1, end, encoding, true);
+      }
+      result.putIfAbsent(key, _createList).add(value);
+    }
+
+    const int _equals = 0x3d;
+    const int _ampersand = 0x26;
+    while (i < query.length) {
+      int char = query.codeUnitAt(i);
+      if (char == _equals) {
+        if (equalsIndex < 0) equalsIndex = i;
+      } else if (char == _ampersand) {
+        parsePair(start, equalsIndex, i);
+        start = i + 1;
+        equalsIndex = -1;
+      }
+      i++;
+    }
+    parsePair(start, equalsIndex, i);
+    return result;
+  }
+
   /**
    * Parse the [host] as an IP version 4 (IPv4) address, returning the address
    * as a list of 4 bytes in network byte order (big endian).
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 3ef584b..8d4c3de 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -126,9 +126,9 @@
   '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
   // FIXME: Move these to better locations.
   'DateTime': () => DateTime,
-  'JsObject': () => js.JsObjectImpl,
-  'JsFunction': () => js.JsFunctionImpl,
-  'JsArray': () => js.JsArrayImpl,
+  'JsObject': () => js.JsObject,
+  'JsFunction': () => js.JsFunction,
+  'JsArray': () => js.JsArray,
   'AbstractWorker': () => AbstractWorker,
   'Animation': () => Animation,
   'AnimationEffect': () => AnimationEffect,
@@ -1128,7 +1128,7 @@
   } else if (runtimeType == TemplateElement) {
     // Data binding with a Dart class.
     tag = element.attributes['is'];
-  } else if (runtimeType == js.JsObjectImpl) {
+  } else if (runtimeType == js.JsObject) {
     // It's a Polymer core element (written in JS).
     // Make sure it's an element anything else we can ignore.
     if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
@@ -1141,7 +1141,7 @@
       }
     }
   } else {
-    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
+    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.');
   }
 
   return tag;
@@ -1149,15 +1149,9 @@
 
 /// An abstract class for all DOM objects we wrap in dart:html and related
 ///  libraries.
-///
-/// ** Internal Use Only **
 @Deprecated("Internal Use Only")
-class DartHtmlDomObject {
-
-  /// The underlying JS DOM object.
-  @Deprecated("Internal Use Only")
-  js.JsObject blink_jsObject;
-
+class DartHtmlDomObject extends js.JSObject {
+  DartHtmlDomObject() : super.internal();
 }
 
 @Deprecated("Internal Use Only")
@@ -1173,24 +1167,6 @@
   }
 }
 
-// TODO(terry): Manage JS interop JsFunctions for each listener used for add/
-//              removeEventListener.  These JsFunctions will leak look at
-//              fixing with weak-refs in C++.  The key are the hashcodes of the
-//              user's this (this is needed for futures) and listener function.
-Map<int, Map<int, js.JsFunction>> _knownListeners = {};
-
-@Deprecated("Internal Use Only")
-js.JsFunction wrap_event_listener(theObject, Function listener) {
-  var thisHashCode = theObject.hashCode;
-  var listenerHashCode = identityHashCode(listener);
-
-  _knownListeners.putIfAbsent(thisHashCode, () => new Map<int, js.JsFunction>());
-  _knownListeners[thisHashCode].putIfAbsent(listenerHashCode, () =>
-    new js.JsFunction.withThis((theObject, event) => listener(wrap_jso(event))));
-
-  return _knownListeners[thisHashCode][listenerHashCode];
-}
-
 @Deprecated("Internal Use Only")
 Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
   var result = new Map();
@@ -1279,9 +1255,7 @@
     return new AnchorElement._internalWrap();
   }
 
-  factory AnchorElement._internalWrap() {
-    return new AnchorElement.internal_();
-  }
+  external factory AnchorElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnchorElement.internal_() : super.internal_();
@@ -1474,9 +1448,7 @@
     return new Animation._internalWrap();
   }
 
-  factory Animation._internalWrap() {
-    return new Animation.internal_();
-  }
+  external factory Animation._internalWrap();
 
   @Deprecated("Internal Use Only")
   Animation.internal_() : super.internal_();
@@ -1535,9 +1507,7 @@
     return new AnimationEvent._internalWrap();
   }
 
-  factory AnimationEvent._internalWrap() {
-    return new AnimationEvent.internal_();
-  }
+  external factory AnimationEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimationEvent.internal_() : super.internal_();
@@ -1642,9 +1612,7 @@
     return new AnimationPlayer._internalWrap();
   }
 
-  factory AnimationPlayer._internalWrap() {
-    return new AnimationPlayer.internal_();
-  }
+  external factory AnimationPlayer._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimationPlayer.internal_() : super.internal_();
@@ -1744,9 +1712,7 @@
     return new AnimationPlayerEvent._internalWrap();
   }
 
-  factory AnimationPlayerEvent._internalWrap() {
-    return new AnimationPlayerEvent.internal_();
-  }
+  external factory AnimationPlayerEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimationPlayerEvent.internal_() : super.internal_();
@@ -1916,9 +1882,7 @@
     return new ApplicationCache._internalWrap();
   }
 
-  factory ApplicationCache._internalWrap() {
-    return new ApplicationCache.internal_();
-  }
+  external factory ApplicationCache._internalWrap();
 
   @Deprecated("Internal Use Only")
   ApplicationCache.internal_() : super.internal_();
@@ -2028,9 +1992,7 @@
     return new ApplicationCacheErrorEvent._internalWrap();
   }
 
-  factory ApplicationCacheErrorEvent._internalWrap() {
-    return new ApplicationCacheErrorEvent.internal_();
-  }
+  external factory ApplicationCacheErrorEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ApplicationCacheErrorEvent.internal_() : super.internal_();
@@ -2090,9 +2052,7 @@
     return new AreaElement._internalWrap();
   }
 
-  factory AreaElement._internalWrap() {
-    return new AreaElement.internal_();
-  }
+  external factory AreaElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AreaElement.internal_() : super.internal_();
@@ -2252,9 +2212,7 @@
     return new AudioElement._internalWrap();
   }
 
-  factory AudioElement._internalWrap() {
-    return new AudioElement.internal_();
-  }
+  external factory AudioElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioElement.internal_() : super.internal_();
@@ -2358,9 +2316,7 @@
     return new AudioTrackList._internalWrap();
   }
 
-  factory AudioTrackList._internalWrap() {
-    return new AudioTrackList.internal_();
-  }
+  external factory AudioTrackList._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioTrackList.internal_() : super.internal_();
@@ -2408,9 +2364,7 @@
     return new AutocompleteErrorEvent._internalWrap();
   }
 
-  factory AutocompleteErrorEvent._internalWrap() {
-    return new AutocompleteErrorEvent.internal_();
-  }
+  external factory AutocompleteErrorEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   AutocompleteErrorEvent.internal_() : super.internal_();
@@ -2444,9 +2398,7 @@
     return new BRElement._internalWrap();
   }
 
-  factory BRElement._internalWrap() {
-    return new BRElement.internal_();
-  }
+  external factory BRElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   BRElement.internal_() : super.internal_();
@@ -2517,9 +2469,7 @@
     return new BaseElement._internalWrap();
   }
 
-  factory BaseElement._internalWrap() {
-    return new BaseElement.internal_();
-  }
+  external factory BaseElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   BaseElement.internal_() : super.internal_();
@@ -2569,9 +2519,7 @@
     return new BatteryManager._internalWrap();
   }
 
-  factory BatteryManager._internalWrap() {
-    return new BatteryManager.internal_();
-  }
+  external factory BatteryManager._internalWrap();
 
   @Deprecated("Internal Use Only")
   BatteryManager.internal_() : super.internal_();
@@ -2613,9 +2561,7 @@
     return new BeforeUnloadEvent._internalWrap();
   }
 
-  factory BeforeUnloadEvent._internalWrap() {
-    return new BeforeUnloadEvent.internal_();
-  }
+  external factory BeforeUnloadEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   BeforeUnloadEvent.internal_() : super.internal_();
@@ -2899,9 +2845,7 @@
     return new BodyElement._internalWrap();
   }
 
-  factory BodyElement._internalWrap() {
-    return new BodyElement.internal_();
-  }
+  external factory BodyElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   BodyElement.internal_() : super.internal_();
@@ -3002,9 +2946,7 @@
     return new ButtonElement._internalWrap();
   }
 
-  factory ButtonElement._internalWrap() {
-    return new ButtonElement.internal_();
-  }
+  external factory ButtonElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ButtonElement.internal_() : super.internal_();
@@ -3147,9 +3089,7 @@
     return new CDataSection._internalWrap();
   }
 
-  factory CDataSection._internalWrap() {
-    return new CDataSection.internal_();
-  }
+  external factory CDataSection._internalWrap();
 
   @Deprecated("Internal Use Only")
   CDataSection.internal_() : super.internal_();
@@ -3305,9 +3245,7 @@
     return new CanvasElement._internalWrap();
   }
 
-  factory CanvasElement._internalWrap() {
-    return new CanvasElement.internal_();
-  }
+  external factory CanvasElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   CanvasElement.internal_() : super.internal_();
@@ -4377,9 +4315,7 @@
     return new CharacterData._internalWrap();
   }
 
-  factory CharacterData._internalWrap() {
-    return new CharacterData.internal_();
-  }
+  external factory CharacterData._internalWrap();
 
   @Deprecated("Internal Use Only")
   CharacterData.internal_() : super.internal_();
@@ -4483,9 +4419,7 @@
     return new CircularGeofencingRegion._internalWrap();
   }
 
-  factory CircularGeofencingRegion._internalWrap() {
-    return new CircularGeofencingRegion.internal_();
-  }
+  external factory CircularGeofencingRegion._internalWrap();
 
   @Deprecated("Internal Use Only")
   CircularGeofencingRegion.internal_() : super.internal_();
@@ -4536,9 +4470,7 @@
     return new CloseEvent._internalWrap();
   }
 
-  factory CloseEvent._internalWrap() {
-    return new CloseEvent.internal_();
-  }
+  external factory CloseEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   CloseEvent.internal_() : super.internal_();
@@ -4583,9 +4515,7 @@
     return new Comment._internalWrap();
   }
 
-  factory Comment._internalWrap() {
-    return new Comment.internal_();
-  }
+  external factory Comment._internalWrap();
 
   @Deprecated("Internal Use Only")
   Comment.internal_() : super.internal_();
@@ -4622,9 +4552,7 @@
     return new CompositionEvent._internalWrap();
   }
 
-  factory CompositionEvent._internalWrap() {
-    return new CompositionEvent.internal_();
-  }
+  external factory CompositionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   CompositionEvent.internal_() : super.internal_();
@@ -4673,9 +4601,7 @@
     return new Console._internalWrap();
   }
 
-  factory Console._internalWrap() {
-    return new Console.internal_();
-  }
+  external factory Console._internalWrap();
 
   @Deprecated("Internal Use Only")
   Console.internal_() : super.internal_();
@@ -4858,9 +4784,7 @@
     return new ContentElement._internalWrap();
   }
 
-  factory ContentElement._internalWrap() {
-    return new ContentElement.internal_();
-  }
+  external factory ContentElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ContentElement.internal_() : super.internal_();
@@ -5207,9 +5131,7 @@
     return new CssCharsetRule._internalWrap();
   }
 
-  factory CssCharsetRule._internalWrap() {
-    return new CssCharsetRule.internal_();
-  }
+  external factory CssCharsetRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssCharsetRule.internal_() : super.internal_();
@@ -5247,9 +5169,7 @@
     return new CssFilterRule._internalWrap();
   }
 
-  factory CssFilterRule._internalWrap() {
-    return new CssFilterRule.internal_();
-  }
+  external factory CssFilterRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssFilterRule.internal_() : super.internal_();
@@ -5279,9 +5199,7 @@
     return new CssFontFaceRule._internalWrap();
   }
 
-  factory CssFontFaceRule._internalWrap() {
-    return new CssFontFaceRule.internal_();
-  }
+  external factory CssFontFaceRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssFontFaceRule.internal_() : super.internal_();
@@ -5311,9 +5229,7 @@
     return new CssImportRule._internalWrap();
   }
 
-  factory CssImportRule._internalWrap() {
-    return new CssImportRule.internal_();
-  }
+  external factory CssImportRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssImportRule.internal_() : super.internal_();
@@ -5352,9 +5268,7 @@
     return new CssKeyframeRule._internalWrap();
   }
 
-  factory CssKeyframeRule._internalWrap() {
-    return new CssKeyframeRule.internal_();
-  }
+  external factory CssKeyframeRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssKeyframeRule.internal_() : super.internal_();
@@ -5396,9 +5310,7 @@
     return new CssKeyframesRule._internalWrap();
   }
 
-  factory CssKeyframesRule._internalWrap() {
-    return new CssKeyframesRule.internal_();
-  }
+  external factory CssKeyframesRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssKeyframesRule.internal_() : super.internal_();
@@ -5459,9 +5371,7 @@
     return new CssMediaRule._internalWrap();
   }
 
-  factory CssMediaRule._internalWrap() {
-    return new CssMediaRule.internal_();
-  }
+  external factory CssMediaRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssMediaRule.internal_() : super.internal_();
@@ -5503,9 +5413,7 @@
     return new CssPageRule._internalWrap();
   }
 
-  factory CssPageRule._internalWrap() {
-    return new CssPageRule.internal_();
-  }
+  external factory CssPageRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssPageRule.internal_() : super.internal_();
@@ -8940,9 +8848,7 @@
     return new CssStyleRule._internalWrap();
   }
 
-  factory CssStyleRule._internalWrap() {
-    return new CssStyleRule.internal_();
-  }
+  external factory CssStyleRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssStyleRule.internal_() : super.internal_();
@@ -8980,9 +8886,7 @@
     return new CssStyleSheet._internalWrap();
   }
 
-  factory CssStyleSheet._internalWrap() {
-    return new CssStyleSheet.internal_();
-  }
+  external factory CssStyleSheet._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssStyleSheet.internal_() : super.internal_();
@@ -9044,9 +8948,7 @@
     return new CssSupportsRule._internalWrap();
   }
 
-  factory CssSupportsRule._internalWrap() {
-    return new CssSupportsRule.internal_();
-  }
+  external factory CssSupportsRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssSupportsRule.internal_() : super.internal_();
@@ -9089,9 +8991,7 @@
     return new CssViewportRule._internalWrap();
   }
 
-  factory CssViewportRule._internalWrap() {
-    return new CssViewportRule.internal_();
-  }
+  external factory CssViewportRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   CssViewportRule.internal_() : super.internal_();
@@ -9155,9 +9055,7 @@
     return new CustomEvent._internalWrap();
   }
 
-  factory CustomEvent._internalWrap() {
-    return new CustomEvent.internal_();
-  }
+  external factory CustomEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   CustomEvent.internal_() : super.internal_();
@@ -9195,9 +9093,7 @@
     return new DListElement._internalWrap();
   }
 
-  factory DListElement._internalWrap() {
-    return new DListElement.internal_();
-  }
+  external factory DListElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DListElement.internal_() : super.internal_();
@@ -9237,9 +9133,7 @@
     return new DataListElement._internalWrap();
   }
 
-  factory DataListElement._internalWrap() {
-    return new DataListElement.internal_();
-  }
+  external factory DataListElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DataListElement.internal_() : super.internal_();
@@ -9524,9 +9418,7 @@
     return new DedicatedWorkerGlobalScope._internalWrap();
   }
 
-  factory DedicatedWorkerGlobalScope._internalWrap() {
-    return new DedicatedWorkerGlobalScope.internal_();
-  }
+  external factory DedicatedWorkerGlobalScope._internalWrap();
 
   @Deprecated("Internal Use Only")
   DedicatedWorkerGlobalScope.internal_() : super.internal_();
@@ -9688,9 +9580,7 @@
     return new DetailsElement._internalWrap();
   }
 
-  factory DetailsElement._internalWrap() {
-    return new DetailsElement.internal_();
-  }
+  external factory DetailsElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DetailsElement.internal_() : super.internal_();
@@ -9777,9 +9667,7 @@
     return new DeviceLightEvent._internalWrap();
   }
 
-  factory DeviceLightEvent._internalWrap() {
-    return new DeviceLightEvent.internal_();
-  }
+  external factory DeviceLightEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   DeviceLightEvent.internal_() : super.internal_();
@@ -9812,9 +9700,7 @@
     return new DeviceMotionEvent._internalWrap();
   }
 
-  factory DeviceMotionEvent._internalWrap() {
-    return new DeviceMotionEvent.internal_();
-  }
+  external factory DeviceMotionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   DeviceMotionEvent.internal_() : super.internal_();
@@ -9869,9 +9755,7 @@
     return new DeviceOrientationEvent._internalWrap();
   }
 
-  factory DeviceOrientationEvent._internalWrap() {
-    return new DeviceOrientationEvent.internal_();
-  }
+  external factory DeviceOrientationEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   DeviceOrientationEvent.internal_() : super.internal_();
@@ -9961,9 +9845,7 @@
     return new DialogElement._internalWrap();
   }
 
-  factory DialogElement._internalWrap() {
-    return new DialogElement.internal_();
-  }
+  external factory DialogElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DialogElement.internal_() : super.internal_();
@@ -10061,9 +9943,7 @@
     return new DirectoryEntry._internalWrap();
   }
 
-  factory DirectoryEntry._internalWrap() {
-    return new DirectoryEntry.internal_();
-  }
+  external factory DirectoryEntry._internalWrap();
 
   @Deprecated("Internal Use Only")
   DirectoryEntry.internal_() : super.internal_();
@@ -10234,9 +10114,7 @@
     return new DivElement._internalWrap();
   }
 
-  factory DivElement._internalWrap() {
-    return new DivElement.internal_();
-  }
+  external factory DivElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DivElement.internal_() : super.internal_();
@@ -10319,9 +10197,7 @@
     return new Document._internalWrap();
   }
 
-  factory Document._internalWrap() {
-    return new Document.internal_();
-  }
+  external factory Document._internalWrap();
 
   @Deprecated("Internal Use Only")
   Document.internal_() : super.internal_();
@@ -11258,9 +11134,7 @@
     return new DocumentFragment._internalWrap();
   }
 
-  factory DocumentFragment._internalWrap() {
-    return new DocumentFragment.internal_();
-  }
+  external factory DocumentFragment._internalWrap();
 
   @Deprecated("Internal Use Only")
   DocumentFragment.internal_() : super.internal_();
@@ -11390,12 +11264,7 @@
     return new DomException._internalWrap();
   }
 
-  @Deprecated("Internal Use Only")
-  js.JsObject blink_jsObject;
-
-  factory DomException._internalWrap() {
-    return new DomException.internal_();
-  }
+  external factory DomException._internalWrap();
 
   @Deprecated("Internal Use Only")
   DomException.internal_() { }
@@ -11539,9 +11408,7 @@
     return new DomMatrix._internalWrap();
   }
 
-  factory DomMatrix._internalWrap() {
-    return new DomMatrix.internal_();
-  }
+  external factory DomMatrix._internalWrap();
 
   @Deprecated("Internal Use Only")
   DomMatrix.internal_() : super.internal_();
@@ -12122,9 +11989,7 @@
     return new DomPoint._internalWrap();
   }
 
-  factory DomPoint._internalWrap() {
-    return new DomPoint.internal_();
-  }
+  external factory DomPoint._internalWrap();
 
   @Deprecated("Internal Use Only")
   DomPoint.internal_() : super.internal_();
@@ -12411,9 +12276,7 @@
     return new DomSettableTokenList._internalWrap();
   }
 
-  factory DomSettableTokenList._internalWrap() {
-    return new DomSettableTokenList.internal_();
-  }
+  external factory DomSettableTokenList._internalWrap();
 
   @Deprecated("Internal Use Only")
   DomSettableTokenList.internal_() : super.internal_();
@@ -15593,9 +15456,7 @@
     return new Element._internalWrap();
   }
 
-  factory Element._internalWrap() {
-    return new Element.internal_();
-  }
+  external factory Element._internalWrap();
 
   @Deprecated("Internal Use Only")
   Element.internal_() : super.internal_();
@@ -16481,9 +16342,7 @@
     return new EmbedElement._internalWrap();
   }
 
-  factory EmbedElement._internalWrap() {
-    return new EmbedElement.internal_();
-  }
+  external factory EmbedElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   EmbedElement.internal_() : super.internal_();
@@ -16770,9 +16629,7 @@
     return new ErrorEvent._internalWrap();
   }
 
-  factory ErrorEvent._internalWrap() {
-    return new ErrorEvent.internal_();
-  }
+  external factory ErrorEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ErrorEvent.internal_() : super.internal_();
@@ -17060,9 +16917,7 @@
     return new EventSource._internalWrap();
   }
 
-  factory EventSource._internalWrap() {
-    return new EventSource.internal_();
-  }
+  external factory EventSource._internalWrap();
 
   @Deprecated("Internal Use Only")
   EventSource.internal_() : super.internal_();
@@ -17257,11 +17112,11 @@
 
   void _addEventListener([String type, EventListener listener, bool useCapture]) {
     if (useCapture != null) {
-      _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(unwrap_jso(this), type, wrap_event_listener(this, listener), useCapture);
+      _blink.BlinkEventTarget.instance.addEventListener_Callback_3_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(listener)), useCapture);
       return;
     }
     if (listener != null) {
-      _blink.BlinkEventTarget.instance.addEventListener_Callback_2_(unwrap_jso(this), type, wrap_event_listener(this, listener));
+      _blink.BlinkEventTarget.instance.addEventListener_Callback_2_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(listener)));
       return;
     }
     if (type != null) {
@@ -17278,11 +17133,11 @@
   
   void _removeEventListener([String type, EventListener listener, bool useCapture]) {
     if (useCapture != null) {
-      _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(unwrap_jso(this), type, _knownListeners[this.hashCode][identityHashCode(listener)], useCapture);
+      _blink.BlinkEventTarget.instance.removeEventListener_Callback_3_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(listener)), useCapture);
       return;
     }
     if (listener != null) {
-      _blink.BlinkEventTarget.instance.removeEventListener_Callback_2_(unwrap_jso(this), type, _knownListeners[this.hashCode][identityHashCode(listener)]);
+      _blink.BlinkEventTarget.instance.removeEventListener_Callback_2_(unwrap_jso(this), type, unwrap_jso(js.allowInterop(listener)));
       return;
     }
     if (type != null) {
@@ -17314,9 +17169,7 @@
     return new ExtendableEvent._internalWrap();
   }
 
-  factory ExtendableEvent._internalWrap() {
-    return new ExtendableEvent.internal_();
-  }
+  external factory ExtendableEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ExtendableEvent.internal_() : super.internal_();
@@ -17354,9 +17207,7 @@
     return new FederatedCredential._internalWrap();
   }
 
-  factory FederatedCredential._internalWrap() {
-    return new FederatedCredential.internal_();
-  }
+  external factory FederatedCredential._internalWrap();
 
   @Deprecated("Internal Use Only")
   FederatedCredential.internal_() : super.internal_();
@@ -17388,9 +17239,7 @@
     return new FetchEvent._internalWrap();
   }
 
-  factory FetchEvent._internalWrap() {
-    return new FetchEvent.internal_();
-  }
+  external factory FetchEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   FetchEvent.internal_() : super.internal_();
@@ -17436,9 +17285,7 @@
     return new FieldSetElement._internalWrap();
   }
 
-  factory FieldSetElement._internalWrap() {
-    return new FieldSetElement.internal_();
-  }
+  external factory FieldSetElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FieldSetElement.internal_() : super.internal_();
@@ -17518,9 +17365,7 @@
     return new File._internalWrap();
   }
 
-  factory File._internalWrap() {
-    return new File.internal_();
-  }
+  external factory File._internalWrap();
 
   @Deprecated("Internal Use Only")
   File.internal_() : super.internal_();
@@ -17580,9 +17425,7 @@
     return new FileEntry._internalWrap();
   }
 
-  factory FileEntry._internalWrap() {
-    return new FileEntry.internal_();
-  }
+  external factory FileEntry._internalWrap();
 
   @Deprecated("Internal Use Only")
   FileEntry.internal_() : super.internal_();
@@ -17644,9 +17487,7 @@
     return new FileError._internalWrap();
   }
 
-  factory FileError._internalWrap() {
-    return new FileError.internal_();
-  }
+  external factory FileError._internalWrap();
 
   @Deprecated("Internal Use Only")
   FileError.internal_() : super.internal_();
@@ -17882,9 +17723,7 @@
     return new FileReader._internalWrap();
   }
 
-  factory FileReader._internalWrap() {
-    return new FileReader.internal_();
-  }
+  external factory FileReader._internalWrap();
 
   @Deprecated("Internal Use Only")
   FileReader.internal_() : super.internal_();
@@ -18136,9 +17975,7 @@
     return new FileWriter._internalWrap();
   }
 
-  factory FileWriter._internalWrap() {
-    return new FileWriter.internal_();
-  }
+  external factory FileWriter._internalWrap();
 
   @Deprecated("Internal Use Only")
   FileWriter.internal_() : super.internal_();
@@ -18249,9 +18086,7 @@
     return new FocusEvent._internalWrap();
   }
 
-  factory FocusEvent._internalWrap() {
-    return new FocusEvent.internal_();
-  }
+  external factory FocusEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   FocusEvent.internal_() : super.internal_();
@@ -18424,9 +18259,7 @@
     return new FontFaceSet._internalWrap();
   }
 
-  factory FontFaceSet._internalWrap() {
-    return new FontFaceSet.internal_();
-  }
+  external factory FontFaceSet._internalWrap();
 
   @Deprecated("Internal Use Only")
   FontFaceSet.internal_() : super.internal_();
@@ -18509,9 +18342,7 @@
     return new FontFaceSetLoadEvent._internalWrap();
   }
 
-  factory FontFaceSetLoadEvent._internalWrap() {
-    return new FontFaceSetLoadEvent.internal_();
-  }
+  external factory FontFaceSetLoadEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   FontFaceSetLoadEvent.internal_() : super.internal_();
@@ -18597,9 +18428,7 @@
     return new FormElement._internalWrap();
   }
 
-  factory FormElement._internalWrap() {
-    return new FormElement.internal_();
-  }
+  external factory FormElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FormElement.internal_() : super.internal_();
@@ -18837,9 +18666,7 @@
     return new GamepadEvent._internalWrap();
   }
 
-  factory GamepadEvent._internalWrap() {
-    return new GamepadEvent.internal_();
-  }
+  external factory GamepadEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   GamepadEvent.internal_() : super.internal_();
@@ -19662,9 +19489,7 @@
     return new HRElement._internalWrap();
   }
 
-  factory HRElement._internalWrap() {
-    return new HRElement.internal_();
-  }
+  external factory HRElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   HRElement.internal_() : super.internal_();
@@ -19719,9 +19544,7 @@
     return new HashChangeEvent._internalWrap();
   }
 
-  factory HashChangeEvent._internalWrap() {
-    return new HashChangeEvent.internal_();
-  }
+  external factory HashChangeEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   HashChangeEvent.internal_() : super.internal_();
@@ -19766,9 +19589,7 @@
     return new HeadElement._internalWrap();
   }
 
-  factory HeadElement._internalWrap() {
-    return new HeadElement.internal_();
-  }
+  external factory HeadElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   HeadElement.internal_() : super.internal_();
@@ -19894,9 +19715,7 @@
     return new HeadingElement._internalWrap();
   }
 
-  factory HeadingElement._internalWrap() {
-    return new HeadingElement.internal_();
-  }
+  external factory HeadingElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   HeadingElement.internal_() : super.internal_();
@@ -20086,9 +19905,7 @@
     return new HtmlDocument._internalWrap();
   }
 
-  factory HtmlDocument._internalWrap() {
-    return new HtmlDocument.internal_();
-  }
+  external factory HtmlDocument._internalWrap();
 
   @Deprecated("Internal Use Only")
   HtmlDocument.internal_() : super.internal_();
@@ -20888,9 +20705,7 @@
     return new HtmlElement._internalWrap();
   }
 
-  factory HtmlElement._internalWrap() {
-    return new HtmlElement.internal_();
-  }
+  external factory HtmlElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   HtmlElement.internal_() : super.internal_();
@@ -21309,9 +21124,7 @@
     return new HtmlFormControlsCollection._internalWrap();
   }
 
-  factory HtmlFormControlsCollection._internalWrap() {
-    return new HtmlFormControlsCollection.internal_();
-  }
+  external factory HtmlFormControlsCollection._internalWrap();
 
   @Deprecated("Internal Use Only")
   HtmlFormControlsCollection.internal_() : super.internal_();
@@ -21345,9 +21158,7 @@
     return new HtmlHtmlElement._internalWrap();
   }
 
-  factory HtmlHtmlElement._internalWrap() {
-    return new HtmlHtmlElement.internal_();
-  }
+  external factory HtmlHtmlElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   HtmlHtmlElement.internal_() : super.internal_();
@@ -21379,9 +21190,7 @@
     return new HtmlOptionsCollection._internalWrap();
   }
 
-  factory HtmlOptionsCollection._internalWrap() {
-    return new HtmlOptionsCollection.internal_();
-  }
+  external factory HtmlOptionsCollection._internalWrap();
 
   @Deprecated("Internal Use Only")
   HtmlOptionsCollection.internal_() : super.internal_();
@@ -21791,9 +21600,7 @@
     return new HttpRequest._internalWrap();
   }
 
-  factory HttpRequest._internalWrap() {
-    return new HttpRequest.internal_();
-  }
+  external factory HttpRequest._internalWrap();
 
   @Deprecated("Internal Use Only")
   HttpRequest.internal_() : super.internal_();
@@ -22204,9 +22011,7 @@
     return new HttpRequestEventTarget._internalWrap();
   }
 
-  factory HttpRequestEventTarget._internalWrap() {
-    return new HttpRequestEventTarget.internal_();
-  }
+  external factory HttpRequestEventTarget._internalWrap();
 
   @Deprecated("Internal Use Only")
   HttpRequestEventTarget.internal_() : super.internal_();
@@ -22284,9 +22089,7 @@
     return new HttpRequestUpload._internalWrap();
   }
 
-  factory HttpRequestUpload._internalWrap() {
-    return new HttpRequestUpload.internal_();
-  }
+  external factory HttpRequestUpload._internalWrap();
 
   @Deprecated("Internal Use Only")
   HttpRequestUpload.internal_() : super.internal_();
@@ -22316,9 +22119,7 @@
     return new IFrameElement._internalWrap();
   }
 
-  factory IFrameElement._internalWrap() {
-    return new IFrameElement.internal_();
-  }
+  external factory IFrameElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   IFrameElement.internal_() : super.internal_();
@@ -22527,9 +22328,7 @@
     return new ImageElement._internalWrap();
   }
 
-  factory ImageElement._internalWrap() {
-    return new ImageElement.internal_();
-  }
+  external factory ImageElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ImageElement.internal_() : super.internal_();
@@ -22729,9 +22528,7 @@
     return new InputElement._internalWrap();
   }
 
-  factory InputElement._internalWrap() {
-    return new InputElement.internal_();
-  }
+  external factory InputElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   InputElement.internal_() : super.internal_();
@@ -23751,9 +23548,7 @@
     return new InputMethodContext._internalWrap();
   }
 
-  factory InputMethodContext._internalWrap() {
-    return new InputMethodContext.internal_();
-  }
+  external factory InputMethodContext._internalWrap();
 
   @Deprecated("Internal Use Only")
   InputMethodContext.internal_() : super.internal_();
@@ -23803,9 +23598,7 @@
     return new InstallEvent._internalWrap();
   }
 
-  factory InstallEvent._internalWrap() {
-    return new InstallEvent.internal_();
-  }
+  external factory InstallEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   InstallEvent.internal_() : super.internal_();
@@ -23857,9 +23650,7 @@
     return new KeyboardEvent._internalWrap();
   }
 
-  factory KeyboardEvent._internalWrap() {
-    return new KeyboardEvent.internal_();
-  }
+  external factory KeyboardEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   KeyboardEvent.internal_() : super.internal_();
@@ -23958,9 +23749,7 @@
     return new KeygenElement._internalWrap();
   }
 
-  factory KeygenElement._internalWrap() {
-    return new KeygenElement.internal_();
-  }
+  external factory KeygenElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   KeygenElement.internal_() : super.internal_();
@@ -24072,9 +23861,7 @@
     return new LIElement._internalWrap();
   }
 
-  factory LIElement._internalWrap() {
-    return new LIElement.internal_();
-  }
+  external factory LIElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LIElement.internal_() : super.internal_();
@@ -24118,9 +23905,7 @@
     return new LabelElement._internalWrap();
   }
 
-  factory LabelElement._internalWrap() {
-    return new LabelElement.internal_();
-  }
+  external factory LabelElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LabelElement.internal_() : super.internal_();
@@ -24172,9 +23957,7 @@
     return new LegendElement._internalWrap();
   }
 
-  factory LegendElement._internalWrap() {
-    return new LegendElement.internal_();
-  }
+  external factory LegendElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LegendElement.internal_() : super.internal_();
@@ -24212,9 +23995,7 @@
     return new LinkElement._internalWrap();
   }
 
-  factory LinkElement._internalWrap() {
-    return new LinkElement.internal_();
-  }
+  external factory LinkElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LinkElement.internal_() : super.internal_();
@@ -24340,9 +24121,7 @@
     return new LocalCredential._internalWrap();
   }
 
-  factory LocalCredential._internalWrap() {
-    return new LocalCredential.internal_();
-  }
+  external factory LocalCredential._internalWrap();
 
   @Deprecated("Internal Use Only")
   LocalCredential.internal_() : super.internal_();
@@ -24518,9 +24297,7 @@
     return new MapElement._internalWrap();
   }
 
-  factory MapElement._internalWrap() {
-    return new MapElement.internal_();
-  }
+  external factory MapElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MapElement.internal_() : super.internal_();
@@ -24572,9 +24349,7 @@
     return new MediaController._internalWrap();
   }
 
-  factory MediaController._internalWrap() {
-    return new MediaController.internal_();
-  }
+  external factory MediaController._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaController.internal_() : super.internal_();
@@ -24793,9 +24568,7 @@
     return new MediaElement._internalWrap();
   }
 
-  factory MediaElement._internalWrap() {
-    return new MediaElement.internal_();
-  }
+  external factory MediaElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaElement.internal_() : super.internal_();
@@ -25279,9 +25052,7 @@
     return new MediaKeyEvent._internalWrap();
   }
 
-  factory MediaKeyEvent._internalWrap() {
-    return new MediaKeyEvent.internal_();
-  }
+  external factory MediaKeyEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaKeyEvent.internal_() : super.internal_();
@@ -25337,9 +25108,7 @@
     return new MediaKeyMessageEvent._internalWrap();
   }
 
-  factory MediaKeyMessageEvent._internalWrap() {
-    return new MediaKeyMessageEvent.internal_();
-  }
+  external factory MediaKeyMessageEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaKeyMessageEvent.internal_() : super.internal_();
@@ -25375,9 +25144,7 @@
     return new MediaKeyNeededEvent._internalWrap();
   }
 
-  factory MediaKeyNeededEvent._internalWrap() {
-    return new MediaKeyNeededEvent.internal_();
-  }
+  external factory MediaKeyNeededEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaKeyNeededEvent.internal_() : super.internal_();
@@ -25414,9 +25181,7 @@
     return new MediaKeySession._internalWrap();
   }
 
-  factory MediaKeySession._internalWrap() {
-    return new MediaKeySession.internal_();
-  }
+  external factory MediaKeySession._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaKeySession.internal_() : super.internal_();
@@ -25596,9 +25361,7 @@
     return new MediaQueryList._internalWrap();
   }
 
-  factory MediaQueryList._internalWrap() {
-    return new MediaQueryList.internal_();
-  }
+  external factory MediaQueryList._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaQueryList.internal_() : super.internal_();
@@ -25646,9 +25409,7 @@
     return new MediaQueryListEvent._internalWrap();
   }
 
-  factory MediaQueryListEvent._internalWrap() {
-    return new MediaQueryListEvent.internal_();
-  }
+  external factory MediaQueryListEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaQueryListEvent.internal_() : super.internal_();
@@ -25694,9 +25455,7 @@
     return new MediaSource._internalWrap();
   }
 
-  factory MediaSource._internalWrap() {
-    return new MediaSource.internal_();
-  }
+  external factory MediaSource._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaSource.internal_() : super.internal_();
@@ -25811,9 +25570,7 @@
     return new MediaStream._internalWrap();
   }
 
-  factory MediaStream._internalWrap() {
-    return new MediaStream.internal_();
-  }
+  external factory MediaStream._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStream.internal_() : super.internal_();
@@ -25913,9 +25670,7 @@
     return new MediaStreamEvent._internalWrap();
   }
 
-  factory MediaStreamEvent._internalWrap() {
-    return new MediaStreamEvent.internal_();
-  }
+  external factory MediaStreamEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStreamEvent.internal_() : super.internal_();
@@ -25981,9 +25736,7 @@
     return new MediaStreamTrack._internalWrap();
   }
 
-  factory MediaStreamTrack._internalWrap() {
-    return new MediaStreamTrack.internal_();
-  }
+  external factory MediaStreamTrack._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStreamTrack.internal_() : super.internal_();
@@ -26078,9 +25831,7 @@
     return new MediaStreamTrackEvent._internalWrap();
   }
 
-  factory MediaStreamTrackEvent._internalWrap() {
-    return new MediaStreamTrackEvent.internal_();
-  }
+  external factory MediaStreamTrackEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStreamTrackEvent.internal_() : super.internal_();
@@ -26179,9 +25930,7 @@
     return new MenuElement._internalWrap();
   }
 
-  factory MenuElement._internalWrap() {
-    return new MenuElement.internal_();
-  }
+  external factory MenuElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MenuElement.internal_() : super.internal_();
@@ -26234,9 +25983,7 @@
     return new MenuItemElement._internalWrap();
   }
 
-  factory MenuItemElement._internalWrap() {
-    return new MenuItemElement.internal_();
-  }
+  external factory MenuItemElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MenuItemElement.internal_() : super.internal_();
@@ -26367,9 +26114,7 @@
     return new MessageEvent._internalWrap();
   }
 
-  factory MessageEvent._internalWrap() {
-    return new MessageEvent.internal_();
-  }
+  external factory MessageEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MessageEvent.internal_() : super.internal_();
@@ -26427,9 +26172,7 @@
     return new MessagePort._internalWrap();
   }
 
-  factory MessagePort._internalWrap() {
-    return new MessagePort.internal_();
-  }
+  external factory MessagePort._internalWrap();
 
   @Deprecated("Internal Use Only")
   MessagePort.internal_() : super.internal_();
@@ -26476,9 +26219,7 @@
     return new MetaElement._internalWrap();
   }
 
-  factory MetaElement._internalWrap() {
-    return new MetaElement.internal_();
-  }
+  external factory MetaElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MetaElement.internal_() : super.internal_();
@@ -26592,9 +26333,7 @@
     return new MeterElement._internalWrap();
   }
 
-  factory MeterElement._internalWrap() {
-    return new MeterElement.internal_();
-  }
+  external factory MeterElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MeterElement.internal_() : super.internal_();
@@ -26704,9 +26443,7 @@
     return new MidiAccess._internalWrap();
   }
 
-  factory MidiAccess._internalWrap() {
-    return new MidiAccess.internal_();
-  }
+  external factory MidiAccess._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiAccess.internal_() : super.internal_();
@@ -26757,9 +26494,7 @@
     return new MidiConnectionEvent._internalWrap();
   }
 
-  factory MidiConnectionEvent._internalWrap() {
-    return new MidiConnectionEvent.internal_();
-  }
+  external factory MidiConnectionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiConnectionEvent.internal_() : super.internal_();
@@ -26801,9 +26536,7 @@
     return new MidiInput._internalWrap();
   }
 
-  factory MidiInput._internalWrap() {
-    return new MidiInput.internal_();
-  }
+  external factory MidiInput._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiInput.internal_() : super.internal_();
@@ -26896,9 +26629,7 @@
     return new MidiMessageEvent._internalWrap();
   }
 
-  factory MidiMessageEvent._internalWrap() {
-    return new MidiMessageEvent.internal_();
-  }
+  external factory MidiMessageEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiMessageEvent.internal_() : super.internal_();
@@ -26934,9 +26665,7 @@
     return new MidiOutput._internalWrap();
   }
 
-  factory MidiOutput._internalWrap() {
-    return new MidiOutput.internal_();
-  }
+  external factory MidiOutput._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiOutput.internal_() : super.internal_();
@@ -27043,9 +26772,7 @@
     return new MidiPort._internalWrap();
   }
 
-  factory MidiPort._internalWrap() {
-    return new MidiPort.internal_();
-  }
+  external factory MidiPort._internalWrap();
 
   @Deprecated("Internal Use Only")
   MidiPort.internal_() : super.internal_();
@@ -27235,9 +26962,7 @@
     return new ModElement._internalWrap();
   }
 
-  factory ModElement._internalWrap() {
-    return new ModElement.internal_();
-  }
+  external factory ModElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ModElement.internal_() : super.internal_();
@@ -27299,9 +27024,7 @@
     return new MouseEvent._internalWrap();
   }
 
-  factory MouseEvent._internalWrap() {
-    return new MouseEvent.internal_();
-  }
+  external factory MouseEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   MouseEvent.internal_() : super.internal_();
@@ -28118,9 +27841,7 @@
     return new NetworkInformation._internalWrap();
   }
 
-  factory NetworkInformation._internalWrap() {
-    return new NetworkInformation.internal_();
-  }
+  external factory NetworkInformation._internalWrap();
 
   @Deprecated("Internal Use Only")
   NetworkInformation.internal_() : super.internal_();
@@ -28420,9 +28141,7 @@
     return new Node._internalWrap();
   }
 
-  factory Node._internalWrap() {
-    return new Node.internal_();
-  }
+  external factory Node._internalWrap();
 
   @Deprecated("Internal Use Only")
   Node.internal_() : super.internal_();
@@ -29026,9 +28745,7 @@
     return new Notification._internalWrap();
   }
 
-  factory Notification._internalWrap() {
-    return new Notification.internal_();
-  }
+  external factory Notification._internalWrap();
 
   @Deprecated("Internal Use Only")
   Notification.internal_() : super.internal_();
@@ -29146,9 +28863,7 @@
     return new OListElement._internalWrap();
   }
 
-  factory OListElement._internalWrap() {
-    return new OListElement.internal_();
-  }
+  external factory OListElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   OListElement.internal_() : super.internal_();
@@ -29212,9 +28927,7 @@
     return new ObjectElement._internalWrap();
   }
 
-  factory ObjectElement._internalWrap() {
-    return new ObjectElement.internal_();
-  }
+  external factory ObjectElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ObjectElement.internal_() : super.internal_();
@@ -29343,9 +29056,7 @@
     return new OptGroupElement._internalWrap();
   }
 
-  factory OptGroupElement._internalWrap() {
-    return new OptGroupElement.internal_();
-  }
+  external factory OptGroupElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   OptGroupElement.internal_() : super.internal_();
@@ -29397,9 +29108,7 @@
     return new OptionElement._internalWrap();
   }
 
-  factory OptionElement._internalWrap() {
-    return new OptionElement.internal_();
-  }
+  external factory OptionElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   OptionElement.internal_() : super.internal_();
@@ -29486,9 +29195,7 @@
     return new OutputElement._internalWrap();
   }
 
-  factory OutputElement._internalWrap() {
-    return new OutputElement.internal_();
-  }
+  external factory OutputElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   OutputElement.internal_() : super.internal_();
@@ -29585,9 +29292,7 @@
     return new OverflowEvent._internalWrap();
   }
 
-  factory OverflowEvent._internalWrap() {
-    return new OverflowEvent.internal_();
-  }
+  external factory OverflowEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   OverflowEvent.internal_() : super.internal_();
@@ -29639,9 +29344,7 @@
     return new PageTransitionEvent._internalWrap();
   }
 
-  factory PageTransitionEvent._internalWrap() {
-    return new PageTransitionEvent.internal_();
-  }
+  external factory PageTransitionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   PageTransitionEvent.internal_() : super.internal_();
@@ -29675,9 +29378,7 @@
     return new ParagraphElement._internalWrap();
   }
 
-  factory ParagraphElement._internalWrap() {
-    return new ParagraphElement.internal_();
-  }
+  external factory ParagraphElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ParagraphElement.internal_() : super.internal_();
@@ -29714,9 +29415,7 @@
     return new ParamElement._internalWrap();
   }
 
-  factory ParamElement._internalWrap() {
-    return new ParamElement.internal_();
-  }
+  external factory ParamElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ParamElement.internal_() : super.internal_();
@@ -29925,9 +29624,7 @@
     return new Performance._internalWrap();
   }
 
-  factory Performance._internalWrap() {
-    return new Performance.internal_();
-  }
+  external factory Performance._internalWrap();
 
   @Deprecated("Internal Use Only")
   Performance.internal_() : super.internal_();
@@ -30087,9 +29784,7 @@
     return new PerformanceMark._internalWrap();
   }
 
-  factory PerformanceMark._internalWrap() {
-    return new PerformanceMark.internal_();
-  }
+  external factory PerformanceMark._internalWrap();
 
   @Deprecated("Internal Use Only")
   PerformanceMark.internal_() : super.internal_();
@@ -30117,9 +29812,7 @@
     return new PerformanceMeasure._internalWrap();
   }
 
-  factory PerformanceMeasure._internalWrap() {
-    return new PerformanceMeasure.internal_();
-  }
+  external factory PerformanceMeasure._internalWrap();
 
   @Deprecated("Internal Use Only")
   PerformanceMeasure.internal_() : super.internal_();
@@ -30201,9 +29894,7 @@
     return new PerformanceResourceTiming._internalWrap();
   }
 
-  factory PerformanceResourceTiming._internalWrap() {
-    return new PerformanceResourceTiming.internal_();
-  }
+  external factory PerformanceResourceTiming._internalWrap();
 
   @Deprecated("Internal Use Only")
   PerformanceResourceTiming.internal_() : super.internal_();
@@ -30395,9 +30086,7 @@
     return new PictureElement._internalWrap();
   }
 
-  factory PictureElement._internalWrap() {
-    return new PictureElement.internal_();
-  }
+  external factory PictureElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PictureElement.internal_() : super.internal_();
@@ -30584,9 +30273,7 @@
     return new PluginPlaceholderElement._internalWrap();
   }
 
-  factory PluginPlaceholderElement._internalWrap() {
-    return new PluginPlaceholderElement.internal_();
-  }
+  external factory PluginPlaceholderElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PluginPlaceholderElement.internal_() : super.internal_();
@@ -30637,9 +30324,7 @@
     return new PopStateEvent._internalWrap();
   }
 
-  factory PopStateEvent._internalWrap() {
-    return new PopStateEvent.internal_();
-  }
+  external factory PopStateEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   PopStateEvent.internal_() : super.internal_();
@@ -30743,9 +30428,7 @@
     return new PreElement._internalWrap();
   }
 
-  factory PreElement._internalWrap() {
-    return new PreElement.internal_();
-  }
+  external factory PreElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PreElement.internal_() : super.internal_();
@@ -30778,9 +30461,7 @@
     return new Presentation._internalWrap();
   }
 
-  factory Presentation._internalWrap() {
-    return new Presentation.internal_();
-  }
+  external factory Presentation._internalWrap();
 
   @Deprecated("Internal Use Only")
   Presentation.internal_() : super.internal_();
@@ -30807,9 +30488,7 @@
     return new ProcessingInstruction._internalWrap();
   }
 
-  factory ProcessingInstruction._internalWrap() {
-    return new ProcessingInstruction.internal_();
-  }
+  external factory ProcessingInstruction._internalWrap();
 
   @Deprecated("Internal Use Only")
   ProcessingInstruction.internal_() : super.internal_();
@@ -30852,9 +30531,7 @@
     return new ProgressElement._internalWrap();
   }
 
-  factory ProgressElement._internalWrap() {
-    return new ProgressElement.internal_();
-  }
+  external factory ProgressElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ProgressElement.internal_() : super.internal_();
@@ -30914,9 +30591,7 @@
     return new ProgressEvent._internalWrap();
   }
 
-  factory ProgressEvent._internalWrap() {
-    return new ProgressEvent.internal_();
-  }
+  external factory ProgressEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ProgressEvent.internal_() : super.internal_();
@@ -30955,9 +30630,7 @@
     return new PushEvent._internalWrap();
   }
 
-  factory PushEvent._internalWrap() {
-    return new PushEvent.internal_();
-  }
+  external factory PushEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   PushEvent.internal_() : super.internal_();
@@ -31067,9 +30740,7 @@
     return new QuoteElement._internalWrap();
   }
 
-  factory QuoteElement._internalWrap() {
-    return new QuoteElement.internal_();
-  }
+  external factory QuoteElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   QuoteElement.internal_() : super.internal_();
@@ -31399,9 +31070,7 @@
     return new RelatedEvent._internalWrap();
   }
 
-  factory RelatedEvent._internalWrap() {
-    return new RelatedEvent.internal_();
-  }
+  external factory RelatedEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   RelatedEvent.internal_() : super.internal_();
@@ -31443,9 +31112,7 @@
     return new ResourceProgressEvent._internalWrap();
   }
 
-  factory ResourceProgressEvent._internalWrap() {
-    return new ResourceProgressEvent.internal_();
-  }
+  external factory ResourceProgressEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ResourceProgressEvent.internal_() : super.internal_();
@@ -31517,9 +31184,7 @@
     return new RtcDataChannel._internalWrap();
   }
 
-  factory RtcDataChannel._internalWrap() {
-    return new RtcDataChannel.internal_();
-  }
+  external factory RtcDataChannel._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcDataChannel.internal_() : super.internal_();
@@ -31661,9 +31326,7 @@
     return new RtcDataChannelEvent._internalWrap();
   }
 
-  factory RtcDataChannelEvent._internalWrap() {
-    return new RtcDataChannelEvent.internal_();
-  }
+  external factory RtcDataChannelEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcDataChannelEvent.internal_() : super.internal_();
@@ -31705,9 +31368,7 @@
     return new RtcDtmfSender._internalWrap();
   }
 
-  factory RtcDtmfSender._internalWrap() {
-    return new RtcDtmfSender.internal_();
-  }
+  external factory RtcDtmfSender._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcDtmfSender.internal_() : super.internal_();
@@ -31773,9 +31434,7 @@
     return new RtcDtmfToneChangeEvent._internalWrap();
   }
 
-  factory RtcDtmfToneChangeEvent._internalWrap() {
-    return new RtcDtmfToneChangeEvent.internal_();
-  }
+  external factory RtcDtmfToneChangeEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcDtmfToneChangeEvent.internal_() : super.internal_();
@@ -31870,9 +31529,7 @@
     return new RtcIceCandidateEvent._internalWrap();
   }
 
-  factory RtcIceCandidateEvent._internalWrap() {
-    return new RtcIceCandidateEvent.internal_();
-  }
+  external factory RtcIceCandidateEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcIceCandidateEvent.internal_() : super.internal_();
@@ -32012,9 +31669,7 @@
     return new RtcPeerConnection._internalWrap();
   }
 
-  factory RtcPeerConnection._internalWrap() {
-    return new RtcPeerConnection.internal_();
-  }
+  external factory RtcPeerConnection._internalWrap();
 
   @Deprecated("Internal Use Only")
   RtcPeerConnection.internal_() : super.internal_();
@@ -32436,9 +32091,7 @@
     return new ScreenOrientation._internalWrap();
   }
 
-  factory ScreenOrientation._internalWrap() {
-    return new ScreenOrientation.internal_();
-  }
+  external factory ScreenOrientation._internalWrap();
 
   @Deprecated("Internal Use Only")
   ScreenOrientation.internal_() : super.internal_();
@@ -32493,9 +32146,7 @@
     return new ScriptElement._internalWrap();
   }
 
-  factory ScriptElement._internalWrap() {
-    return new ScriptElement.internal_();
-  }
+  external factory ScriptElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ScriptElement.internal_() : super.internal_();
@@ -32603,9 +32254,7 @@
     return new SecurityPolicyViolationEvent._internalWrap();
   }
 
-  factory SecurityPolicyViolationEvent._internalWrap() {
-    return new SecurityPolicyViolationEvent.internal_();
-  }
+  external factory SecurityPolicyViolationEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   SecurityPolicyViolationEvent.internal_() : super.internal_();
@@ -32673,9 +32322,7 @@
     return new SelectElement._internalWrap();
   }
 
-  factory SelectElement._internalWrap() {
-    return new SelectElement.internal_();
-  }
+  external factory SelectElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SelectElement.internal_() : super.internal_();
@@ -33137,9 +32784,7 @@
     return new ServiceWorkerGlobalScope._internalWrap();
   }
 
-  factory ServiceWorkerGlobalScope._internalWrap() {
-    return new ServiceWorkerGlobalScope.internal_();
-  }
+  external factory ServiceWorkerGlobalScope._internalWrap();
 
   @Deprecated("Internal Use Only")
   ServiceWorkerGlobalScope.internal_() : super.internal_();
@@ -33207,9 +32852,7 @@
     return new ServiceWorkerRegistration._internalWrap();
   }
 
-  factory ServiceWorkerRegistration._internalWrap() {
-    return new ServiceWorkerRegistration.internal_();
-  }
+  external factory ServiceWorkerRegistration._internalWrap();
 
   @Deprecated("Internal Use Only")
   ServiceWorkerRegistration.internal_() : super.internal_();
@@ -33267,9 +32910,7 @@
     return new ShadowElement._internalWrap();
   }
 
-  factory ShadowElement._internalWrap() {
-    return new ShadowElement.internal_();
-  }
+  external factory ShadowElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ShadowElement.internal_() : super.internal_();
@@ -33311,9 +32952,7 @@
     return new ShadowRoot._internalWrap();
   }
 
-  factory ShadowRoot._internalWrap() {
-    return new ShadowRoot.internal_();
-  }
+  external factory ShadowRoot._internalWrap();
 
   @Deprecated("Internal Use Only")
   ShadowRoot.internal_() : super.internal_();
@@ -33439,9 +33078,7 @@
     return new SharedWorker._internalWrap();
   }
 
-  factory SharedWorker._internalWrap() {
-    return new SharedWorker.internal_();
-  }
+  external factory SharedWorker._internalWrap();
 
   @Deprecated("Internal Use Only")
   SharedWorker.internal_() : super.internal_();
@@ -33493,9 +33130,7 @@
     return new SharedWorkerGlobalScope._internalWrap();
   }
 
-  factory SharedWorkerGlobalScope._internalWrap() {
-    return new SharedWorkerGlobalScope.internal_();
-  }
+  external factory SharedWorkerGlobalScope._internalWrap();
 
   @Deprecated("Internal Use Only")
   SharedWorkerGlobalScope.internal_() : super.internal_();
@@ -33534,9 +33169,7 @@
     return new SourceBuffer._internalWrap();
   }
 
-  factory SourceBuffer._internalWrap() {
-    return new SourceBuffer.internal_();
-  }
+  external factory SourceBuffer._internalWrap();
 
   @Deprecated("Internal Use Only")
   SourceBuffer.internal_() : super.internal_();
@@ -33639,9 +33272,7 @@
     return new SourceBufferList._internalWrap();
   }
 
-  factory SourceBufferList._internalWrap() {
-    return new SourceBufferList.internal_();
-  }
+  external factory SourceBufferList._internalWrap();
 
   @Deprecated("Internal Use Only")
   SourceBufferList.internal_() : super.internal_();
@@ -33725,9 +33356,7 @@
     return new SourceElement._internalWrap();
   }
 
-  factory SourceElement._internalWrap() {
-    return new SourceElement.internal_();
-  }
+  external factory SourceElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SourceElement.internal_() : super.internal_();
@@ -33867,9 +33496,7 @@
     return new SpanElement._internalWrap();
   }
 
-  factory SpanElement._internalWrap() {
-    return new SpanElement.internal_();
-  }
+  external factory SpanElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpanElement.internal_() : super.internal_();
@@ -34182,9 +33809,7 @@
     return new SpeechRecognition._internalWrap();
   }
 
-  factory SpeechRecognition._internalWrap() {
-    return new SpeechRecognition.internal_();
-  }
+  external factory SpeechRecognition._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechRecognition.internal_() : super.internal_();
@@ -34363,9 +33988,7 @@
     return new SpeechRecognitionError._internalWrap();
   }
 
-  factory SpeechRecognitionError._internalWrap() {
-    return new SpeechRecognitionError.internal_();
-  }
+  external factory SpeechRecognitionError._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechRecognitionError.internal_() : super.internal_();
@@ -34402,9 +34025,7 @@
     return new SpeechRecognitionEvent._internalWrap();
   }
 
-  factory SpeechRecognitionEvent._internalWrap() {
-    return new SpeechRecognitionEvent.internal_();
-  }
+  external factory SpeechRecognitionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechRecognitionEvent.internal_() : super.internal_();
@@ -34492,9 +34113,7 @@
     return new SpeechSynthesis._internalWrap();
   }
 
-  factory SpeechSynthesis._internalWrap() {
-    return new SpeechSynthesis.internal_();
-  }
+  external factory SpeechSynthesis._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechSynthesis.internal_() : super.internal_();
@@ -34554,9 +34173,7 @@
     return new SpeechSynthesisEvent._internalWrap();
   }
 
-  factory SpeechSynthesisEvent._internalWrap() {
-    return new SpeechSynthesisEvent.internal_();
-  }
+  external factory SpeechSynthesisEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechSynthesisEvent.internal_() : super.internal_();
@@ -34672,9 +34289,7 @@
     return new SpeechSynthesisUtterance._internalWrap();
   }
 
-  factory SpeechSynthesisUtterance._internalWrap() {
-    return new SpeechSynthesisUtterance.internal_();
-  }
+  external factory SpeechSynthesisUtterance._internalWrap();
 
   @Deprecated("Internal Use Only")
   SpeechSynthesisUtterance.internal_() : super.internal_();
@@ -35016,9 +34631,7 @@
     return new StorageEvent._internalWrap();
   }
 
-  factory StorageEvent._internalWrap() {
-    return new StorageEvent.internal_();
-  }
+  external factory StorageEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   StorageEvent.internal_() : super.internal_();
@@ -35192,9 +34805,7 @@
     return new StyleElement._internalWrap();
   }
 
-  factory StyleElement._internalWrap() {
-    return new StyleElement.internal_();
-  }
+  external factory StyleElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   StyleElement.internal_() : super.internal_();
@@ -35358,9 +34969,7 @@
     return new TableCaptionElement._internalWrap();
   }
 
-  factory TableCaptionElement._internalWrap() {
-    return new TableCaptionElement.internal_();
-  }
+  external factory TableCaptionElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableCaptionElement.internal_() : super.internal_();
@@ -35396,9 +35005,7 @@
     return new TableCellElement._internalWrap();
   }
 
-  factory TableCellElement._internalWrap() {
-    return new TableCellElement.internal_();
-  }
+  external factory TableCellElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableCellElement.internal_() : super.internal_();
@@ -35462,9 +35069,7 @@
     return new TableColElement._internalWrap();
   }
 
-  factory TableColElement._internalWrap() {
-    return new TableColElement.internal_();
-  }
+  external factory TableColElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableColElement.internal_() : super.internal_();
@@ -35526,9 +35131,7 @@
     return new TableElement._internalWrap();
   }
 
-  factory TableElement._internalWrap() {
-    return new TableElement.internal_();
-  }
+  external factory TableElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableElement.internal_() : super.internal_();
@@ -35644,9 +35247,7 @@
     return new TableRowElement._internalWrap();
   }
 
-  factory TableRowElement._internalWrap() {
-    return new TableRowElement.internal_();
-  }
+  external factory TableRowElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableRowElement.internal_() : super.internal_();
@@ -35710,9 +35311,7 @@
     return new TableSectionElement._internalWrap();
   }
 
-  factory TableSectionElement._internalWrap() {
-    return new TableSectionElement.internal_();
-  }
+  external factory TableSectionElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TableSectionElement.internal_() : super.internal_();
@@ -35765,9 +35364,7 @@
     return new TemplateElement._internalWrap();
   }
 
-  factory TemplateElement._internalWrap() {
-    return new TemplateElement.internal_();
-  }
+  external factory TemplateElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TemplateElement.internal_() : super.internal_();
@@ -35822,9 +35419,7 @@
     return new Text._internalWrap();
   }
 
-  factory Text._internalWrap() {
-    return new Text.internal_();
-  }
+  external factory Text._internalWrap();
 
   @Deprecated("Internal Use Only")
   Text.internal_() : super.internal_();
@@ -35867,9 +35462,7 @@
     return new TextAreaElement._internalWrap();
   }
 
-  factory TextAreaElement._internalWrap() {
-    return new TextAreaElement.internal_();
-  }
+  external factory TextAreaElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextAreaElement.internal_() : super.internal_();
@@ -36114,9 +35707,7 @@
     return new TextEvent._internalWrap();
   }
 
-  factory TextEvent._internalWrap() {
-    return new TextEvent.internal_();
-  }
+  external factory TextEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextEvent.internal_() : super.internal_();
@@ -36250,9 +35841,7 @@
     return new TextTrack._internalWrap();
   }
 
-  factory TextTrack._internalWrap() {
-    return new TextTrack.internal_();
-  }
+  external factory TextTrack._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextTrack.internal_() : super.internal_();
@@ -36361,9 +35950,7 @@
     return new TextTrackCue._internalWrap();
   }
 
-  factory TextTrackCue._internalWrap() {
-    return new TextTrackCue.internal_();
-  }
+  external factory TextTrackCue._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextTrackCue.internal_() : super.internal_();
@@ -36541,9 +36128,7 @@
     return new TextTrackList._internalWrap();
   }
 
-  factory TextTrackList._internalWrap() {
-    return new TextTrackList.internal_();
-  }
+  external factory TextTrackList._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextTrackList.internal_() : super.internal_();
@@ -36813,9 +36398,7 @@
     return new TitleElement._internalWrap();
   }
 
-  factory TitleElement._internalWrap() {
-    return new TitleElement.internal_();
-  }
+  external factory TitleElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TitleElement.internal_() : super.internal_();
@@ -36982,9 +36565,7 @@
     return new TouchEvent._internalWrap();
   }
 
-  factory TouchEvent._internalWrap() {
-    return new TouchEvent.internal_();
-  }
+  external factory TouchEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   TouchEvent.internal_() : super.internal_();
@@ -37151,9 +36732,7 @@
     return new TrackElement._internalWrap();
   }
 
-  factory TrackElement._internalWrap() {
-    return new TrackElement.internal_();
-  }
+  external factory TrackElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TrackElement.internal_() : super.internal_();
@@ -37263,9 +36842,7 @@
     return new TrackEvent._internalWrap();
   }
 
-  factory TrackEvent._internalWrap() {
-    return new TrackEvent.internal_();
-  }
+  external factory TrackEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   TrackEvent.internal_() : super.internal_();
@@ -37295,9 +36872,7 @@
     return new TransitionEvent._internalWrap();
   }
 
-  factory TransitionEvent._internalWrap() {
-    return new TransitionEvent.internal_();
-  }
+  external factory TransitionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   TransitionEvent.internal_() : super.internal_();
@@ -37428,9 +37003,7 @@
     return new UIEvent._internalWrap();
   }
 
-  factory UIEvent._internalWrap() {
-    return new UIEvent.internal_();
-  }
+  external factory UIEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   UIEvent.internal_() : super.internal_();
@@ -37519,9 +37092,7 @@
     return new UListElement._internalWrap();
   }
 
-  factory UListElement._internalWrap() {
-    return new UListElement.internal_();
-  }
+  external factory UListElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   UListElement.internal_() : super.internal_();
@@ -37553,9 +37124,7 @@
     return new UnknownElement._internalWrap();
   }
 
-  factory UnknownElement._internalWrap() {
-    return new UnknownElement.internal_();
-  }
+  external factory UnknownElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   UnknownElement.internal_() : super.internal_();
@@ -38015,9 +37584,7 @@
     return new VideoElement._internalWrap();
   }
 
-  factory VideoElement._internalWrap() {
-    return new VideoElement.internal_();
-  }
+  external factory VideoElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   VideoElement.internal_() : super.internal_();
@@ -38232,9 +37799,7 @@
     return new VideoTrackList._internalWrap();
   }
 
-  factory VideoTrackList._internalWrap() {
-    return new VideoTrackList.internal_();
-  }
+  external factory VideoTrackList._internalWrap();
 
   @Deprecated("Internal Use Only")
   VideoTrackList.internal_() : super.internal_();
@@ -38303,9 +37868,7 @@
     return new VttCue._internalWrap();
   }
 
-  factory VttCue._internalWrap() {
-    return new VttCue.internal_();
-  }
+  external factory VttCue._internalWrap();
 
   @Deprecated("Internal Use Only")
   VttCue.internal_() : super.internal_();
@@ -38677,9 +38240,7 @@
     return new WebSocket._internalWrap();
   }
 
-  factory WebSocket._internalWrap() {
-    return new WebSocket.internal_();
-  }
+  external factory WebSocket._internalWrap();
 
   @Deprecated("Internal Use Only")
   WebSocket.internal_() : super.internal_();
@@ -38851,9 +38412,7 @@
     return new WheelEvent._internalWrap();
   }
 
-  factory WheelEvent._internalWrap() {
-    return new WheelEvent.internal_();
-  }
+  external factory WheelEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   WheelEvent.internal_() : super.internal_();
@@ -39193,9 +38752,7 @@
     return new Window._internalWrap();
   }
 
-  factory Window._internalWrap() {
-    return new Window.internal_();
-  }
+  external factory Window._internalWrap();
 
   @Deprecated("Internal Use Only")
   Window.internal_() : super.internal_();
@@ -40663,9 +40220,7 @@
     return new Worker._internalWrap();
   }
 
-  factory Worker._internalWrap() {
-    return new Worker.internal_();
-  }
+  external factory Worker._internalWrap();
 
   @Deprecated("Internal Use Only")
   Worker.internal_() : super.internal_();
@@ -40714,9 +40269,7 @@
     return new WorkerConsole._internalWrap();
   }
 
-  factory WorkerConsole._internalWrap() {
-    return new WorkerConsole.internal_();
-  }
+  external factory WorkerConsole._internalWrap();
 
   @Deprecated("Internal Use Only")
   WorkerConsole.internal_() : super.internal_();
@@ -40754,9 +40307,7 @@
     return new WorkerGlobalScope._internalWrap();
   }
 
-  factory WorkerGlobalScope._internalWrap() {
-    return new WorkerGlobalScope.internal_();
-  }
+  external factory WorkerGlobalScope._internalWrap();
 
   @Deprecated("Internal Use Only")
   WorkerGlobalScope.internal_() : super.internal_();
@@ -41194,9 +40745,7 @@
     return new XmlDocument._internalWrap();
   }
 
-  factory XmlDocument._internalWrap() {
-    return new XmlDocument.internal_();
-  }
+  external factory XmlDocument._internalWrap();
 
   @Deprecated("Internal Use Only")
   XmlDocument.internal_() : super.internal_();
@@ -41337,9 +40886,7 @@
     return new _Attr._internalWrap();
   }
 
-  factory _Attr._internalWrap() {
-    return new _Attr.internal_();
-  }
+  external factory _Attr._internalWrap();
 
   @Deprecated("Internal Use Only")
   _Attr.internal_() : super.internal_();
@@ -41404,9 +40951,7 @@
     return new _CSSPrimitiveValue._internalWrap();
   }
 
-  factory _CSSPrimitiveValue._internalWrap() {
-    return new _CSSPrimitiveValue.internal_();
-  }
+  external factory _CSSPrimitiveValue._internalWrap();
 
   @Deprecated("Internal Use Only")
   _CSSPrimitiveValue.internal_() : super.internal_();
@@ -41434,9 +40979,7 @@
     return new _CSSUnknownRule._internalWrap();
   }
 
-  factory _CSSUnknownRule._internalWrap() {
-    return new _CSSUnknownRule.internal_();
-  }
+  external factory _CSSUnknownRule._internalWrap();
 
   @Deprecated("Internal Use Only")
   _CSSUnknownRule.internal_() : super.internal_();
@@ -41912,9 +41455,7 @@
     return new _CssValueList._internalWrap();
   }
 
-  factory _CssValueList._internalWrap() {
-    return new _CssValueList.internal_();
-  }
+  external factory _CssValueList._internalWrap();
 
   @Deprecated("Internal Use Only")
   _CssValueList.internal_() : super.internal_();
@@ -42028,9 +41569,7 @@
     return new _DirectoryEntrySync._internalWrap();
   }
 
-  factory _DirectoryEntrySync._internalWrap() {
-    return new _DirectoryEntrySync.internal_();
-  }
+  external factory _DirectoryEntrySync._internalWrap();
 
   @Deprecated("Internal Use Only")
   _DirectoryEntrySync.internal_() : super.internal_();
@@ -42087,9 +41626,7 @@
     return new _DocumentType._internalWrap();
   }
 
-  factory _DocumentType._internalWrap() {
-    return new _DocumentType.internal_();
-  }
+  external factory _DocumentType._internalWrap();
 
   @Deprecated("Internal Use Only")
   _DocumentType.internal_() : super.internal_();
@@ -42138,9 +41675,7 @@
     return new _DomRect._internalWrap();
   }
 
-  factory _DomRect._internalWrap() {
-    return new _DomRect.internal_();
-  }
+  external factory _DomRect._internalWrap();
 
   @Deprecated("Internal Use Only")
   _DomRect.internal_() : super.internal_();
@@ -42239,9 +41774,7 @@
     return new _FileEntrySync._internalWrap();
   }
 
-  factory _FileEntrySync._internalWrap() {
-    return new _FileEntrySync.internal_();
-  }
+  external factory _FileEntrySync._internalWrap();
 
   @Deprecated("Internal Use Only")
   _FileEntrySync.internal_() : super.internal_();
@@ -42457,9 +41990,7 @@
     return new _HTMLAppletElement._internalWrap();
   }
 
-  factory _HTMLAppletElement._internalWrap() {
-    return new _HTMLAppletElement.internal_();
-  }
+  external factory _HTMLAppletElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLAppletElement.internal_() : super.internal_();
@@ -42493,9 +42024,7 @@
     return new _HTMLDirectoryElement._internalWrap();
   }
 
-  factory _HTMLDirectoryElement._internalWrap() {
-    return new _HTMLDirectoryElement.internal_();
-  }
+  external factory _HTMLDirectoryElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLDirectoryElement.internal_() : super.internal_();
@@ -42529,9 +42058,7 @@
     return new _HTMLFontElement._internalWrap();
   }
 
-  factory _HTMLFontElement._internalWrap() {
-    return new _HTMLFontElement.internal_();
-  }
+  external factory _HTMLFontElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLFontElement.internal_() : super.internal_();
@@ -42565,9 +42092,7 @@
     return new _HTMLFrameElement._internalWrap();
   }
 
-  factory _HTMLFrameElement._internalWrap() {
-    return new _HTMLFrameElement.internal_();
-  }
+  external factory _HTMLFrameElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLFrameElement.internal_() : super.internal_();
@@ -42599,9 +42124,7 @@
     return new _HTMLFrameSetElement._internalWrap();
   }
 
-  factory _HTMLFrameSetElement._internalWrap() {
-    return new _HTMLFrameSetElement.internal_();
-  }
+  external factory _HTMLFrameSetElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLFrameSetElement.internal_() : super.internal_();
@@ -42644,9 +42167,7 @@
     return new _HTMLMarqueeElement._internalWrap();
   }
 
-  factory _HTMLMarqueeElement._internalWrap() {
-    return new _HTMLMarqueeElement.internal_();
-  }
+  external factory _HTMLMarqueeElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _HTMLMarqueeElement.internal_() : super.internal_();
@@ -42686,9 +42207,7 @@
     return new _MutationEvent._internalWrap();
   }
 
-  factory _MutationEvent._internalWrap() {
-    return new _MutationEvent.internal_();
-  }
+  external factory _MutationEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   _MutationEvent.internal_() : super.internal_();
@@ -42885,9 +42404,7 @@
     return new _RadioNodeList._internalWrap();
   }
 
-  factory _RadioNodeList._internalWrap() {
-    return new _RadioNodeList.internal_();
-  }
+  external factory _RadioNodeList._internalWrap();
 
   @Deprecated("Internal Use Only")
   _RadioNodeList.internal_() : super.internal_();
@@ -42965,9 +42482,7 @@
     return new _Request._internalWrap();
   }
 
-  factory _Request._internalWrap() {
-    return new _Request.internal_();
-  }
+  external factory _Request._internalWrap();
 
   @Deprecated("Internal Use Only")
   _Request.internal_() : super.internal_();
@@ -43058,9 +42573,7 @@
     return new _Response._internalWrap();
   }
 
-  factory _Response._internalWrap() {
-    return new _Response.internal_();
-  }
+  external factory _Response._internalWrap();
 
   @Deprecated("Internal Use Only")
   _Response.internal_() : super.internal_();
@@ -43085,9 +42598,7 @@
     return new _ServiceWorker._internalWrap();
   }
 
-  factory _ServiceWorker._internalWrap() {
-    return new _ServiceWorker.internal_();
-  }
+  external factory _ServiceWorker._internalWrap();
 
   @Deprecated("Internal Use Only")
   _ServiceWorker.internal_() : super.internal_();
@@ -43320,9 +42831,7 @@
     return new _WebKitCSSFilterValue._internalWrap();
   }
 
-  factory _WebKitCSSFilterValue._internalWrap() {
-    return new _WebKitCSSFilterValue.internal_();
-  }
+  external factory _WebKitCSSFilterValue._internalWrap();
 
   @Deprecated("Internal Use Only")
   _WebKitCSSFilterValue.internal_() : super.internal_();
@@ -43390,9 +42899,7 @@
     return new _WebKitCSSTransformValue._internalWrap();
   }
 
-  factory _WebKitCSSTransformValue._internalWrap() {
-    return new _WebKitCSSTransformValue.internal_();
-  }
+  external factory _WebKitCSSTransformValue._internalWrap();
 
   @Deprecated("Internal Use Only")
   _WebKitCSSTransformValue.internal_() : super.internal_();
@@ -43534,9 +43041,7 @@
     return new _XMLHttpRequestProgressEvent._internalWrap();
   }
 
-  factory _XMLHttpRequestProgressEvent._internalWrap() {
-    return new _XMLHttpRequestProgressEvent.internal_();
-  }
+  external factory _XMLHttpRequestProgressEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   _XMLHttpRequestProgressEvent.internal_() : super.internal_();
@@ -47719,7 +47224,7 @@
         throw new UnsupportedError('$tag is not registered.');
       }
       jsObject = unwrap_jso(element);
-    } else if (element.runtimeType == js.JsObjectImpl) {
+    } else if (element.runtimeType == js.JsObject) {
       // It's a Polymer core element (written in JS).
       jsObject = element;
     } else if (isNativeElementExtension) {
@@ -47731,7 +47236,7 @@
     } else if (tag != null && element.localName != tag) {
       throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected native Html or Svg element to extend.');
     } else if (tag == null) {
-      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObjectImpl.');
+      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObject.');
     }
 
     // Remember Dart class to tagName for any upgrading done in wrap_jso.
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index 2403387..3e3e5c1 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -126,9 +126,14 @@
     }
 
     if (jsObject is js.JsArray) {
-      var wrappingList = new DartHtmlWrappingList(jsObject);
-      js.setDartHtmlWrapperFor(jsObject, wrappingList);
-      return wrappingList;
+      wrapper = new js.JSArray.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
+    }
+    if (jsObject is js.JsFunction) {
+      wrapper = new js.JSFunction.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
     }
 
     // Try the most general type conversions on it.
@@ -144,14 +149,15 @@
     if (constructor == null) {
       // Perfectly valid case for JavaScript objects where __proto__ has
       // intentionally been set to null.
-      js.setDartHtmlWrapperFor(jsObject, jsObject);
+      js.setDartHtmlWrapperFor(jsObject, new js.JSObject.create(jsObject));
       return jsObject;
     }
     var jsTypeName = js.JsNative.getProperty(constructor, 'name');
     if (jsTypeName is! String || jsTypeName.length == 0) {
       // Not an html type.
-      js.setDartHtmlWrapperFor(jsObject, jsObject);
-      return jsObject;
+      wrapper = new js.JSObject.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
     }
 
     var dartClass_instance;
@@ -204,12 +210,11 @@
 
     // TODO(jacobr): cache that this is not a dart:html JS class.
     return dartClass_instance;
-  } catch(e, stacktrace){
+  } catch (e, stacktrace) {
     if (interop_checks) {
-      if (e is DebugAssertException)
-        window.console.log("${e.message}\n ${stacktrace}");
-      else
-        window.console.log("${stacktrace}");
+      if (e is DebugAssertException) window.console
+          .log("${e.message}\n ${stacktrace}");
+      else window.console.log("${stacktrace}");
     }
   }
 
@@ -236,31 +241,30 @@
       return wrapper;
     }
 
-    // TODO(jacobr): auomatically wrapping JsArray here is fundamentally broken
-    // as it hijacks adding custom methods on JS Array classes as part of the
-    // new typed DartJsInterop.
-    // To make this work we really need to make DartHtmlWrappingList extend
-    // JsArrayImpl. Fixing this issue needs to be part of a broader refactor
-    // that allows calling custom typed JS interop methods on all dart:html
-    // classes.
     if (jsObject is js.JsArray) {
-      var wrappingList = new DartHtmlWrappingList(jsObject);
-      js.setDartHtmlWrapperFor(jsObject, wrappingList);
-      return wrappingList;
+      wrapper = new js.JSArray.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
+    }
+    if (jsObject is js.JsFunction) {
+      wrapper = new js.JSFunction.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
     }
 
     var constructor = js.JsNative.getProperty(jsObject, 'constructor');
     if (constructor == null) {
       // Perfectly valid case for JavaScript objects where __proto__ has
       // intentionally been set to null.
-      js.setDartHtmlWrapperFor(jsObject, jsObject);
+      js.setDartHtmlWrapperFor(jsObject, new js.JSObject.create(jsObject));
       return jsObject;
     }
     var jsTypeName = js.JsNative.getProperty(constructor, 'name');
     if (jsTypeName is! String || jsTypeName.length == 0) {
       // Not an html type.
-      js.setDartHtmlWrapperFor(jsObject, jsObject);
-      return jsObject;
+      wrapper = new js.JSObject.create(jsObject);
+      js.setDartHtmlWrapperFor(jsObject, wrapper);
+      return wrapper;
     }
 
     var func = getHtmlCreateFunction(jsTypeName);
@@ -270,13 +274,14 @@
       js.setDartHtmlWrapperFor(jsObject, dartClass_instance);
       return dartClass_instance;
     }
-    return jsObject;
-  } catch(e, stacktrace){
+    wrapper = new js.JSObject.create(jsObject);
+    js.setDartHtmlWrapperFor(jsObject, wrapper);
+    return wrapper;
+  } catch (e, stacktrace) {
     if (interop_checks) {
-      if (e is DebugAssertException)
-        window.console.log("${e.message}\n ${stacktrace}");
-      else
-        window.console.log("${stacktrace}");
+      if (e is DebugAssertException) window.console
+          .log("${e.message}\n ${stacktrace}");
+      else window.console.log("${stacktrace}");
     }
   }
 
@@ -333,7 +338,7 @@
   } else if (runtimeType == TemplateElement) {
     // Data binding with a Dart class.
     tag = element.attributes['is'];
-  } else if (runtimeType == js.JsObjectImpl) {
+  } else if (runtimeType == js.JsObject) {
     // It's a Polymer core element (written in JS).
     // Make sure it's an element anything else we can ignore.
     if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
@@ -347,7 +352,8 @@
       }
     }
   } else {
-    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
+    throw new UnsupportedError(
+        'Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.');
   }
 
   var entry = _knownCustomElements[tag];
@@ -378,19 +384,3 @@
   }
   return null;
 }
-
-/**
- * Wraps a JsArray and will call wrap_jso on its entries.
- */
-class DartHtmlWrappingList extends ListBase implements NativeFieldWrapperClass2 {
-  DartHtmlWrappingList(this.blink_jsObject);
-
-  final js.JsArray blink_jsObject;
-
-  operator [](int index) => wrap_jso_no_SerializedScriptvalue(js.JsNative.getArrayIndex(blink_jsObject, index));
-
-  operator []=(int index, value) => blink_jsObject[index] = value;
-
-  int get length => blink_jsObject.length;
-  int set length(int newLength) => blink_jsObject.length = newLength;
-}
diff --git a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
index 4ab3e30..36b35e3 100644
--- a/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
+++ b/sdk/lib/indexed_db/dartium/indexed_db_dartium.dart
@@ -247,9 +247,7 @@
     return new CursorWithValue._internalWrap();
   }
 
-  factory CursorWithValue._internalWrap() {
-    return new CursorWithValue.internal_();
-  }
+  external factory CursorWithValue._internalWrap();
 
   @Deprecated("Internal Use Only")
   CursorWithValue.internal_() : super.internal_();
@@ -365,9 +363,7 @@
     return new Database._internalWrap();
   }
 
-  factory Database._internalWrap() {
-    return new Database.internal_();
-  }
+  external factory Database._internalWrap();
 
   @Deprecated("Internal Use Only")
   Database.internal_() : super.internal_();
@@ -1126,9 +1122,7 @@
     return new OpenDBRequest._internalWrap();
   }
 
-  factory OpenDBRequest._internalWrap() {
-    return new OpenDBRequest.internal_();
-  }
+  external factory OpenDBRequest._internalWrap();
 
   @Deprecated("Internal Use Only")
   OpenDBRequest.internal_() : super.internal_();
@@ -1185,9 +1179,7 @@
     return new Request._internalWrap();
   }
 
-  factory Request._internalWrap() {
-    return new Request.internal_();
-  }
+  external factory Request._internalWrap();
 
   @Deprecated("Internal Use Only")
   Request.internal_() : super.internal_();
@@ -1300,9 +1292,7 @@
     return new Transaction._internalWrap();
   }
 
-  factory Transaction._internalWrap() {
-    return new Transaction.internal_();
-  }
+  external factory Transaction._internalWrap();
 
   @Deprecated("Internal Use Only")
   Transaction.internal_() : super.internal_();
@@ -1364,9 +1354,7 @@
     return new VersionChangeEvent._internalWrap();
   }
 
-  factory VersionChangeEvent._internalWrap() {
-    return new VersionChangeEvent.internal_();
-  }
+  external factory VersionChangeEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   VersionChangeEvent.internal_() : super.internal_();
diff --git a/sdk/lib/io/platform.dart b/sdk/lib/io/platform.dart
index 326597f..d881ce5 100644
--- a/sdk/lib/io/platform.dart
+++ b/sdk/lib/io/platform.dart
@@ -181,20 +181,20 @@
   static List<String> get executableArguments => _Platform.executableArguments;
 
   /**
-   * Returns the value of the --package-root flag passed to the executable
+   * Returns the value of the `--package-root` flag passed to the executable
    * 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 null is returned.
+   * If there is no `--package-root` flag, `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
+ * 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.
+ * If there is no `--packages` flag, `null` is returned.
  */
   static String get packageConfig => _Platform.packageConfig;
 
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index ce2c5a2..d2b1f39 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -101,6 +101,26 @@
 @Deprecated("Internal Use Only")
 final bool CHECK_JS_INVOCATIONS = true;
 
+final String _DART_RESERVED_NAME_PREFIX = r'JS$';
+
+String _stripReservedNamePrefix(String name) =>
+    name.startsWith(_DART_RESERVED_NAME_PREFIX)
+        ? name.substring(_DART_RESERVED_NAME_PREFIX.length)
+        : name;
+
+_buildArgs(Invocation invocation) {
+  if (invocation.namedArguments.isEmpty) {
+    return invocation.positionalArguments;
+  } else {
+    var varArgs = new Map<String, Object>();
+    invocation.namedArguments.forEach((symbol, val) {
+      varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
+    });
+    return invocation.positionalArguments.toList()
+      ..add(maybeWrapTypedInterop(new JsObject.jsify(varArgs)));
+  }
+}
+
 final _allowedMethods = new Map<Symbol, _DeclarationSet>();
 final _allowedGetters = new Map<Symbol, _DeclarationSet>();
 final _allowedSetters = new Map<Symbol, _DeclarationSet>();
@@ -292,6 +312,20 @@
 
 bool _hasJsName(mirrors.DeclarationMirror mirror) => _getJsName(mirror) != null;
 
+bool hasDomName(mirrors.DeclarationMirror mirror) {
+  var location = mirror.location;
+  if (location == null || location.sourceUri.scheme != 'dart') return false;
+  for (var annotation in mirror.metadata) {
+    if (mirrors.MirrorSystem.getName(annotation.type.simpleName) == "DomName") {
+      // We can't make sure the annotation is in dart: as Dartium believes it
+      // is file://dart/sdk/lib/html/html_common/metadata.dart
+      // instead of a proper dart: location.
+      return true;
+    }
+  }
+  return false;
+}
+
 _getJsMemberName(mirrors.DeclarationMirror mirror) {
   var name = _getJsName(mirror);
   return name == null || name.isEmpty ? _getDeclarationName(mirror) : name;
@@ -304,7 +338,7 @@
     assert(name.endsWith("="));
     name = name.substring(0, name.length - 1);
   }
-  return name;
+  return _stripReservedNamePrefix(name);
 }
 
 final _JS_LIBRARY_PREFIX = "js_library";
@@ -347,16 +381,20 @@
   }
   sb.write(" ");
   if (declaration.isGetter) {
-    sb.write("get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});");
+    sb.write(
+        "get $name => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPath(path)});");
   } else if (declaration.isSetter) {
-    sb.write("set $name(v) => ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});");
+    sb.write("set $name(v) {\n"
+        "  ${_JS_LIBRARY_PREFIX}.safeForTypedInterop(v);\n"
+        "  return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(${_accessJsPathSetter(path)});\n"
+        "}\n");
   } else {
     sb.write("$name(");
     bool hasOptional = false;
     int i = 0;
     var args = <String>[];
     for (var p in declaration.parameters) {
-      assert(!p.isNamed); // XXX throw
+      assert(!p.isNamed); // TODO(jacobr): throw.
       assert(!p.hasDefaultValue);
       if (i > 0) {
         sb.write(", ");
@@ -377,8 +415,11 @@
       sb.write("]");
     }
     // TODO(jacobr):
-    sb.write(") => ");
-    sb.write('${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(');
+    sb.write(") {\n");
+    for (var arg in args) {
+      sb.write("  ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($arg);\n");
+    }
+    sb.write("  return ${_JS_LIBRARY_PREFIX}.maybeWrapTypedInterop(");
     if (declaration.isConstructor) {
       sb.write("new ${_JS_LIBRARY_PREFIX}.JsObject(");
     }
@@ -391,6 +432,7 @@
       sb.write(".takeWhile((i) => i != ${_UNDEFINED_VAR}).toList()");
     }
     sb.write("));");
+    sb.write("}\n");
   }
   sb.write("\n");
 }
@@ -399,7 +441,7 @@
   // This try-catch block is a workaround for BUG:24834.
   try {
     return mirror.isExternal;
-  } catch (e) { }
+  } catch (e) {}
   return false;
 }
 
@@ -416,195 +458,106 @@
         }
       } else if (declaration is mirrors.ClassMirror) {
         mirrors.ClassMirror clazz = declaration;
-        if (_hasJsName(clazz)) {
+        var isDom = hasDomName(clazz);
+        var isJsInterop = _hasJsName(clazz);
+        if (isDom || isJsInterop) {
           // TODO(jacobr): verify class implements JavaScriptObject.
-          String jsClassName = _getJsMemberName(clazz);
           var className = mirrors.MirrorSystem.getName(clazz.simpleName);
+          var classNameImpl = '${className}Impl';
           var sbPatch = new StringBuffer();
-          jsInterfaceTypes.add(clazz);
-          clazz.declarations.forEach((name, declaration) {
-            if (declaration is! mirrors.MethodMirror ||
-                !_isExternal(declaration)) return;
-            if (declaration.isFactoryConstructor && _isAnonymousClass(clazz)) {
-              sbPatch.write("  factory ${className}(");
-              int i = 0;
-              var args = <String>[];
-              for (var p in declaration.parameters) {
-                args.add(mirrors.MirrorSystem.getName(p.simpleName));
-                i++;
-              }
-              if (args.isNotEmpty) {
-                sbPatch
-                  ..write('{')
-                  ..write(
-                      args.map((name) => '$name:${_UNDEFINED_VAR}').join(", "))
-                  ..write('}');
-              }
-              sbPatch.write(") {\n"
+          if (isJsInterop) {
+            String jsClassName = _getJsMemberName(clazz);
+
+            jsInterfaceTypes.add(clazz);
+            clazz.declarations.forEach((name, declaration) {
+              if (declaration is! mirrors.MethodMirror ||
+                  !_isExternal(declaration)) return;
+              if (declaration.isFactoryConstructor &&
+                  _isAnonymousClass(clazz)) {
+                sbPatch.write("  factory ${className}(");
+                int i = 0;
+                var args = <String>[];
+                for (var p in declaration.parameters) {
+                  args.add(mirrors.MirrorSystem.getName(p.simpleName));
+                  i++;
+                }
+                if (args.isNotEmpty) {
+                  sbPatch
+                    ..write('{')
+                    ..write(args
+                        .map((name) => '$name:${_UNDEFINED_VAR}')
+                        .join(", "))
+                    ..write('}');
+                }
+                sbPatch.write(") {\n"
                     "    var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});\n");
-              i = 0;
-              for (var p in declaration.parameters) {
-                assert(p.isNamed); // XXX throw
-                var name = args[i];
-                var jsName = mirrors.MirrorSystem.getName(p.simpleName);
-                // XXX apply name conversion rules.
+                i = 0;
+                for (var p in declaration.parameters) {
+                  assert(p.isNamed); // TODO(jacobr): throw.
+                  var name = args[i];
+                  var jsName = _stripReservedNamePrefix(
+                      mirrors.MirrorSystem.getName(p.simpleName));
+                  sbPatch.write("    if($name != ${_UNDEFINED_VAR}) {\n"
+                      "      ${_JS_LIBRARY_PREFIX}.safeForTypedInterop($name);\n"
+                      "      ret['$jsName'] = $name;\n"
+                      "    }\n");
+                  i++;
+                }
+
                 sbPatch.write(
-                    "    if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n");
-                i++;
+                    "    return new ${_JS_LIBRARY_PREFIX}.JSObject.create(ret);\n"
+                    "  }\n");
+              } else if (declaration.isConstructor ||
+                  declaration.isFactoryConstructor) {
+                sbPatch.write("  ");
+                addMemberHelper(
+                    declaration,
+                    (jsLibraryName != null && jsLibraryName.isNotEmpty)
+                        ? "${jsLibraryName}.${jsClassName}"
+                        : jsClassName,
+                    sbPatch,
+                    isStatic: true,
+                    memberName: className);
               }
+            });
 
-              sbPatch.write("    return ret;\n"
-                  "  }\n");
-            } else if (declaration.isConstructor ||
-                declaration.isFactoryConstructor) {
-              sbPatch.write("  ");
-              addMemberHelper(
-                  declaration,
-                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                      ? "${jsLibraryName}.${jsClassName}"
-                      : jsClassName,
-                  sbPatch,
-                  isStatic: true,
-                  memberName: className);
-            }
-          });
-
-          clazz.staticMembers.forEach((memberName, member) {
-            if (_isExternal(member)) {
-              sbPatch.write("  ");
-              addMemberHelper(
-                  member,
-                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                      ? "${jsLibraryName}.${jsClassName}"
-                      : jsClassName,
-                  sbPatch,
-                  isStatic: true);
-            }
-          });
-          var typeVariablesClause = '';
-          if (!clazz.typeVariables.isEmpty) {
-            typeVariablesClause =
-                '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
+            clazz.staticMembers.forEach((memberName, member) {
+              if (_isExternal(member)) {
+                sbPatch.write("  ");
+                addMemberHelper(
+                    member,
+                    (jsLibraryName != null && jsLibraryName.isNotEmpty)
+                        ? "${jsLibraryName}.${jsClassName}"
+                        : jsClassName,
+                    sbPatch,
+                    isStatic: true);
+              }
+            });
+          }
+          if (isDom) {
+            sbPatch.write("  factory ${className}._internalWrap() => "
+                "new ${classNameImpl}.internal_();\n");
           }
           if (sbPatch.isNotEmpty) {
+            var typeVariablesClause = '';
+            if (!clazz.typeVariables.isEmpty) {
+              typeVariablesClause =
+                  '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
+            }
             sb.write("""
 patch class $className$typeVariablesClause {
 $sbPatch
 }
 """);
-          }
-        }
-      }
-    });
-    if (sb.isNotEmpty) {
-      staticCodegen
-        ..add(uri.toString())
-        ..add("${uri}_js_interop_patch.dart")
-        ..add("""
-import 'dart:js' as ${_JS_LIBRARY_PREFIX};
-
-/**
- * Placeholder object for cases where we need to determine exactly how many
- * args were passed to a function.
- */
-const ${_UNDEFINED_VAR} = const Object();
-
-${sb}
-""");
-    }
-  });
-
-  return staticCodegen;
-}
-
-List<String> _generateExternalMethods2() {
-  var staticCodegen = <String>[];
-  mirrors.currentMirrorSystem().libraries.forEach((uri, library) {
-    var sb = new StringBuffer();
-    String jsLibraryName = _getJsName(library);
-    library.declarations.forEach((name, declaration) {
-      var isExternal = _isExternal(declaration);
-      if (declaration is mirrors.MethodMirror) {
-        if (isExternal && (_hasJsName(declaration) || jsLibraryName != null)) {
-          addMemberHelper(declaration, jsLibraryName, sb);
-        }
-      } else if (declaration is mirrors.ClassMirror) {
-        mirrors.ClassMirror clazz = declaration;
-        if (_hasJsName(clazz)) {
-          // TODO(jacobr): verify class implements JavaScriptObject.
-          String jsClassName = _getJsMemberName(clazz);
-          var className = mirrors.MirrorSystem.getName(clazz.simpleName);
-          var sbPatch = new StringBuffer();
-          jsInterfaceTypes.add(clazz);
-          clazz.declarations.forEach((name, declaration) {
-            if (declaration is! mirrors.MethodMirror ||
-                !declaration.isAbstract ||
-                !isExternal) return;
-            if (_hasLiteralAnnotation(declaration) &&
-                declaration.isFactoryConstructor) {
-              sbPatch.write("  factory ${className}({");
-              int i = 0;
-              var args = <String>[];
-              for (var p in declaration.parameters) {
-                assert(p.isNamed); // XXX throw
-                args.add(mirrors.MirrorSystem.getName(p.simpleName));
-                i++;
-              }
-              sbPatch
-                ..write(
-                    args.map((name) => '$name:${_UNDEFINED_VAR}').join(", "))
-                ..write("}) {\n"
-                    "    var ret = new ${_JS_LIBRARY_PREFIX}.JsObject.jsify({});\n");
-              i = 0;
-              for (var p in declaration.parameters) {
-                assert(p.isNamed); // XXX throw
-                var name = args[i];
-                var jsName = mirrors.MirrorSystem.getName(p.simpleName);
-                // XXX apply name conversion rules.
-                sbPatch.write(
-                    "    if($name != ${_UNDEFINED_VAR}) ret['$jsName'] = $name;\n");
-                i++;
-              }
-
-              sbPatch.write("    return ret;\n"
-                  "  }\n");
-            } else if (declaration.isConstructor ||
-                declaration.isFactoryConstructor) {
-              sbPatch.write("  ");
-              addMemberHelper(
-                  declaration,
-                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                      ? "${jsLibraryName}.${jsClassName}"
-                      : jsClassName,
-                  sbPatch,
-                  isStatic: true,
-                  memberName: className);
-            }
-          });
-
-          clazz.staticMembers.forEach((memberName, member) {
-            if (_isExternal(member)) {
-              sbPatch.write("  ");
-              addMemberHelper(
-                  member,
-                  (jsLibraryName != null && jsLibraryName.isNotEmpty)
-                      ? "${jsLibraryName}.${jsClassName}"
-                      : jsClassName,
-                  sbPatch,
-                  isStatic: true);
-            }
-          });
-          var typeVariablesClause = '';
-          if (!clazz.typeVariables.isEmpty) {
-            typeVariablesClause =
-                '<${clazz.typeVariables.map((m) => mirrors.MirrorSystem.getName(m.simpleName)).join(',')}>';
-          }
-          if (sbPatch.isNotEmpty) {
-            sb.write("""
-patch class $className$typeVariablesClause {
-$sbPatch
+            if (isDom) {
+              sb.write("""
+class $classNameImpl$typeVariablesClause extends $className implements ${_JS_LIBRARY_PREFIX}.JSObjectInterfacesDom {
+  ${classNameImpl}.internal_() : super.internal_();
+  get runtimeType => $className;
+  toString() => super.toString();
 }
 """);
+            }
           }
         }
       }
@@ -631,9 +584,9 @@
 }
 
 /**
- * Generates a part file defining source code for JsObjectImpl and related
- * classes. This calass is needed so that type checks for all registered JavaScript
- * interop classes pass.
+ * Generates part files defining source code for JSObjectImpl, all DOM classes
+ * classes. This codegen  is needed so that type checks for all registered
+ * JavaScript interop classes pass.
  */
 List<String> _generateInteropPatchFiles() {
   var ret = _generateExternalMethods();
@@ -643,7 +596,10 @@
 
   var implements = <String>[];
   var implementsArray = <String>[];
+  var implementsDom = <String>[];
   var listMirror = mirrors.reflectType(List);
+  var functionMirror = mirrors.reflectType(Function);
+  var jsObjectMirror = mirrors.reflectType(JSObject);
 
   for (var typeMirror in jsInterfaceTypes) {
     mirrors.LibraryMirror libraryMirror = typeMirror.owner;
@@ -665,8 +621,25 @@
       libraryPrefixes[libraryMirror] = prefixName;
     }
     var isArray = typeMirror.isSubtypeOf(listMirror);
-    (isArray ? implementsArray : implements).add(
-        '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}');
+    var isFunction = typeMirror.isSubtypeOf(functionMirror);
+    var isJSObject = typeMirror.isSubtypeOf(jsObjectMirror);
+    var fullName =
+        '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}';
+    (isArray ? implementsArray : implements).add(fullName);
+    if (!isArray && !isFunction && !isJSObject) {
+      // For DOM classes we need to be a bit more conservative at tagging them
+      // as implementing JS inteorp classes risks strange unintended
+      // consequences as unrleated code may have instanceof checks.  Checking
+      // for isJSObject ensures we do not accidentally pull in existing
+      // dart:html classes as they all have JSObject as a base class.
+      // Note that methods from these classes can still be called on a
+      // dart:html instance but checked mode type checks will fail. This is
+      // not ideal but is better than causing strange breaks in existing
+      // code that uses dart:html.
+      // TODO(jacobr): consider throwing compile time errors if @JS classes
+      // extend JSObject as that case cannot be safely handled in Dartium.
+      implementsDom.add(fullName);
+    }
   }
   libraryPrefixes.forEach((libraryMirror, prefix) {
     sb.writeln('import "${libraryMirror.uri}" as $prefix;');
@@ -674,20 +647,51 @@
   buildImplementsClause(classes) =>
       classes.isEmpty ? "" : "implements ${classes.join(', ')}";
   var implementsClause = buildImplementsClause(implements);
+  var implementsClauseDom = buildImplementsClause(implementsDom);
   // TODO(jacobr): only certain classes need to be implemented by
   // JsFunctionImpl.
   var allTypes = []..addAll(implements)..addAll(implementsArray);
   sb.write('''
-class JsObjectImpl extends JsObject $implementsClause {
-  JsObjectImpl.internal() : super.internal();
+class JSObjectImpl extends JSObject $implementsClause {
+  JSObjectImpl.internal() : super.internal();
 }
 
-class JsFunctionImpl extends JsFunction $implementsClause {
-  JsFunctionImpl.internal() : super.internal();
+class JSFunctionImpl extends JSFunction $implementsClause {
+  JSFunctionImpl.internal() : super.internal();
 }
 
-class JsArrayImpl<E> extends JsArray<E> ${buildImplementsClause(implementsArray)} {
-  JsArrayImpl.internal() : super.internal();
+class JSArrayImpl extends JSArray ${buildImplementsClause(implementsArray)} {
+  JSArrayImpl.internal() : super.internal();
+}
+
+// Interfaces that are safe to slam on all DOM classes.
+// Adding implementsClause would be risky as it could contain Function which
+// is likely to break a lot of instanceof checks.
+abstract class JSObjectInterfacesDom $implementsClauseDom {
+}
+
+patch class JSObject {
+  factory JSObject.create(JsObject jsObject) {
+    var ret = new JSObjectImpl.internal()..blink_jsObject = jsObject;
+    jsObject._dartHtmlWrapper = ret;
+    return ret;
+  }
+}
+
+patch class JSFunction {
+  factory JSFunction.create(JsObject jsObject) {
+    var ret = new JSFunctionImpl.internal()..blink_jsObject = jsObject;
+    jsObject._dartHtmlWrapper = ret;
+    return ret;
+  }
+}
+
+patch class JSArray {
+  factory JSArray.create(JsObject jsObject) {
+    var ret = new JSArrayImpl.internal()..blink_jsObject = jsObject;
+    jsObject._dartHtmlWrapper = ret;
+    return ret;
+  }
 }
 
 _registerAllJsInterfaces() {
@@ -695,7 +699,7 @@
 }
 
 ''');
-  ret..addAll(["dart:js", "JsInteropImpl.dart", sb.toString()]);
+  ret..addAll(["dart:js", "JSInteropImpl.dart", sb.toString()]);
   return ret;
 }
 
@@ -870,8 +874,7 @@
 }
 
 @Deprecated("Internal Use Only")
-maybeWrapTypedInterop(o) =>
-    html_common.wrap_jso_no_SerializedScriptvalue(o);
+maybeWrapTypedInterop(o) => html_common.wrap_jso_no_SerializedScriptvalue(o);
 
 _maybeWrap(o) {
   var wrapped = html_common.wrap_jso_no_SerializedScriptvalue(o);
@@ -910,7 +913,7 @@
  */
 @Deprecated("Internal Use Only")
 unwrap_jso(dartClass_instance) {
-  if (dartClass_instance is html.DartHtmlDomObject &&
+  if (dartClass_instance is JSObject &&
       dartClass_instance is! JsObject) return dartClass_instance.blink_jsObject;
   else return dartClass_instance;
 }
@@ -946,19 +949,6 @@
   static JsObject _create(JsFunction constructor, arguments)
       native "JsObject_constructorCallback";
 
-  _buildArgs(Invocation invocation) {
-    if (invocation.namedArguments.isEmpty) {
-      return invocation.positionalArguments;
-    } else {
-      var varArgs = new Map<String, Object>();
-      invocation.namedArguments.forEach((symbol, val) {
-        varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
-      });
-      return invocation.positionalArguments.toList()
-        ..add(new JsObject.jsify(varArgs));
-    }
-  }
-
   /**
    * Constructs a [JsObject] that proxies a native Dart object; _for expert use
    * only_.
@@ -1099,13 +1089,28 @@
     }
   }
 
+  _callMethod(String name, List args) native "JsObject_callMethod";
+}
+
+/// Base class for all JS objects used through dart:html and typed JS interop.
+@Deprecated("Internal Use Only")
+class JSObject {
+  JSObject.internal() {}
+  external factory JSObject.create(JsObject jsObject);
+
+  @Deprecated("Internal Use Only")
+  JsObject blink_jsObject;
+
+  String toString() => blink_jsObject.toString();
+
   noSuchMethod(Invocation invocation) {
     throwError() {
-      throw new NoSuchMethodError(this, invocation.memberName,
-          invocation.positionalArguments, invocation.namedArguments);
+      super.noSuchMethod(invocation);
     }
 
-    String name = mirrors.MirrorSystem.getName(invocation.memberName);
+    String name = _stripReservedNamePrefix(
+        mirrors.MirrorSystem.getName(invocation.memberName));
+    argsSafeForTypedInterop(invocation.positionalArguments);
     if (invocation.isGetter) {
       if (CHECK_JS_INVOCATIONS) {
         var matches = _allowedGetters[invocation.memberName];
@@ -1113,8 +1118,8 @@
             !_allowedMethods.containsKey(invocation.memberName)) {
           throwError();
         }
-        var ret = this[name];
-        if (matches != null && matches._checkReturnType(ret)) return ret;
+        var ret = maybeWrapTypedInterop(blink_jsObject._operator_getter(name));
+        if (matches != null) return ret;
         if (ret is Function ||
             (ret is JsFunction /* shouldn't be needed in the future*/) &&
                 _allowedMethods.containsKey(
@@ -1122,7 +1127,7 @@
         throwError();
       } else {
         // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
-        return maybeWrapTypedInterop(this._operator_getter(name));
+        return maybeWrapTypedInterop(blink_jsObject._operator_getter(name));
       }
     } else if (invocation.isSetter) {
       if (CHECK_JS_INVOCATIONS) {
@@ -1132,7 +1137,7 @@
       }
       assert(name.endsWith("="));
       name = name.substring(0, name.length - 1);
-      return maybeWrapTypedInterop(_operator_setter(
+      return maybeWrapTypedInterop(blink_jsObject._operator_setter(
           name, invocation.positionalArguments.first));
     } else {
       // TODO(jacobr): also allow calling getters that look like functions.
@@ -1142,15 +1147,61 @@
         if (matches == null ||
             !matches.checkInvocation(invocation)) throwError();
       }
-      var ret = maybeWrapTypedInterop(this._callMethod(name, _buildArgs(invocation)));
+      var ret = maybeWrapTypedInterop(
+          blink_jsObject._callMethod(name, _buildArgs(invocation)));
       if (CHECK_JS_INVOCATIONS) {
-        if (!matches._checkReturnType(ret)) throwError();
+        if (!matches._checkReturnType(ret)) {
+          html.window.console.error("Return value for method: ${name} is "
+              "${ret.runtimeType} which is inconsistent with all typed "
+              "JS interop definitions for method ${name}.");
+        }
       }
       return ret;
     }
   }
+}
 
-  _callMethod(String name, List args) native "JsObject_callMethod";
+@Deprecated("Internal Use Only")
+class JSArray extends JSObject with ListMixin {
+  JSArray.internal() : super.internal();
+  external factory JSArray.create(JsObject jsObject);
+  operator [](int index) =>
+      maybeWrapTypedInterop(JsNative.getArrayIndex(blink_jsObject, index));
+
+  operator []=(int index, value) => blink_jsObject[index] = value;
+
+  int get length => blink_jsObject.length;
+  int set length(int newLength) => blink_jsObject.length = newLength;
+}
+
+@Deprecated("Internal Use Only")
+class JSFunction extends JSObject implements Function {
+  JSFunction.internal() : super.internal();
+
+  external factory JSFunction.create(JsObject jsObject);
+
+  call(
+      [a1 = _UNDEFINED,
+      a2 = _UNDEFINED,
+      a3 = _UNDEFINED,
+      a4 = _UNDEFINED,
+      a5 = _UNDEFINED,
+      a6 = _UNDEFINED,
+      a7 = _UNDEFINED,
+      a8 = _UNDEFINED,
+      a9 = _UNDEFINED,
+      a10 = _UNDEFINED]) {
+    return maybeWrapTypedInterop(blink_jsObject
+        .apply(_stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10])));
+  }
+
+  noSuchMethod(Invocation invocation) {
+    if (invocation.isMethod && invocation.memberName == #call) {
+      return maybeWrapTypedInterop(
+          blink_jsObject.apply(_buildArgs(invocation)));
+    }
+    return super.noSuchMethod(invocation);
+  }
 }
 
 // JavaScript interop methods that do not automatically wrap to dart:html types.
@@ -1185,7 +1236,7 @@
 /**
  * Proxies a JavaScript Function object.
  */
-class JsFunction extends JsObject implements Function {
+class JsFunction extends JsObject {
   JsFunction.internal() : super.internal();
 
   /**
@@ -1203,27 +1254,6 @@
 
   dynamic _apply(List args, {thisArg}) native "JsFunction_apply";
 
-  call([a1 = _UNDEFINED,
-        a2 = _UNDEFINED,
-        a3 = _UNDEFINED,
-        a4 = _UNDEFINED,
-        a5 = _UNDEFINED,
-        a6 = _UNDEFINED,
-        a7 = _UNDEFINED,
-        a8 = _UNDEFINED,
-        a9 = _UNDEFINED,
-        a10 = _UNDEFINED]) {
-    return apply(
-        _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
-  }
-
-  noSuchMethod(Invocation invocation) {
-    if (invocation.isMethod && invocation.memberName == #call) {
-      return apply(_buildArgs(invocation));
-    }
-    return super.noSuchMethod(invocation);
-  }
-
   /**
    * Internal only version of apply which uses debugger proxies of Dart objects
    * rather than opaque handles. This method is private because it cannot be
@@ -1349,6 +1379,39 @@
     args.takeWhile((i) => i != _UNDEFINED).toList();
 
 /**
+ * Check that that if [arg] is a [Function] it is safe to pass to JavaScript.
+ * To make a function safe, call [allowInterop] or [allowInteropCaptureThis].
+ */
+@Deprecated("Internal Use Only")
+safeForTypedInterop(arg) {
+  if (CHECK_JS_INVOCATIONS && arg is Function && arg is! JSFunction) {
+    throw new ArgumentError(
+        "Attempt to pass Function '$arg' to JavaScript via without calling allowInterop or allowInteropCaptureThis");
+  }
+}
+
+/**
+ * Check that that if any elements of [args] are [Function] it is safe to pass
+ * to JavaScript. To make a function safe, call [allowInterop] or
+ * [allowInteropCaptureThis].
+ */
+@Deprecated("Internal Use Only")
+void argsSafeForTypedInterop(Iterable args) {
+  for (var arg in args) {
+    safeForTypedInterop(arg);
+  }
+}
+
+List _stripAndWrapArgs(Iterable args) {
+  var ret = [];
+  for (var arg in args) {
+    if (arg == _UNDEFINED) break;
+    ret.add(maybeWrapTypedInterop(arg));
+  }
+  return ret;
+}
+
+/**
  * Returns a method that can be called with an arbitrary number (for n less
  * than 11) of arguments without violating Dart type checks.
  */
@@ -1366,9 +1429,89 @@
     jsFunction._applyDebuggerOnly(
         _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
 
-// The allowInterop method is a no-op in Dartium.
-// TODO(jacobr): tag methods so we can throw if a Dart method is passed to
-// JavaScript using the new interop without calling allowInterop.
+/// This helper is purely a hack so we can reuse JsFunction.withThis even when
+/// we don't care about passing JS "this". In an ideal world we would implement
+/// helpers in C++ that directly implement allowInterop and
+/// allowInteropCaptureThis.
+class _CreateDartFunctionForInteropIgnoreThis implements Function {
+  Function _fn;
+
+  _CreateDartFunctionForInteropIgnoreThis(this._fn);
+
+  call(
+      [ignoredThis = _UNDEFINED,
+      a1 = _UNDEFINED,
+      a2 = _UNDEFINED,
+      a3 = _UNDEFINED,
+      a4 = _UNDEFINED,
+      a5 = _UNDEFINED,
+      a6 = _UNDEFINED,
+      a7 = _UNDEFINED,
+      a8 = _UNDEFINED,
+      a9 = _UNDEFINED,
+      a10 = _UNDEFINED]) {
+    var ret = Function.apply(
+        _fn, _stripAndWrapArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
+    safeForTypedInterop(ret);
+    return ret;
+  }
+
+  noSuchMethod(Invocation invocation) {
+    if (invocation.isMethod && invocation.memberName == #call) {
+      // Named arguments not yet supported.
+      if (invocation.namedArguments.isNotEmpty) return;
+      var ret = Function.apply(
+          _fn, _stripAndWrapArgs(invocation.positionalArguments.skip(1)));
+      // TODO(jacobr): it would be nice to check that the return value is safe
+      // for interop but we don't want to break existing addEventListener users.
+      // safeForTypedInterop(ret);
+      safeForTypedInterop(ret);
+      return ret;
+    }
+    return super.noSuchMethod(invocation);
+  }
+}
+
+/// See comment for [_CreateDartFunctionForInteropIgnoreThis].
+/// This Function exists purely because JsObject doesn't have the DOM type
+/// conversion semantics we want for JS typed interop.
+class _CreateDartFunctionForInterop implements Function {
+  Function _fn;
+
+  _CreateDartFunctionForInterop(this._fn);
+
+  call(
+      [a1 = _UNDEFINED,
+      a2 = _UNDEFINED,
+      a3 = _UNDEFINED,
+      a4 = _UNDEFINED,
+      a5 = _UNDEFINED,
+      a6 = _UNDEFINED,
+      a7 = _UNDEFINED,
+      a8 = _UNDEFINED,
+      a9 = _UNDEFINED,
+      a10 = _UNDEFINED]) {
+    var ret = Function.apply(
+        _fn, _stripAndWrapArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
+    safeForTypedInterop(ret);
+    return ret;
+  }
+
+  noSuchMethod(Invocation invocation) {
+    if (invocation.isMethod && invocation.memberName == #call) {
+      // Named arguments not yet supported.
+      if (invocation.namedArguments.isNotEmpty) return;
+      var ret = Function.apply(
+          _fn, _stripAndWrapArgs(invocation.positionalArguments));
+      safeForTypedInterop(ret);
+      return ret;
+    }
+    return super.noSuchMethod(invocation);
+  }
+}
+
+/// Cached JSFunction associated with the Dart Function.
+Expando<JSFunction> _interopExpando = new Expando<JSFunction>();
 
 /// Returns a wrapper around function [f] that can be called from JavaScript
 /// using the package:js Dart-JavaScript interop.
@@ -1381,9 +1524,25 @@
 /// JavaScript. We may remove the need to call this method completely in the
 /// future if Dart2Js is refactored so that its function calling conventions
 /// are more compatible with JavaScript.
-Function allowInterop(Function f) => f;
+JSFunction allowInterop(Function f) {
+  if (f is JSFunction) {
+    // The function is already a JSFunction... no need to do anything.
+    return f;
+  } else {
+    var ret = _interopExpando[f];
+    if (ret == null) {
+      // TODO(jacobr): we could optimize this.
+      ret = new JSFunction.create(new JsFunction.withThis(
+          new _CreateDartFunctionForInteropIgnoreThis(f)));
+      _interopExpando[f] = ret;
+    }
+    return ret;
+  }
+}
 
-Expando<JsFunction> _interopCaptureThisExpando = new Expando<JsFunction>();
+/// Cached JSFunction associated with the Dart function when "this" is
+/// captured.
+Expando<JSFunction> _interopCaptureThisExpando = new Expando<JSFunction>();
 
 /// Returns a [Function] that when called from JavaScript captures its 'this'
 /// binding and calls [f] with the value of this passed as the first argument.
@@ -1391,8 +1550,8 @@
 ///
 /// See the documention for [allowInterop]. This method should only be used with
 /// package:js Dart-JavaScript interop.
-Function allowInteropCaptureThis(Function f) {
-  if (f is JsFunction) {
+JSFunction allowInteropCaptureThis(Function f) {
+  if (f is JSFunction) {
     // Behavior when the function is already a JS function is unspecified.
     throw new ArgumentError(
         "Function is already a JS function so cannot capture this.");
@@ -1400,7 +1559,9 @@
   } else {
     var ret = _interopCaptureThisExpando[f];
     if (ret == null) {
-      ret = new JsFunction.withThis(f);
+      // TODO(jacobr): we could optimize this.
+      ret = new JSFunction.create(
+          new JsFunction.withThis(new _CreateDartFunctionForInterop(f)));
       _interopCaptureThisExpando[f] = ret;
     }
     return ret;
diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart
index c093cab..7795952 100644
--- a/sdk/lib/svg/dartium/svg_dartium.dart
+++ b/sdk/lib/svg/dartium/svg_dartium.dart
@@ -349,9 +349,7 @@
     return new AElement._internalWrap();
   }
 
-  factory AElement._internalWrap() {
-    return new AElement.internal_();
-  }
+  external factory AElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AElement.internal_() : super.internal_();
@@ -399,9 +397,7 @@
     return new AltGlyphElement._internalWrap();
   }
 
-  factory AltGlyphElement._internalWrap() {
-    return new AltGlyphElement.internal_();
-  }
+  external factory AltGlyphElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AltGlyphElement.internal_() : super.internal_();
@@ -550,9 +546,7 @@
     return new AnimateElement._internalWrap();
   }
 
-  factory AnimateElement._internalWrap() {
-    return new AnimateElement.internal_();
-  }
+  external factory AnimateElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimateElement.internal_() : super.internal_();
@@ -595,9 +589,7 @@
     return new AnimateMotionElement._internalWrap();
   }
 
-  factory AnimateMotionElement._internalWrap() {
-    return new AnimateMotionElement.internal_();
-  }
+  external factory AnimateMotionElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimateMotionElement.internal_() : super.internal_();
@@ -640,9 +632,7 @@
     return new AnimateTransformElement._internalWrap();
   }
 
-  factory AnimateTransformElement._internalWrap() {
-    return new AnimateTransformElement.internal_();
-  }
+  external factory AnimateTransformElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimateTransformElement.internal_() : super.internal_();
@@ -1158,9 +1148,7 @@
     return new AnimationElement._internalWrap();
   }
 
-  factory AnimationElement._internalWrap() {
-    return new AnimationElement.internal_();
-  }
+  external factory AnimationElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnimationElement.internal_() : super.internal_();
@@ -1245,9 +1233,7 @@
     return new CircleElement._internalWrap();
   }
 
-  factory CircleElement._internalWrap() {
-    return new CircleElement.internal_();
-  }
+  external factory CircleElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   CircleElement.internal_() : super.internal_();
@@ -1296,9 +1282,7 @@
     return new ClipPathElement._internalWrap();
   }
 
-  factory ClipPathElement._internalWrap() {
-    return new ClipPathElement.internal_();
-  }
+  external factory ClipPathElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ClipPathElement.internal_() : super.internal_();
@@ -1339,9 +1323,7 @@
     return new DefsElement._internalWrap();
   }
 
-  factory DefsElement._internalWrap() {
-    return new DefsElement.internal_();
-  }
+  external factory DefsElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DefsElement.internal_() : super.internal_();
@@ -1378,9 +1360,7 @@
     return new DescElement._internalWrap();
   }
 
-  factory DescElement._internalWrap() {
-    return new DescElement.internal_();
-  }
+  external factory DescElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DescElement.internal_() : super.internal_();
@@ -1413,9 +1393,7 @@
     return new DiscardElement._internalWrap();
   }
 
-  factory DiscardElement._internalWrap() {
-    return new DiscardElement.internal_();
-  }
+  external factory DiscardElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   DiscardElement.internal_() : super.internal_();
@@ -1452,9 +1430,7 @@
     return new EllipseElement._internalWrap();
   }
 
-  factory EllipseElement._internalWrap() {
-    return new EllipseElement.internal_();
-  }
+  external factory EllipseElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   EllipseElement.internal_() : super.internal_();
@@ -1511,9 +1487,7 @@
     return new FEBlendElement._internalWrap();
   }
 
-  factory FEBlendElement._internalWrap() {
-    return new FEBlendElement.internal_();
-  }
+  external factory FEBlendElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEBlendElement.internal_() : super.internal_();
@@ -1613,9 +1587,7 @@
     return new FEColorMatrixElement._internalWrap();
   }
 
-  factory FEColorMatrixElement._internalWrap() {
-    return new FEColorMatrixElement.internal_();
-  }
+  external factory FEColorMatrixElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEColorMatrixElement.internal_() : super.internal_();
@@ -1711,9 +1683,7 @@
     return new FEComponentTransferElement._internalWrap();
   }
 
-  factory FEComponentTransferElement._internalWrap() {
-    return new FEComponentTransferElement.internal_();
-  }
+  external factory FEComponentTransferElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEComponentTransferElement.internal_() : super.internal_();
@@ -1773,9 +1743,7 @@
     return new FECompositeElement._internalWrap();
   }
 
-  factory FECompositeElement._internalWrap() {
-    return new FECompositeElement.internal_();
-  }
+  external factory FECompositeElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FECompositeElement.internal_() : super.internal_();
@@ -1892,9 +1860,7 @@
     return new FEConvolveMatrixElement._internalWrap();
   }
 
-  factory FEConvolveMatrixElement._internalWrap() {
-    return new FEConvolveMatrixElement.internal_();
-  }
+  external factory FEConvolveMatrixElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEConvolveMatrixElement.internal_() : super.internal_();
@@ -2022,9 +1988,7 @@
     return new FEDiffuseLightingElement._internalWrap();
   }
 
-  factory FEDiffuseLightingElement._internalWrap() {
-    return new FEDiffuseLightingElement.internal_();
-  }
+  external factory FEDiffuseLightingElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEDiffuseLightingElement.internal_() : super.internal_();
@@ -2108,9 +2072,7 @@
     return new FEDisplacementMapElement._internalWrap();
   }
 
-  factory FEDisplacementMapElement._internalWrap() {
-    return new FEDisplacementMapElement.internal_();
-  }
+  external factory FEDisplacementMapElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEDisplacementMapElement.internal_() : super.internal_();
@@ -2214,9 +2176,7 @@
     return new FEDistantLightElement._internalWrap();
   }
 
-  factory FEDistantLightElement._internalWrap() {
-    return new FEDistantLightElement.internal_();
-  }
+  external factory FEDistantLightElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEDistantLightElement.internal_() : super.internal_();
@@ -2268,9 +2228,7 @@
     return new FEFloodElement._internalWrap();
   }
 
-  factory FEFloodElement._internalWrap() {
-    return new FEFloodElement.internal_();
-  }
+  external factory FEFloodElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEFloodElement.internal_() : super.internal_();
@@ -2334,9 +2292,7 @@
     return new FEFuncAElement._internalWrap();
   }
 
-  factory FEFuncAElement._internalWrap() {
-    return new FEFuncAElement.internal_();
-  }
+  external factory FEFuncAElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEFuncAElement.internal_() : super.internal_();
@@ -2380,9 +2336,7 @@
     return new FEFuncBElement._internalWrap();
   }
 
-  factory FEFuncBElement._internalWrap() {
-    return new FEFuncBElement.internal_();
-  }
+  external factory FEFuncBElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEFuncBElement.internal_() : super.internal_();
@@ -2426,9 +2380,7 @@
     return new FEFuncGElement._internalWrap();
   }
 
-  factory FEFuncGElement._internalWrap() {
-    return new FEFuncGElement.internal_();
-  }
+  external factory FEFuncGElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEFuncGElement.internal_() : super.internal_();
@@ -2472,9 +2424,7 @@
     return new FEFuncRElement._internalWrap();
   }
 
-  factory FEFuncRElement._internalWrap() {
-    return new FEFuncRElement.internal_();
-  }
+  external factory FEFuncRElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEFuncRElement.internal_() : super.internal_();
@@ -2518,9 +2468,7 @@
     return new FEGaussianBlurElement._internalWrap();
   }
 
-  factory FEGaussianBlurElement._internalWrap() {
-    return new FEGaussianBlurElement.internal_();
-  }
+  external factory FEGaussianBlurElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEGaussianBlurElement.internal_() : super.internal_();
@@ -2600,9 +2548,7 @@
     return new FEImageElement._internalWrap();
   }
 
-  factory FEImageElement._internalWrap() {
-    return new FEImageElement.internal_();
-  }
+  external factory FEImageElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEImageElement.internal_() : super.internal_();
@@ -2674,9 +2620,7 @@
     return new FEMergeElement._internalWrap();
   }
 
-  factory FEMergeElement._internalWrap() {
-    return new FEMergeElement.internal_();
-  }
+  external factory FEMergeElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEMergeElement.internal_() : super.internal_();
@@ -2740,9 +2684,7 @@
     return new FEMergeNodeElement._internalWrap();
   }
 
-  factory FEMergeNodeElement._internalWrap() {
-    return new FEMergeNodeElement.internal_();
-  }
+  external factory FEMergeNodeElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEMergeNodeElement.internal_() : super.internal_();
@@ -2786,9 +2728,7 @@
     return new FEMorphologyElement._internalWrap();
   }
 
-  factory FEMorphologyElement._internalWrap() {
-    return new FEMorphologyElement.internal_();
-  }
+  external factory FEMorphologyElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEMorphologyElement.internal_() : super.internal_();
@@ -2877,9 +2817,7 @@
     return new FEOffsetElement._internalWrap();
   }
 
-  factory FEOffsetElement._internalWrap() {
-    return new FEOffsetElement.internal_();
-  }
+  external factory FEOffsetElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEOffsetElement.internal_() : super.internal_();
@@ -2955,9 +2893,7 @@
     return new FEPointLightElement._internalWrap();
   }
 
-  factory FEPointLightElement._internalWrap() {
-    return new FEPointLightElement.internal_();
-  }
+  external factory FEPointLightElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FEPointLightElement.internal_() : super.internal_();
@@ -3013,9 +2949,7 @@
     return new FESpecularLightingElement._internalWrap();
   }
 
-  factory FESpecularLightingElement._internalWrap() {
-    return new FESpecularLightingElement.internal_();
-  }
+  external factory FESpecularLightingElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FESpecularLightingElement.internal_() : super.internal_();
@@ -3095,9 +3029,7 @@
     return new FESpotLightElement._internalWrap();
   }
 
-  factory FESpotLightElement._internalWrap() {
-    return new FESpotLightElement.internal_();
-  }
+  external factory FESpotLightElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FESpotLightElement.internal_() : super.internal_();
@@ -3173,9 +3105,7 @@
     return new FETileElement._internalWrap();
   }
 
-  factory FETileElement._internalWrap() {
-    return new FETileElement.internal_();
-  }
+  external factory FETileElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FETileElement.internal_() : super.internal_();
@@ -3243,9 +3173,7 @@
     return new FETurbulenceElement._internalWrap();
   }
 
-  factory FETurbulenceElement._internalWrap() {
-    return new FETurbulenceElement.internal_();
-  }
+  external factory FETurbulenceElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FETurbulenceElement.internal_() : super.internal_();
@@ -3357,9 +3285,7 @@
     return new FilterElement._internalWrap();
   }
 
-  factory FilterElement._internalWrap() {
-    return new FilterElement.internal_();
-  }
+  external factory FilterElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   FilterElement.internal_() : super.internal_();
@@ -3500,9 +3426,7 @@
     return new ForeignObjectElement._internalWrap();
   }
 
-  factory ForeignObjectElement._internalWrap() {
-    return new ForeignObjectElement.internal_();
-  }
+  external factory ForeignObjectElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ForeignObjectElement.internal_() : super.internal_();
@@ -3558,9 +3482,7 @@
     return new GElement._internalWrap();
   }
 
-  factory GElement._internalWrap() {
-    return new GElement.internal_();
-  }
+  external factory GElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   GElement.internal_() : super.internal_();
@@ -3593,9 +3515,7 @@
     return new GeometryElement._internalWrap();
   }
 
-  factory GeometryElement._internalWrap() {
-    return new GeometryElement.internal_();
-  }
+  external factory GeometryElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   GeometryElement.internal_() : super.internal_();
@@ -3638,9 +3558,7 @@
     return new GraphicsElement._internalWrap();
   }
 
-  factory GraphicsElement._internalWrap() {
-    return new GraphicsElement.internal_();
-  }
+  external factory GraphicsElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   GraphicsElement.internal_() : super.internal_();
@@ -3732,9 +3650,7 @@
     return new ImageElement._internalWrap();
   }
 
-  factory ImageElement._internalWrap() {
-    return new ImageElement.internal_();
-  }
+  external factory ImageElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ImageElement.internal_() : super.internal_();
@@ -4021,9 +3937,7 @@
     return new LineElement._internalWrap();
   }
 
-  factory LineElement._internalWrap() {
-    return new LineElement.internal_();
-  }
+  external factory LineElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LineElement.internal_() : super.internal_();
@@ -4076,9 +3990,7 @@
     return new LinearGradientElement._internalWrap();
   }
 
-  factory LinearGradientElement._internalWrap() {
-    return new LinearGradientElement.internal_();
-  }
+  external factory LinearGradientElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   LinearGradientElement.internal_() : super.internal_();
@@ -4131,9 +4043,7 @@
     return new MarkerElement._internalWrap();
   }
 
-  factory MarkerElement._internalWrap() {
-    return new MarkerElement.internal_();
-  }
+  external factory MarkerElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MarkerElement.internal_() : super.internal_();
@@ -4238,9 +4148,7 @@
     return new MaskElement._internalWrap();
   }
 
-  factory MaskElement._internalWrap() {
-    return new MaskElement.internal_();
-  }
+  external factory MaskElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MaskElement.internal_() : super.internal_();
@@ -4435,9 +4343,7 @@
     return new MetadataElement._internalWrap();
   }
 
-  factory MetadataElement._internalWrap() {
-    return new MetadataElement.internal_();
-  }
+  external factory MetadataElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   MetadataElement.internal_() : super.internal_();
@@ -4628,9 +4534,7 @@
     return new PathElement._internalWrap();
   }
 
-  factory PathElement._internalWrap() {
-    return new PathElement.internal_();
-  }
+  external factory PathElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathElement.internal_() : super.internal_();
@@ -4889,9 +4793,7 @@
     return new PathSegArcAbs._internalWrap();
   }
 
-  factory PathSegArcAbs._internalWrap() {
-    return new PathSegArcAbs.internal_();
-  }
+  external factory PathSegArcAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegArcAbs.internal_() : super.internal_();
@@ -4974,9 +4876,7 @@
     return new PathSegArcRel._internalWrap();
   }
 
-  factory PathSegArcRel._internalWrap() {
-    return new PathSegArcRel.internal_();
-  }
+  external factory PathSegArcRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegArcRel.internal_() : super.internal_();
@@ -5059,9 +4959,7 @@
     return new PathSegClosePath._internalWrap();
   }
 
-  factory PathSegClosePath._internalWrap() {
-    return new PathSegClosePath.internal_();
-  }
+  external factory PathSegClosePath._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegClosePath.internal_() : super.internal_();
@@ -5088,9 +4986,7 @@
     return new PathSegCurvetoCubicAbs._internalWrap();
   }
 
-  factory PathSegCurvetoCubicAbs._internalWrap() {
-    return new PathSegCurvetoCubicAbs.internal_();
-  }
+  external factory PathSegCurvetoCubicAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoCubicAbs.internal_() : super.internal_();
@@ -5165,9 +5061,7 @@
     return new PathSegCurvetoCubicRel._internalWrap();
   }
 
-  factory PathSegCurvetoCubicRel._internalWrap() {
-    return new PathSegCurvetoCubicRel.internal_();
-  }
+  external factory PathSegCurvetoCubicRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoCubicRel.internal_() : super.internal_();
@@ -5242,9 +5136,7 @@
     return new PathSegCurvetoCubicSmoothAbs._internalWrap();
   }
 
-  factory PathSegCurvetoCubicSmoothAbs._internalWrap() {
-    return new PathSegCurvetoCubicSmoothAbs.internal_();
-  }
+  external factory PathSegCurvetoCubicSmoothAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoCubicSmoothAbs.internal_() : super.internal_();
@@ -5303,9 +5195,7 @@
     return new PathSegCurvetoCubicSmoothRel._internalWrap();
   }
 
-  factory PathSegCurvetoCubicSmoothRel._internalWrap() {
-    return new PathSegCurvetoCubicSmoothRel.internal_();
-  }
+  external factory PathSegCurvetoCubicSmoothRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoCubicSmoothRel.internal_() : super.internal_();
@@ -5364,9 +5254,7 @@
     return new PathSegCurvetoQuadraticAbs._internalWrap();
   }
 
-  factory PathSegCurvetoQuadraticAbs._internalWrap() {
-    return new PathSegCurvetoQuadraticAbs.internal_();
-  }
+  external factory PathSegCurvetoQuadraticAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoQuadraticAbs.internal_() : super.internal_();
@@ -5425,9 +5313,7 @@
     return new PathSegCurvetoQuadraticRel._internalWrap();
   }
 
-  factory PathSegCurvetoQuadraticRel._internalWrap() {
-    return new PathSegCurvetoQuadraticRel.internal_();
-  }
+  external factory PathSegCurvetoQuadraticRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoQuadraticRel.internal_() : super.internal_();
@@ -5486,9 +5372,7 @@
     return new PathSegCurvetoQuadraticSmoothAbs._internalWrap();
   }
 
-  factory PathSegCurvetoQuadraticSmoothAbs._internalWrap() {
-    return new PathSegCurvetoQuadraticSmoothAbs.internal_();
-  }
+  external factory PathSegCurvetoQuadraticSmoothAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoQuadraticSmoothAbs.internal_() : super.internal_();
@@ -5531,9 +5415,7 @@
     return new PathSegCurvetoQuadraticSmoothRel._internalWrap();
   }
 
-  factory PathSegCurvetoQuadraticSmoothRel._internalWrap() {
-    return new PathSegCurvetoQuadraticSmoothRel.internal_();
-  }
+  external factory PathSegCurvetoQuadraticSmoothRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegCurvetoQuadraticSmoothRel.internal_() : super.internal_();
@@ -5576,9 +5458,7 @@
     return new PathSegLinetoAbs._internalWrap();
   }
 
-  factory PathSegLinetoAbs._internalWrap() {
-    return new PathSegLinetoAbs.internal_();
-  }
+  external factory PathSegLinetoAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoAbs.internal_() : super.internal_();
@@ -5621,9 +5501,7 @@
     return new PathSegLinetoHorizontalAbs._internalWrap();
   }
 
-  factory PathSegLinetoHorizontalAbs._internalWrap() {
-    return new PathSegLinetoHorizontalAbs.internal_();
-  }
+  external factory PathSegLinetoHorizontalAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoHorizontalAbs.internal_() : super.internal_();
@@ -5658,9 +5536,7 @@
     return new PathSegLinetoHorizontalRel._internalWrap();
   }
 
-  factory PathSegLinetoHorizontalRel._internalWrap() {
-    return new PathSegLinetoHorizontalRel.internal_();
-  }
+  external factory PathSegLinetoHorizontalRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoHorizontalRel.internal_() : super.internal_();
@@ -5695,9 +5571,7 @@
     return new PathSegLinetoRel._internalWrap();
   }
 
-  factory PathSegLinetoRel._internalWrap() {
-    return new PathSegLinetoRel.internal_();
-  }
+  external factory PathSegLinetoRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoRel.internal_() : super.internal_();
@@ -5740,9 +5614,7 @@
     return new PathSegLinetoVerticalAbs._internalWrap();
   }
 
-  factory PathSegLinetoVerticalAbs._internalWrap() {
-    return new PathSegLinetoVerticalAbs.internal_();
-  }
+  external factory PathSegLinetoVerticalAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoVerticalAbs.internal_() : super.internal_();
@@ -5777,9 +5649,7 @@
     return new PathSegLinetoVerticalRel._internalWrap();
   }
 
-  factory PathSegLinetoVerticalRel._internalWrap() {
-    return new PathSegLinetoVerticalRel.internal_();
-  }
+  external factory PathSegLinetoVerticalRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegLinetoVerticalRel.internal_() : super.internal_();
@@ -5930,9 +5800,7 @@
     return new PathSegMovetoAbs._internalWrap();
   }
 
-  factory PathSegMovetoAbs._internalWrap() {
-    return new PathSegMovetoAbs.internal_();
-  }
+  external factory PathSegMovetoAbs._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegMovetoAbs.internal_() : super.internal_();
@@ -5975,9 +5843,7 @@
     return new PathSegMovetoRel._internalWrap();
   }
 
-  factory PathSegMovetoRel._internalWrap() {
-    return new PathSegMovetoRel.internal_();
-  }
+  external factory PathSegMovetoRel._internalWrap();
 
   @Deprecated("Internal Use Only")
   PathSegMovetoRel.internal_() : super.internal_();
@@ -6024,9 +5890,7 @@
     return new PatternElement._internalWrap();
   }
 
-  factory PatternElement._internalWrap() {
-    return new PatternElement.internal_();
-  }
+  external factory PatternElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PatternElement.internal_() : super.internal_();
@@ -6241,9 +6105,7 @@
     return new PolygonElement._internalWrap();
   }
 
-  factory PolygonElement._internalWrap() {
-    return new PolygonElement.internal_();
-  }
+  external factory PolygonElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PolygonElement.internal_() : super.internal_();
@@ -6288,9 +6150,7 @@
     return new PolylineElement._internalWrap();
   }
 
-  factory PolylineElement._internalWrap() {
-    return new PolylineElement.internal_();
-  }
+  external factory PolylineElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   PolylineElement.internal_() : super.internal_();
@@ -6437,9 +6297,7 @@
     return new RadialGradientElement._internalWrap();
   }
 
-  factory RadialGradientElement._internalWrap() {
-    return new RadialGradientElement.internal_();
-  }
+  external factory RadialGradientElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   RadialGradientElement.internal_() : super.internal_();
@@ -6562,9 +6420,7 @@
     return new RectElement._internalWrap();
   }
 
-  factory RectElement._internalWrap() {
-    return new RectElement.internal_();
-  }
+  external factory RectElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   RectElement.internal_() : super.internal_();
@@ -6679,9 +6535,7 @@
     return new ScriptElement._internalWrap();
   }
 
-  factory ScriptElement._internalWrap() {
-    return new ScriptElement.internal_();
-  }
+  external factory ScriptElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ScriptElement.internal_() : super.internal_();
@@ -6733,9 +6587,7 @@
     return new SetElement._internalWrap();
   }
 
-  factory SetElement._internalWrap() {
-    return new SetElement.internal_();
-  }
+  external factory SetElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SetElement.internal_() : super.internal_();
@@ -6775,9 +6627,7 @@
     return new StopElement._internalWrap();
   }
 
-  factory StopElement._internalWrap() {
-    return new StopElement.internal_();
-  }
+  external factory StopElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   StopElement.internal_() : super.internal_();
@@ -6935,9 +6785,7 @@
     return new StyleElement._internalWrap();
   }
 
-  factory StyleElement._internalWrap() {
-    return new StyleElement.internal_();
-  }
+  external factory StyleElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   StyleElement.internal_() : super.internal_();
@@ -7416,9 +7264,7 @@
     return new SvgElement._internalWrap();
   }
 
-  factory SvgElement._internalWrap() {
-    return new SvgElement.internal_();
-  }
+  external factory SvgElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SvgElement.internal_() : super.internal_();
@@ -7771,9 +7617,7 @@
     return new SvgSvgElement._internalWrap();
   }
 
-  factory SvgSvgElement._internalWrap() {
-    return new SvgSvgElement.internal_();
-  }
+  external factory SvgSvgElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SvgSvgElement.internal_() : super.internal_();
@@ -7974,9 +7818,7 @@
     return new SwitchElement._internalWrap();
   }
 
-  factory SwitchElement._internalWrap() {
-    return new SwitchElement.internal_();
-  }
+  external factory SwitchElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SwitchElement.internal_() : super.internal_();
@@ -8013,9 +7855,7 @@
     return new SymbolElement._internalWrap();
   }
 
-  factory SymbolElement._internalWrap() {
-    return new SymbolElement.internal_();
-  }
+  external factory SymbolElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   SymbolElement.internal_() : super.internal_();
@@ -8060,9 +7900,7 @@
     return new TSpanElement._internalWrap();
   }
 
-  factory TSpanElement._internalWrap() {
-    return new TSpanElement.internal_();
-  }
+  external factory TSpanElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TSpanElement.internal_() : super.internal_();
@@ -8126,9 +7964,7 @@
     return new TextContentElement._internalWrap();
   }
 
-  factory TextContentElement._internalWrap() {
-    return new TextContentElement.internal_();
-  }
+  external factory TextContentElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextContentElement.internal_() : super.internal_();
@@ -8221,9 +8057,7 @@
     return new TextElement._internalWrap();
   }
 
-  factory TextElement._internalWrap() {
-    return new TextElement.internal_();
-  }
+  external factory TextElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextElement.internal_() : super.internal_();
@@ -8256,9 +8090,7 @@
     return new TextPathElement._internalWrap();
   }
 
-  factory TextPathElement._internalWrap() {
-    return new TextPathElement.internal_();
-  }
+  external factory TextPathElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextPathElement.internal_() : super.internal_();
@@ -8331,9 +8163,7 @@
     return new TextPositioningElement._internalWrap();
   }
 
-  factory TextPositioningElement._internalWrap() {
-    return new TextPositioningElement.internal_();
-  }
+  external factory TextPositioningElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TextPositioningElement.internal_() : super.internal_();
@@ -8390,9 +8220,7 @@
     return new TitleElement._internalWrap();
   }
 
-  factory TitleElement._internalWrap() {
-    return new TitleElement.internal_();
-  }
+  external factory TitleElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   TitleElement.internal_() : super.internal_();
@@ -8708,9 +8536,7 @@
     return new UseElement._internalWrap();
   }
 
-  factory UseElement._internalWrap() {
-    return new UseElement.internal_();
-  }
+  external factory UseElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   UseElement.internal_() : super.internal_();
@@ -8767,9 +8593,7 @@
     return new ViewElement._internalWrap();
   }
 
-  factory ViewElement._internalWrap() {
-    return new ViewElement.internal_();
-  }
+  external factory ViewElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   ViewElement.internal_() : super.internal_();
@@ -8931,9 +8755,7 @@
     return new ZoomEvent._internalWrap();
   }
 
-  factory ZoomEvent._internalWrap() {
-    return new ZoomEvent.internal_();
-  }
+  external factory ZoomEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ZoomEvent.internal_() : super.internal_();
@@ -8980,9 +8802,7 @@
     return new _GradientElement._internalWrap();
   }
 
-  factory _GradientElement._internalWrap() {
-    return new _GradientElement.internal_();
-  }
+  external factory _GradientElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _GradientElement.internal_() : super.internal_();
@@ -9047,9 +8867,7 @@
     return new _SVGAltGlyphDefElement._internalWrap();
   }
 
-  factory _SVGAltGlyphDefElement._internalWrap() {
-    return new _SVGAltGlyphDefElement.internal_();
-  }
+  external factory _SVGAltGlyphDefElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGAltGlyphDefElement.internal_() : super.internal_();
@@ -9082,9 +8900,7 @@
     return new _SVGAltGlyphItemElement._internalWrap();
   }
 
-  factory _SVGAltGlyphItemElement._internalWrap() {
-    return new _SVGAltGlyphItemElement.internal_();
-  }
+  external factory _SVGAltGlyphItemElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGAltGlyphItemElement.internal_() : super.internal_();
@@ -9117,9 +8933,7 @@
     return new _SVGComponentTransferFunctionElement._internalWrap();
   }
 
-  factory _SVGComponentTransferFunctionElement._internalWrap() {
-    return new _SVGComponentTransferFunctionElement.internal_();
-  }
+  external factory _SVGComponentTransferFunctionElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGComponentTransferFunctionElement.internal_() : super.internal_();
@@ -9154,9 +8968,7 @@
     return new _SVGCursorElement._internalWrap();
   }
 
-  factory _SVGCursorElement._internalWrap() {
-    return new _SVGCursorElement.internal_();
-  }
+  external factory _SVGCursorElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGCursorElement.internal_() : super.internal_();
@@ -9197,9 +9009,7 @@
     return new _SVGFEDropShadowElement._internalWrap();
   }
 
-  factory _SVGFEDropShadowElement._internalWrap() {
-    return new _SVGFEDropShadowElement.internal_();
-  }
+  external factory _SVGFEDropShadowElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFEDropShadowElement.internal_() : super.internal_();
@@ -9239,9 +9049,7 @@
     return new _SVGFontElement._internalWrap();
   }
 
-  factory _SVGFontElement._internalWrap() {
-    return new _SVGFontElement.internal_();
-  }
+  external factory _SVGFontElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontElement.internal_() : super.internal_();
@@ -9274,9 +9082,7 @@
     return new _SVGFontFaceElement._internalWrap();
   }
 
-  factory _SVGFontFaceElement._internalWrap() {
-    return new _SVGFontFaceElement.internal_();
-  }
+  external factory _SVGFontFaceElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontFaceElement.internal_() : super.internal_();
@@ -9309,9 +9115,7 @@
     return new _SVGFontFaceFormatElement._internalWrap();
   }
 
-  factory _SVGFontFaceFormatElement._internalWrap() {
-    return new _SVGFontFaceFormatElement.internal_();
-  }
+  external factory _SVGFontFaceFormatElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontFaceFormatElement.internal_() : super.internal_();
@@ -9344,9 +9148,7 @@
     return new _SVGFontFaceNameElement._internalWrap();
   }
 
-  factory _SVGFontFaceNameElement._internalWrap() {
-    return new _SVGFontFaceNameElement.internal_();
-  }
+  external factory _SVGFontFaceNameElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontFaceNameElement.internal_() : super.internal_();
@@ -9379,9 +9181,7 @@
     return new _SVGFontFaceSrcElement._internalWrap();
   }
 
-  factory _SVGFontFaceSrcElement._internalWrap() {
-    return new _SVGFontFaceSrcElement.internal_();
-  }
+  external factory _SVGFontFaceSrcElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontFaceSrcElement.internal_() : super.internal_();
@@ -9414,9 +9214,7 @@
     return new _SVGFontFaceUriElement._internalWrap();
   }
 
-  factory _SVGFontFaceUriElement._internalWrap() {
-    return new _SVGFontFaceUriElement.internal_();
-  }
+  external factory _SVGFontFaceUriElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGFontFaceUriElement.internal_() : super.internal_();
@@ -9453,9 +9251,7 @@
     return new _SVGGlyphElement._internalWrap();
   }
 
-  factory _SVGGlyphElement._internalWrap() {
-    return new _SVGGlyphElement.internal_();
-  }
+  external factory _SVGGlyphElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGGlyphElement.internal_() : super.internal_();
@@ -9486,9 +9282,7 @@
     return new _SVGGlyphRefElement._internalWrap();
   }
 
-  factory _SVGGlyphRefElement._internalWrap() {
-    return new _SVGGlyphRefElement.internal_();
-  }
+  external factory _SVGGlyphRefElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGGlyphRefElement.internal_() : super.internal_();
@@ -9528,9 +9322,7 @@
     return new _SVGHKernElement._internalWrap();
   }
 
-  factory _SVGHKernElement._internalWrap() {
-    return new _SVGHKernElement.internal_();
-  }
+  external factory _SVGHKernElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGHKernElement.internal_() : super.internal_();
@@ -9564,9 +9356,7 @@
     return new _SVGMPathElement._internalWrap();
   }
 
-  factory _SVGMPathElement._internalWrap() {
-    return new _SVGMPathElement.internal_();
-  }
+  external factory _SVGMPathElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGMPathElement.internal_() : super.internal_();
@@ -9602,9 +9392,7 @@
     return new _SVGMissingGlyphElement._internalWrap();
   }
 
-  factory _SVGMissingGlyphElement._internalWrap() {
-    return new _SVGMissingGlyphElement.internal_();
-  }
+  external factory _SVGMissingGlyphElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGMissingGlyphElement.internal_() : super.internal_();
@@ -9641,9 +9429,7 @@
     return new _SVGVKernElement._internalWrap();
   }
 
-  factory _SVGVKernElement._internalWrap() {
-    return new _SVGVKernElement.internal_();
-  }
+  external factory _SVGVKernElement._internalWrap();
 
   @Deprecated("Internal Use Only")
   _SVGVKernElement.internal_() : super.internal_();
diff --git a/sdk/lib/web_audio/dartium/web_audio_dartium.dart b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
index cc99534..7a3a9c4 100644
--- a/sdk/lib/web_audio/dartium/web_audio_dartium.dart
+++ b/sdk/lib/web_audio/dartium/web_audio_dartium.dart
@@ -104,9 +104,7 @@
     return new AnalyserNode._internalWrap();
   }
 
-  factory AnalyserNode._internalWrap() {
-    return new AnalyserNode.internal_();
-  }
+  external factory AnalyserNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   AnalyserNode.internal_() : super.internal_();
@@ -262,9 +260,7 @@
     return new AudioBufferSourceNode._internalWrap();
   }
 
-  factory AudioBufferSourceNode._internalWrap() {
-    return new AudioBufferSourceNode.internal_();
-  }
+  external factory AudioBufferSourceNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioBufferSourceNode.internal_() : super.internal_();
@@ -375,9 +371,7 @@
     return new AudioContext._internalWrap();
   }
 
-  factory AudioContext._internalWrap() {
-    return new AudioContext.internal_();
-  }
+  external factory AudioContext._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioContext.internal_() : super.internal_();
@@ -542,9 +536,7 @@
     return new AudioDestinationNode._internalWrap();
   }
 
-  factory AudioDestinationNode._internalWrap() {
-    return new AudioDestinationNode.internal_();
-  }
+  external factory AudioDestinationNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioDestinationNode.internal_() : super.internal_();
@@ -632,9 +624,7 @@
     return new AudioNode._internalWrap();
   }
 
-  factory AudioNode._internalWrap() {
-    return new AudioNode.internal_();
-  }
+  external factory AudioNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioNode.internal_() : super.internal_();
@@ -788,9 +778,7 @@
     return new AudioProcessingEvent._internalWrap();
   }
 
-  factory AudioProcessingEvent._internalWrap() {
-    return new AudioProcessingEvent.internal_();
-  }
+  external factory AudioProcessingEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioProcessingEvent.internal_() : super.internal_();
@@ -831,9 +819,7 @@
     return new AudioSourceNode._internalWrap();
   }
 
-  factory AudioSourceNode._internalWrap() {
-    return new AudioSourceNode.internal_();
-  }
+  external factory AudioSourceNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   AudioSourceNode.internal_() : super.internal_();
@@ -861,9 +847,7 @@
     return new BiquadFilterNode._internalWrap();
   }
 
-  factory BiquadFilterNode._internalWrap() {
-    return new BiquadFilterNode.internal_();
-  }
+  external factory BiquadFilterNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   BiquadFilterNode.internal_() : super.internal_();
@@ -919,9 +903,7 @@
     return new ChannelMergerNode._internalWrap();
   }
 
-  factory ChannelMergerNode._internalWrap() {
-    return new ChannelMergerNode.internal_();
-  }
+  external factory ChannelMergerNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   ChannelMergerNode.internal_() : super.internal_();
@@ -949,9 +931,7 @@
     return new ChannelSplitterNode._internalWrap();
   }
 
-  factory ChannelSplitterNode._internalWrap() {
-    return new ChannelSplitterNode.internal_();
-  }
+  external factory ChannelSplitterNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   ChannelSplitterNode.internal_() : super.internal_();
@@ -979,9 +959,7 @@
     return new ConvolverNode._internalWrap();
   }
 
-  factory ConvolverNode._internalWrap() {
-    return new ConvolverNode.internal_();
-  }
+  external factory ConvolverNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   ConvolverNode.internal_() : super.internal_();
@@ -1025,9 +1003,7 @@
     return new DelayNode._internalWrap();
   }
 
-  factory DelayNode._internalWrap() {
-    return new DelayNode.internal_();
-  }
+  external factory DelayNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   DelayNode.internal_() : super.internal_();
@@ -1059,9 +1035,7 @@
     return new DynamicsCompressorNode._internalWrap();
   }
 
-  factory DynamicsCompressorNode._internalWrap() {
-    return new DynamicsCompressorNode.internal_();
-  }
+  external factory DynamicsCompressorNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   DynamicsCompressorNode.internal_() : super.internal_();
@@ -1113,9 +1087,7 @@
     return new GainNode._internalWrap();
   }
 
-  factory GainNode._internalWrap() {
-    return new GainNode.internal_();
-  }
+  external factory GainNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   GainNode.internal_() : super.internal_();
@@ -1147,9 +1119,7 @@
     return new MediaElementAudioSourceNode._internalWrap();
   }
 
-  factory MediaElementAudioSourceNode._internalWrap() {
-    return new MediaElementAudioSourceNode.internal_();
-  }
+  external factory MediaElementAudioSourceNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaElementAudioSourceNode.internal_() : super.internal_();
@@ -1182,9 +1152,7 @@
     return new MediaStreamAudioDestinationNode._internalWrap();
   }
 
-  factory MediaStreamAudioDestinationNode._internalWrap() {
-    return new MediaStreamAudioDestinationNode.internal_();
-  }
+  external factory MediaStreamAudioDestinationNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStreamAudioDestinationNode.internal_() : super.internal_();
@@ -1216,9 +1184,7 @@
     return new MediaStreamAudioSourceNode._internalWrap();
   }
 
-  factory MediaStreamAudioSourceNode._internalWrap() {
-    return new MediaStreamAudioSourceNode.internal_();
-  }
+  external factory MediaStreamAudioSourceNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   MediaStreamAudioSourceNode.internal_() : super.internal_();
@@ -1250,9 +1216,7 @@
     return new OfflineAudioCompletionEvent._internalWrap();
   }
 
-  factory OfflineAudioCompletionEvent._internalWrap() {
-    return new OfflineAudioCompletionEvent.internal_();
-  }
+  external factory OfflineAudioCompletionEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   OfflineAudioCompletionEvent.internal_() : super.internal_();
@@ -1290,9 +1254,7 @@
     return new OfflineAudioContext._internalWrap();
   }
 
-  factory OfflineAudioContext._internalWrap() {
-    return new OfflineAudioContext.internal_();
-  }
+  external factory OfflineAudioContext._internalWrap();
 
   @Deprecated("Internal Use Only")
   OfflineAudioContext.internal_() : super.internal_();
@@ -1331,9 +1293,7 @@
     return new OscillatorNode._internalWrap();
   }
 
-  factory OscillatorNode._internalWrap() {
-    return new OscillatorNode.internal_();
-  }
+  external factory OscillatorNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   OscillatorNode.internal_() : super.internal_();
@@ -1414,9 +1374,7 @@
     return new PannerNode._internalWrap();
   }
 
-  factory PannerNode._internalWrap() {
-    return new PannerNode.internal_();
-  }
+  external factory PannerNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   PannerNode.internal_() : super.internal_();
@@ -1561,9 +1519,7 @@
     return new ScriptProcessorNode._internalWrap();
   }
 
-  factory ScriptProcessorNode._internalWrap() {
-    return new ScriptProcessorNode.internal_();
-  }
+  external factory ScriptProcessorNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   ScriptProcessorNode.internal_() : super.internal_();
@@ -1613,9 +1569,7 @@
     return new WaveShaperNode._internalWrap();
   }
 
-  factory WaveShaperNode._internalWrap() {
-    return new WaveShaperNode.internal_();
-  }
+  external factory WaveShaperNode._internalWrap();
 
   @Deprecated("Internal Use Only")
   WaveShaperNode.internal_() : super.internal_();
diff --git a/sdk/lib/web_gl/dartium/web_gl_dartium.dart b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
index 1fdf4c7..707af2d 100644
--- a/sdk/lib/web_gl/dartium/web_gl_dartium.dart
+++ b/sdk/lib/web_gl/dartium/web_gl_dartium.dart
@@ -824,9 +824,7 @@
     return new ContextEvent._internalWrap();
   }
 
-  factory ContextEvent._internalWrap() {
-    return new ContextEvent.internal_();
-  }
+  external factory ContextEvent._internalWrap();
 
   @Deprecated("Internal Use Only")
   ContextEvent.internal_() : super.internal_();
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a5781a6..f47d3ce 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -149,8 +149,8 @@
 LibTest/core/List/getRange_A03_t01: RuntimeError, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
 LibTest/core/List/removeAt_A02_t01: RuntimeError # Issue 1533
 LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
-LibTest/core/double/INFINITY_A01_t04: RuntimeError # Please triage this failure.
-LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # Please triage this failure.
+LibTest/core/double/INFINITY_A01_t04: RuntimeError # Expected to fail because double.INFINITY is int.
+LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # Expected to fail because double.NEGATIVE_INFINITY is int.
 LibTest/core/int/hashCode_A01_t01: RuntimeError, OK # co19 issue 308
 LibTest/core/int/isEven_A01_t01: RuntimeError, OK # co19 issue 277
 LibTest/core/int/isOdd_A01_t01: RuntimeError, OK # co19 issue 277
@@ -687,7 +687,7 @@
 LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
@@ -9616,9 +9616,7 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $cps_ir ]
-Language/Statements/Labels/scope_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
+Language/Types/Interface_Types/subtype_t09: Crash # Pending static: JSArray
 Language/Types/Interface_Types/subtype_t39: RuntimeError # Please triage this failure.
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
@@ -9632,5 +9630,3 @@
 LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Please triage this failure.
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/double/INFINITY_A01_t04: Pass # Please triage this failure.
-LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Pass # Please triage this failure.
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index f97f79d..061649b 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -20,7 +20,6 @@
 LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/events/remove-event-listener_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/attr-namespace_t01: RuntimeError # Dartium JsInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
@@ -241,7 +240,6 @@
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/caretRangeFromPoint-in-strict-mode-wtih-checkbox_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
@@ -265,7 +263,6 @@
 LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unfocusable_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/inert-node-is-unselectable_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/multiple-centered-dialogs_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/non-anchored-dialog-positioning_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLDialogElement/show-modal-focusing-steps_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -285,7 +282,6 @@
 LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # co19-roll r722: Issue 18010
 LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Issue 18931
 LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -303,14 +299,8 @@
 LayoutTests/fast/dom/Node/fragment-mutation_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/Node/initial-values_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/insertNode-empty-fragment-crash_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/mutation_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-constructor_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-expand_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-separate-endContainer_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/Range/range-insertNode-splittext_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -331,7 +321,6 @@
 LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -636,7 +625,6 @@
 LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # co19 issue 11.
 LayoutTests/fast/text/font-ligatures-linebreak_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text/glyph-reordering_t01: Pass, RuntimeError # This is a false pass. The font gets sanitized, so whether it works or not probably depends on default sizes. # co19 issue 11.
-LayoutTests/fast/text/international/cjk-segmentation_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text/international/complex-text-rectangle_t01: Skip # co19 issue 732.
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # co19 issue 11.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index a11b526..ae94df1 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -74,7 +74,7 @@
 LibTest/isolate/Isolate/spawnUri_A01_t04: Crash, Pass # Issue 17440
 LibTest/isolate/Isolate/spawn_A01_t04: Crash, Pass # Issue 17440
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
 LibTest/core/Uri/Uri_A06_t03: Skip  # Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t01: Skip  # Timeout
@@ -135,9 +135,6 @@
 Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
 Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug ]
-Language/Mixins/Mixin_Application/wrong_type_t02: Crash # Please triage this failure
-
 [ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
 Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
 Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index d88745d..71fbd97 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -17,7 +17,14 @@
 import 'package:compiler/src/world.dart';
 
 void main() {
-  asyncTest(() => TypeEnvironment.create(r"""
+  asyncTest(() async {
+    await testIterators();
+    await testForEach();
+  });
+}
+
+testIterators() async {
+  var env = await TypeEnvironment.create(r"""
       ///        A
       ///       / \
       ///      B   C
@@ -42,305 +49,536 @@
         new G();
       }
       """,
-      useMockCompiler: false).then((env) {
-    World world = env.compiler.world;
+      useMockCompiler: false);
+  World world = env.compiler.world;
 
-    ClassElement A = env.getElement("A");
-    ClassElement B = env.getElement("B");
-    ClassElement C = env.getElement("C");
-    ClassElement D = env.getElement("D");
-    ClassElement E = env.getElement("E");
-    ClassElement F = env.getElement("F");
-    ClassElement G = env.getElement("G");
+  ClassElement A = env.getElement("A");
+  ClassElement B = env.getElement("B");
+  ClassElement C = env.getElement("C");
+  ClassElement D = env.getElement("D");
+  ClassElement E = env.getElement("E");
+  ClassElement F = env.getElement("F");
+  ClassElement G = env.getElement("G");
 
-    void checkClass(ClassElement cls,
-                    {bool directlyInstantiated: false,
-                     bool indirectlyInstantiated: false}) {
-      ClassHierarchyNode node = world.getClassHierarchyNode(cls);
-      Expect.isNotNull(node, "Expected ClassHierarchyNode for $cls.");
-      Expect.equals(
-          directlyInstantiated || indirectlyInstantiated,
-          node.isInstantiated,
-          "Unexpected `isInstantiated` on ClassHierarchyNode for $cls.");
-      Expect.equals(
-          directlyInstantiated,
-          node.isDirectlyInstantiated,
-          "Unexpected `isDirectlyInstantiated` on ClassHierarchyNode for "
-          "$cls.");
-      Expect.equals(
-          indirectlyInstantiated,
-          node.isIndirectlyInstantiated,
-          "Unexpected `isIndirectlyInstantiated` on ClassHierarchyNode for "
-          "$cls.");
+  void checkClass(ClassElement cls,
+                  {bool directlyInstantiated: false,
+                   bool indirectlyInstantiated: false}) {
+    ClassHierarchyNode node = world.getClassHierarchyNode(cls);
+    Expect.isNotNull(node, "Expected ClassHierarchyNode for $cls.");
+    Expect.equals(
+        directlyInstantiated || indirectlyInstantiated,
+        node.isInstantiated,
+        "Unexpected `isInstantiated` on ClassHierarchyNode for $cls.");
+    Expect.equals(
+        directlyInstantiated,
+        node.isDirectlyInstantiated,
+        "Unexpected `isDirectlyInstantiated` on ClassHierarchyNode for "
+        "$cls.");
+    Expect.equals(
+        indirectlyInstantiated,
+        node.isIndirectlyInstantiated,
+        "Unexpected `isIndirectlyInstantiated` on ClassHierarchyNode for "
+        "$cls.");
+  }
+
+
+  checkClass(A, directlyInstantiated: true, indirectlyInstantiated: true);
+  checkClass(B, indirectlyInstantiated: true);
+  checkClass(C, directlyInstantiated: true, indirectlyInstantiated: true);
+  checkClass(D, directlyInstantiated: true);
+  checkClass(E, directlyInstantiated: true);
+  checkClass(F, directlyInstantiated: true);
+  checkClass(G, directlyInstantiated: true);
+
+  ClassHierarchyNodeIterator iterator;
+
+  void checkState(
+      ClassElement root,
+      {ClassElement currentNode,
+       List<List<ClassElement>> stack}) {
+
+    ClassElement classOf(ClassHierarchyNode node) {
+      return node != null ? node.cls : null;
     }
 
-
-    checkClass(A, directlyInstantiated: true, indirectlyInstantiated: true);
-    checkClass(B, indirectlyInstantiated: true);
-    checkClass(C, directlyInstantiated: true, indirectlyInstantiated: true);
-    checkClass(D, directlyInstantiated: true);
-    checkClass(E, directlyInstantiated: true);
-    checkClass(F, directlyInstantiated: true);
-    checkClass(G, directlyInstantiated: true);
-
-    ClassHierarchyNodeIterator iterator;
-
-    void checkState(
-        ClassElement root,
-        {ClassElement currentNode,
-         List<List<ClassElement>> stack}) {
-
-      ClassElement classOf(ClassHierarchyNode node) {
-        return node != null ? node.cls : null;
-      }
-
-      List<ClassElement> classesOf(Link<ClassHierarchyNode> link) {
-        if (link == null) return null;
-        return link.map(classOf).toList();
-      }
-
-      ClassElement foundRoot = iterator.root.cls;
-      ClassElement foundCurrentNode = classOf(iterator.currentNode);
-      List<ClassElement> foundStack = classesOf(iterator.stack);
-
-      StringBuffer sb = new StringBuffer();
-      sb.write('{\n root: $foundRoot');
-      sb.write('\n currentNode: $foundCurrentNode');
-      sb.write('\n stack: $foundStack\n}');
-
-      Expect.equals(root, foundRoot,
-          "Expected root $root in $sb.");
-      if (currentNode == null) {
-        Expect.isNull(iterator.currentNode,
-            "Unexpected non-null currentNode in $sb.");
-      } else {
-        Expect.isNotNull(foundCurrentNode,
-            "Expected non-null currentNode ${currentNode} in $sb.");
-        Expect.equals(currentNode, foundCurrentNode,
-            "Expected currentNode $currentNode in $sb.");
-      }
-      if (stack == null) {
-        Expect.isNull(foundStack,
-            "Unexpected non-null stack in $sb.");
-      } else {
-        Expect.isNotNull(foundStack,
-            "Expected non-null stack ${stack} in $sb.");
-        Expect.listEquals(stack, foundStack,
-            "Expected stack ${stack}, "
-            "found ${foundStack} in $sb.");
-      }
+    List<ClassElement> classesOf(Link<ClassHierarchyNode> link) {
+      if (link == null) return null;
+      return link.map(classOf).toList();
     }
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(G),
-        ClassHierarchyNode.ALL).iterator;
-    checkState(G, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(G, currentNode: G, stack: []);
-    Expect.equals(G, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(G, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+    ClassElement foundRoot = iterator.root.cls;
+    ClassElement foundCurrentNode = classOf(iterator.currentNode);
+    List<ClassElement> foundStack = classesOf(iterator.stack);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(G),
-        ClassHierarchyNode.ALL,
-        includeRoot: false).iterator;
-    checkState(G, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(G, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+    StringBuffer sb = new StringBuffer();
+    sb.write('{\n root: $foundRoot');
+    sb.write('\n currentNode: $foundCurrentNode');
+    sb.write('\n stack: $foundStack\n}');
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(C),
-        ClassHierarchyNode.ALL).iterator;
-    checkState(C, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(C, currentNode: C, stack: [E, F, G]);
-    Expect.equals(C, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(C, currentNode: E, stack: [F, G]);
-    Expect.equals(E, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(C, currentNode: F, stack: [G]);
-    Expect.equals(F, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(C, currentNode: G, stack: []);
-    Expect.equals(G, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(C, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+    Expect.equals(root, foundRoot,
+        "Expected root $root in $sb.");
+    if (currentNode == null) {
+      Expect.isNull(iterator.currentNode,
+          "Unexpected non-null currentNode in $sb.");
+    } else {
+      Expect.isNotNull(foundCurrentNode,
+          "Expected non-null currentNode ${currentNode} in $sb.");
+      Expect.equals(currentNode, foundCurrentNode,
+          "Expected currentNode $currentNode in $sb.");
+    }
+    if (stack == null) {
+      Expect.isNull(foundStack,
+          "Unexpected non-null stack in $sb.");
+    } else {
+      Expect.isNotNull(foundStack,
+          "Expected non-null stack ${stack} in $sb.");
+      Expect.listEquals(stack, foundStack,
+          "Expected stack ${stack}, "
+          "found ${foundStack} in $sb.");
+    }
+  }
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(D),
-        ClassHierarchyNode.ALL).iterator;
-    checkState(D, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(D, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(D, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(G),
+      ClassHierarchyNode.ALL).iterator;
+  checkState(G, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(G, currentNode: G, stack: []);
+  Expect.equals(G, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(G, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(B),
-        ClassHierarchyNode.ALL).iterator;
-    checkState(B, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(B, currentNode: B, stack: [D]);
-    Expect.equals(B, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(B, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(B, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(G),
+      ClassHierarchyNode.ALL,
+      includeRoot: false).iterator;
+  checkState(G, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(G, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(B),
-        ClassHierarchyNode.ALL,
-        includeRoot: false).iterator;
-    checkState(B, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(B, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(B, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(C),
+      ClassHierarchyNode.ALL).iterator;
+  checkState(C, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(C, currentNode: C, stack: [E, F, G]);
+  Expect.equals(C, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(C, currentNode: E, stack: [F, G]);
+  Expect.equals(E, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(C, currentNode: F, stack: [G]);
+  Expect.equals(F, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(C, currentNode: G, stack: []);
+  Expect.equals(G, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(C, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(B),
-        new EnumSet<Instantiation>.fromValues(<Instantiation>[
-            Instantiation.DIRECTLY_INSTANTIATED,
-            Instantiation.UNINSTANTIATED])).iterator;
-    checkState(B, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(B, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(B, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(D),
+      ClassHierarchyNode.ALL).iterator;
+  checkState(D, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(D, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(D, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A),
-        ClassHierarchyNode.ALL).iterator;
-    checkState(A, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: A, stack: [C, B]);
-    Expect.equals(A, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: C, stack: [E, F, G, B]);
-    Expect.equals(C, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: E, stack: [F, G, B]);
-    Expect.equals(E, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: F, stack: [G, B]);
-    Expect.equals(F, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: G, stack: [B]);
-    Expect.equals(G, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: B, stack: [D]);
-    Expect.equals(B, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(A, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(B),
+      ClassHierarchyNode.ALL).iterator;
+  checkState(B, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(B, currentNode: B, stack: [D]);
+  Expect.equals(B, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(B, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(B, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A),
-        ClassHierarchyNode.ALL,
-        includeRoot: false).iterator;
-    checkState(A, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: C, stack: [E, F, G, B]);
-    Expect.equals(C, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: E, stack: [F, G, B]);
-    Expect.equals(E, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: F, stack: [G, B]);
-    Expect.equals(F, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: G, stack: [B]);
-    Expect.equals(G, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: B, stack: [D]);
-    Expect.equals(B, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(A, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(B),
+      ClassHierarchyNode.ALL,
+      includeRoot: false).iterator;
+  checkState(B, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(B, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(B, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A),
-        new EnumSet<Instantiation>.fromValues(<Instantiation>[
-            Instantiation.DIRECTLY_INSTANTIATED,
-            Instantiation.UNINSTANTIATED])).iterator;
-    checkState(A, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: A, stack: [C, B]);
-    Expect.equals(A, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: C, stack: [E, F, G, B]);
-    Expect.equals(C, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: E, stack: [F, G, B]);
-    Expect.equals(E, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: F, stack: [G, B]);
-    Expect.equals(F, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: G, stack: [B]);
-    Expect.equals(G, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(A, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(B),
+      new EnumSet<Instantiation>.fromValues(<Instantiation>[
+          Instantiation.DIRECTLY_INSTANTIATED,
+          Instantiation.UNINSTANTIATED])).iterator;
+  checkState(B, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(B, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(B, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 
-    iterator = new ClassHierarchyNodeIterable(
-        world.getClassHierarchyNode(A),
-        new EnumSet<Instantiation>.fromValues(<Instantiation>[
-            Instantiation.DIRECTLY_INSTANTIATED,
-            Instantiation.UNINSTANTIATED]),
-        includeRoot: false).iterator;
-    checkState(A, currentNode: null, stack: null);
-    Expect.isNull(iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: C, stack: [E, F, G, B]);
-    Expect.equals(C, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: E, stack: [F, G, B]);
-    Expect.equals(E, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: F, stack: [G, B]);
-    Expect.equals(F, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: G, stack: [B]);
-    Expect.equals(G, iterator.current);
-    Expect.isTrue(iterator.moveNext());
-    checkState(A, currentNode: D, stack: []);
-    Expect.equals(D, iterator.current);
-    Expect.isFalse(iterator.moveNext());
-    checkState(A, currentNode: null, stack: []);
-    Expect.isNull(iterator.current);
-  }));
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(A),
+      ClassHierarchyNode.ALL).iterator;
+  checkState(A, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: A, stack: [C, B]);
+  Expect.equals(A, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: C, stack: [E, F, G, B]);
+  Expect.equals(C, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: E, stack: [F, G, B]);
+  Expect.equals(E, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: F, stack: [G, B]);
+  Expect.equals(F, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: G, stack: [B]);
+  Expect.equals(G, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: B, stack: [D]);
+  Expect.equals(B, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(A, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
+
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(A),
+      ClassHierarchyNode.ALL,
+      includeRoot: false).iterator;
+  checkState(A, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: C, stack: [E, F, G, B]);
+  Expect.equals(C, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: E, stack: [F, G, B]);
+  Expect.equals(E, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: F, stack: [G, B]);
+  Expect.equals(F, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: G, stack: [B]);
+  Expect.equals(G, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: B, stack: [D]);
+  Expect.equals(B, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(A, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
+
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(A),
+      new EnumSet<Instantiation>.fromValues(<Instantiation>[
+          Instantiation.DIRECTLY_INSTANTIATED,
+          Instantiation.UNINSTANTIATED])).iterator;
+  checkState(A, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: A, stack: [C, B]);
+  Expect.equals(A, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: C, stack: [E, F, G, B]);
+  Expect.equals(C, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: E, stack: [F, G, B]);
+  Expect.equals(E, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: F, stack: [G, B]);
+  Expect.equals(F, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: G, stack: [B]);
+  Expect.equals(G, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(A, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
+
+  iterator = new ClassHierarchyNodeIterable(
+      world.getClassHierarchyNode(A),
+      new EnumSet<Instantiation>.fromValues(<Instantiation>[
+          Instantiation.DIRECTLY_INSTANTIATED,
+          Instantiation.UNINSTANTIATED]),
+      includeRoot: false).iterator;
+  checkState(A, currentNode: null, stack: null);
+  Expect.isNull(iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: C, stack: [E, F, G, B]);
+  Expect.equals(C, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: E, stack: [F, G, B]);
+  Expect.equals(E, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: F, stack: [G, B]);
+  Expect.equals(F, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: G, stack: [B]);
+  Expect.equals(G, iterator.current);
+  Expect.isTrue(iterator.moveNext());
+  checkState(A, currentNode: D, stack: []);
+  Expect.equals(D, iterator.current);
+  Expect.isFalse(iterator.moveNext());
+  checkState(A, currentNode: null, stack: []);
+  Expect.isNull(iterator.current);
 }
 
+testForEach() async {
+  var env = await TypeEnvironment.create(r"""
+      ///        A
+      ///       / \
+      ///      B   C
+      ///     /   /|\
+      ///    D   E F G
+      ///         / \
+      ///         H I
+      ///
+      class A implements X {}
+      class B extends A {}
+      class C extends A {}
+      class D extends B {}
+      class E extends C {}
+      class F extends C implements B {}
+      class G extends C implements D {}
+      class H extends F {}
+      class I extends F {}
+      class X {}
+      """,
+        mainSource: r"""
+      main() {
+        new A();
+        new C();
+        new D();
+        new E();
+        new F();
+        new G();
+        new H();
+        new I();
+      }
+      """,
+      useMockCompiler: false);
+  World world = env.compiler.world;
+
+  ClassElement A = env.getElement("A");
+  ClassElement B = env.getElement("B");
+  ClassElement C = env.getElement("C");
+  ClassElement D = env.getElement("D");
+  ClassElement E = env.getElement("E");
+  ClassElement F = env.getElement("F");
+  ClassElement G = env.getElement("G");
+  ClassElement H = env.getElement("H");
+  ClassElement I = env.getElement("I");
+  ClassElement X = env.getElement("X");
+
+  void checkForEachSubclass(ClassElement cls, List<ClassElement> expected) {
+    ClassSet classSet = world.getClassSet(cls);
+    List<ClassElement> visited = <ClassElement>[];
+    classSet.forEachSubclass((ClassElement cls) {
+      visited.add(cls);
+    }, ClassHierarchyNode.ALL);
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls.forEachSubclass:\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+
+    visited = <ClassElement>[];
+    classSet.forEachSubclass((ClassElement cls) {
+      visited.add(cls);
+      return ForEach.CONTINUE;
+    }, ClassHierarchyNode.ALL);
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls.forEachSubclass:\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+  }
+
+  checkForEachSubclass(A, [A, B, D, C, G, F, I, H, E]);
+  checkForEachSubclass(B, [B, D]);
+  checkForEachSubclass(C, [C, G, F, I, H, E]);
+  checkForEachSubclass(D, [D]);
+  checkForEachSubclass(E, [E]);
+  checkForEachSubclass(F, [F, I, H]);
+  checkForEachSubclass(G, [G]);
+  checkForEachSubclass(H, [H]);
+  checkForEachSubclass(I, [I]);
+  checkForEachSubclass(X, [X]);
+
+  void checkForEachSubtype(ClassElement cls, List<ClassElement> expected) {
+    ClassSet classSet = world.getClassSet(cls);
+    List<ClassElement> visited = <ClassElement>[];
+    classSet.forEachSubtype((ClassElement cls) {
+      visited.add(cls);
+    }, ClassHierarchyNode.ALL);
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls.forEachSubtype:\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+
+    visited = <ClassElement>[];
+    classSet.forEachSubtype((ClassElement cls) {
+      visited.add(cls);
+      return ForEach.CONTINUE;
+    }, ClassHierarchyNode.ALL);
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls.forEachSubtype:\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+  }
+
+  checkForEachSubtype(A, [A, B, D, C, G, F, I, H, E]);
+  checkForEachSubtype(B, [B, D, F, I, H, G]);
+  checkForEachSubtype(C, [C, G, F, I, H, E]);
+  checkForEachSubtype(D, [D, G]);
+  checkForEachSubtype(E, [E]);
+  checkForEachSubtype(F, [F, I, H]);
+  checkForEachSubtype(G, [G]);
+  checkForEachSubtype(H, [H]);
+  checkForEachSubtype(I, [I]);
+  checkForEachSubtype(X, [X, A, B, D, C, G, F, I, H, E]);
+
+  void checkForEach(
+      ClassElement cls,
+      List<ClassElement> expected,
+      {ClassElement stop,
+       List<ClassElement> skipSubclasses: const <ClassElement>[],
+       bool forEachSubtype: false,
+       EnumSet<Instantiation> mask}) {
+
+    if (mask == null) {
+      mask = ClassHierarchyNode.ALL;
+    }
+
+    ClassSet classSet = world.getClassSet(cls);
+    List<ClassElement> visited = <ClassElement>[];
+
+    ForEach visit(ClassElement cls) {
+      visited.add(cls);
+      if (cls == stop) {
+        return ForEach.STOP;
+      } else if (skipSubclasses.contains(cls)) {
+        return ForEach.SKIP_SUBCLASSES;
+      }
+      return ForEach.CONTINUE;
+    }
+
+    if (forEachSubtype) {
+      classSet.forEachSubtype(visit, mask);
+    } else {
+      classSet.forEachSubclass(visit, mask);
+    }
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls."
+        "forEach${forEachSubtype ? 'Subtype' : 'Subclass'} "
+        "(stop:$stop, skipSubclasses:$skipSubclasses):\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+  }
+
+  checkForEach(A, [A, B, D, C, G, F, I, H, E]);
+  checkForEach(A, [A], stop: A);
+  checkForEach(A, [A, B, C, G, F, I, H, E], skipSubclasses: [B]);
+  checkForEach(A, [A, B, C], skipSubclasses: [B, C]);
+  checkForEach(A, [A, B, C, G], stop: G, skipSubclasses: [B]);
+
+  checkForEach(B, [B, D, F, I, H, G], forEachSubtype: true);
+  checkForEach(B, [B, D], stop: D, forEachSubtype: true);
+  checkForEach(B, [B, D, F, G], skipSubclasses: [F], forEachSubtype: true);
+  checkForEach(B, [B, F, I, H, G], skipSubclasses: [B], forEachSubtype: true);
+  checkForEach(B, [B, D, F, I, H, G], skipSubclasses: [D], forEachSubtype: true);
+
+  checkForEach(X, [X, A, B, D, C, G, F, I, H, E], forEachSubtype: true);
+  checkForEach(X, [X, A, B, D], stop: D, forEachSubtype: true);
+  checkForEach(X, [X, A, B, D, C, G, F, E],
+      skipSubclasses: [F], forEachSubtype: true);
+  checkForEach(X, [X, A, B, D, C, G, F, I, H, E],
+      skipSubclasses: [X], forEachSubtype: true);
+  checkForEach(X, [X, A, B, D, C, G, F, I, H, E],
+      skipSubclasses: [D], forEachSubtype: true);
+  checkForEach(X, [A, D, C, G, F, I, H, E],
+      forEachSubtype: true,
+      mask: ClassHierarchyNode.DIRECTLY_INSTANTIATED);
+  checkForEach(X, [A, B, D, C, G, F, I, H, E],
+      forEachSubtype: true,
+      mask: ClassHierarchyNode.INSTANTIATED);
+
+  void checkAny(
+      ClassElement cls,
+      List<ClassElement> expected,
+      {ClassElement find,
+       bool expectedResult,
+       bool anySubtype: false}) {
+    ClassSet classSet = world.getClassSet(cls);
+    List<ClassElement> visited = <ClassElement>[];
+
+    bool visit(ClassElement cls) {
+      visited.add(cls);
+      return cls == find;
+    }
+
+    bool result;
+    if (anySubtype) {
+      result = classSet.anySubtype(visit, ClassHierarchyNode.ALL);
+    } else {
+      result = classSet.anySubclass(visit, ClassHierarchyNode.ALL);
+    }
+
+    Expect.equals(expectedResult, result,
+        "Unexpected result on $cls."
+        "any${anySubtype ? 'Subtype' : 'Subclass'} "
+        "(find:$find).");
+
+    Expect.listEquals(expected, visited,
+        "Unexpected classes on $cls."
+        "any${anySubtype ? 'Subtype' : 'Subclass'} "
+        "(find:$find):\n"
+        "Actual: $visited, expected: $expected\n$classSet");
+  }
+
+  checkAny(A, [A, B, D, C, G, F, I, H, E], expectedResult: false);
+  checkAny(A, [A], find: A, expectedResult: true);
+  checkAny(A, [A, B, D, C, G, F, I], find: I, expectedResult: true);
+
+  checkAny(B, [B, D, F, I, H, G], anySubtype: true, expectedResult: false);
+  checkAny(B, [B, D, F, I, H, G],
+      find: A, anySubtype: true, expectedResult: false);
+  checkAny(B, [B, D],
+      find: D, anySubtype: true, expectedResult: true);
+  checkAny(B, [B, D, F, I],
+      find: I, anySubtype: true, expectedResult: true);
+
+  checkAny(X, [X, A, B, D, C, G, F, I, H, E],
+      anySubtype: true, expectedResult: false);
+  checkAny(X, [X, A],
+      find: A, anySubtype: true, expectedResult: true);
+  checkAny(X, [X, A, B, D],
+      find: D, anySubtype: true, expectedResult: true);
+  checkAny(X, [X, A, B, D, C, G, F, I],
+      find: I, anySubtype: true, expectedResult: true);
+}
diff --git a/tests/compiler/dart2js/cps_ir/closures_16_test.dart b/tests/compiler/dart2js/cps_ir/closures_16_test.dart
new file mode 100644
index 0000000..6b359ec
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/closures_16_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.closures_16.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("closures_16.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
index 589d358..2c4e7c7 100644
--- a/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
+++ b/tests/compiler/dart2js/cps_ir/expected/argument_refinement_21.js
@@ -16,15 +16,6 @@
   P.print(v0);
   if (!v0)
     throw H.wrapException(H.argumentErrorValue(y));
-  if (x < y)
-    v0 = -1;
-  else if (x > y)
-    v0 = 1;
-  else if (x === y) {
-    v0 = x === 0;
-    v0 = v0 ? (y === 0 ? 1 / y < 0 : y < 0) === (v0 ? 1 / x < 0 : x < 0) ? 0 : (v0 ? 1 / x < 0 : x < 0) ? -1 : 1 : 0;
-  } else
-    v0 = isNaN(x) ? isNaN(y) ? 0 : 1 : -1;
-  P.print(v0);
+  P.print(x < y ? -1 : x > y ? 1 : x === y ? x === 0 ? 1 / x < 0 === (y === 0 ? 1 / y < 0 : y < 0) ? 0 : 1 / x < 0 ? -1 : 1 : 0 : isNaN(x) ? isNaN(y) ? 0 : 1 : -1);
   P.print(true);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_1.js b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
index 1cf4ed5..5ae55be 100644
--- a/tests/compiler/dart2js/cps_ir/expected/basic_1.js
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_1.js
@@ -15,12 +15,12 @@
 // }
 
 function() {
-  var l = [1, 2, 3], m = P.LinkedHashMap_LinkedHashMap$_literal(["s", 1]);
+  var l = [1, 2, 3], m = P.LinkedHashMap__makeLiteral(["s", 1]);
   P.print("()");
   P.print("(true)");
   P.print("(1)");
   P.print("(" + P.IterableBase_iterableToFullString([1, 2, 3], "[", "]") + ")");
-  P.print("(" + P.Maps_mapToString(P.LinkedHashMap_LinkedHashMap$_literal(["s", 1])) + ")");
+  P.print("(" + P.Maps_mapToString(P.LinkedHashMap__makeLiteral(["s", 1])) + ")");
   P.print("(1)");
   P.print("(" + P.IterableBase_iterableToFullString(l, "[", "]") + ")");
   P.print("(" + P.Maps_mapToString(m) + ")");
diff --git a/tests/compiler/dart2js/cps_ir/expected/basic_10.js b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
index cfd6571..104f614 100644
--- a/tests/compiler/dart2js/cps_ir/expected/basic_10.js
+++ b/tests/compiler/dart2js/cps_ir/expected/basic_10.js
@@ -4,7 +4,7 @@
 // }
 
 function() {
-  var v0 = Date.now() < Date.now(), line = v0 ? "true" : false === v0 ? "false" : String(v0);
+  var line = Date.now() < Date.now() ? "true" : "false";
   if (typeof dartPrint == "function")
     dartPrint(line);
   else if (typeof console == "object" && typeof console.log != "undefined")
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_10.js b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
index a628815..64e5e31 100644
--- a/tests/compiler/dart2js/cps_ir/expected/closures_10.js
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_10.js
@@ -8,7 +8,7 @@
 // }
 
 function() {
-  var line = H.S(new V.A_b_closure(V.A$()).call$0());
+  var line = H.S(V.A$().a$0());
   if (typeof dartPrint == "function")
     dartPrint(line);
   else if (typeof console == "object" && typeof console.log != "undefined")
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_15.js b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
index 46c7d38..cf37dd2 100644
--- a/tests/compiler/dart2js/cps_ir/expected/closures_15.js
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_15.js
@@ -13,5 +13,5 @@
 function(x) {
   V.Foo$();
   P.print("getter");
-  P.print(new V.Foo_getter_closure().call$1(123));
+  P.print(123);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/closures_16.js b/tests/compiler/dart2js/cps_ir/expected/closures_16.js
new file mode 100644
index 0000000..e589971
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/closures_16.js
@@ -0,0 +1,17 @@
+// Expectation for test: 
+// class Foo {
+//   get getter {
+//     print('getter');
+//     return (x) { try { return x; } finally { } };  // Inhibit inlining.
+//   }
+// }
+// main(x) {
+//   // Getter may or may not be inlined.
+//   var notTearOff = new Foo().getter;
+//   // Closure is not inlined.
+//   print(notTearOff(123));
+// }
+
+function(x) {
+  P.print(V.Foo$().get$getter().call$1(123));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
index 73e278b..4fdd8a2 100644
--- a/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
+++ b/tests/compiler/dart2js/cps_ir/expected/codeUnitAt_2.js
@@ -11,13 +11,12 @@
 // }
 
 function() {
-  var v0 = "ABC".length, sum = 0, i = 0;
-  for (; i < v0; sum += "ABC".charCodeAt(i), ++i)
+  var sum = 0, i = 0;
+  for (; i < 3; sum += "ABC".charCodeAt(i), ++i)
     ;
   P.print(sum);
-  v0 = "Hello".length;
   sum = 0;
-  for (i = 0; i < v0; sum += "Hello".charCodeAt(i), ++i)
+  for (i = 0; i < 5; sum += "Hello".charCodeAt(i), ++i)
     ;
   P.print(sum);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
index 950d594..7fd9aff 100644
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_1.js
@@ -4,6 +4,6 @@
 // }
 
 function() {
-  while (true)
+  for (;;)
     ;
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
index 79c2ddd..3cb9718 100644
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_2.js
@@ -1,5 +1,5 @@
 // Expectation for test: 
-// foo(a) { print(a); return a; }
+// foo(a) { try { print(a); } finally { return a; } }
 // 
 // main() {
 //   while (true) {
@@ -14,20 +14,14 @@
 // }
 
 function() {
-  L1:
-    while (true)
-      L0:
-        while (true)
-          while (true) {
-            P.print(true);
-            if (false) {
-              P.print(1);
-              continue L0;
-            }
-            P.print(false);
-            if (false) {
-              P.print(2);
-              continue L1;
-            }
+  L0:
+    for (;;)
+      for (;;) {
+        while (V.foo(true))
+          if (V.foo(false)) {
+            P.print(2);
+            continue L0;
           }
+        P.print(1);
+      }
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
index 514ed7b..f7c0900 100644
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_3.js
@@ -1,5 +1,5 @@
 // Expectation for test: 
-// foo(a) { print(a); return a; }
+// foo(a) { try { print(a); } finally { return a; } }
 // 
 // main() {
 //   for (int i = 0; foo(true); i = foo(i)) {
@@ -10,17 +10,11 @@
 // }
 
 function() {
-  while (true) {
-    P.print(true);
-    if (true === true) {
-      P.print(1);
-      P.print(false);
-      if (false !== true) {
-        P.print(0);
-        continue;
-      }
-    }
-    P.print(2);
-    return null;
+  var i = 0;
+  for (; V.foo(true) === true; i = V.foo(i)) {
+    P.print(1);
+    if (V.foo(false) === true)
+      break;
   }
+  P.print(2);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
index 00099d0..dae4cc7 100644
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_4.js
@@ -1,5 +1,5 @@
 // Expectation for test: 
-// foo(a) { print(a); return a; }
+// foo(a) { try { print(a); } finally { return a; } }
 // 
 // main() {
 //  foo(false);
@@ -12,8 +12,7 @@
 // }
 
 function() {
-  P.print(false);
-  P.print(true);
-  true ? P.print(1) : P.print(2);
+  V.foo(false);
+  V.foo(true) ? P.print(1) : P.print(2);
   P.print(3);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
index 78c0641..0f28201 100644
--- a/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
+++ b/tests/compiler/dart2js/cps_ir/expected/control_flow_5.js
@@ -1,5 +1,5 @@
 // Expectation for test: 
-// foo(a) { print(a); return a; }
+// foo(a) { try { print(a); } finally { return a; } }
 // 
 // main() {
 //  foo(false);
@@ -14,9 +14,8 @@
 // }
 
 function() {
-  P.print(false);
-  P.print(true);
-  if (true) {
+  V.foo(false);
+  if (V.foo(true)) {
     P.print(1);
     P.print(1);
   } else {
diff --git a/tests/compiler/dart2js/cps_ir/expected/literals_1.js b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
index ef654f5..d70ebf8 100644
--- a/tests/compiler/dart2js/cps_ir/expected/literals_1.js
+++ b/tests/compiler/dart2js/cps_ir/expected/literals_1.js
@@ -14,7 +14,7 @@
   P.print([1]);
   P.print([1, 2]);
   P.print([1, [1, 2]]);
-  P.print(P.LinkedHashMap_LinkedHashMap$_empty());
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
-  P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
+  P.print(P.LinkedHashMap__makeEmpty());
+  P.print(P.LinkedHashMap__makeLiteral([1, 2]));
+  P.print(P.LinkedHashMap__makeLiteral([[1, 2], [3, 4]]));
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_1.js b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
index 5e39b1e..71a1da5 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_1.js
@@ -1,11 +1,12 @@
 // Expectation for test: 
+// // Method to test: function(foo)
 // foo(a, b) => ((a & 0xff0000) >> 1) & b;
 // main() {
+//   print(foo.toString());
 //   print(foo(123, 234));
 //   print(foo(0, 2));
 // }
 
-function() {
-  P.print((123 & 16711680) >>> 1 & 234);
-  P.print((0 & 16711680) >>> 1 & 2);
+function(a, b) {
+  return (a & 16711680) >>> 1 & b;
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
index 8d6d52d..7858649 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_2.js
@@ -1,11 +1,12 @@
 // Expectation for test: 
+// // Method to test: function(foo)
 // foo(a) => ~a;
 // main() {
+//   print(foo.toString());
 //   print(foo(1));
 //   print(foo(10));
 // }
 
-function() {
-  P.print(~1 >>> 0);
-  P.print(~10 >>> 0);
+function(a) {
+  return ~a >>> 0;
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
index ff5d25d..bf578b2 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_3.js
@@ -8,5 +8,5 @@
 
 function(a) {
   var result = a % 13;
-  return result === 0 ? 0 : result > 0 ? result : 13 < 0 ? result - 13 : result + 13;
+  return result === 0 ? 0 : result > 0 ? result : result + 13;
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
index 837393f..9faff59 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators2_7.js
@@ -1,11 +1,12 @@
 // Expectation for test: 
+// // Method to test: function(foo)
 // foo(a) => a ~/ 13;
 // main() {
+//   print(foo.toString());
 //   print(foo(5));
 //   print(foo(100));
 // }
 
-function() {
-  P.print(5 / 13 | 0);
-  P.print(100 / 13 | 0);
+function(a) {
+  return a / 13 | 0;
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_4.js b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
index f86a490..ccfc0a8 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators_4.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_4.js
@@ -16,7 +16,7 @@
       v0 = false;
     } else
       v0 = false;
-    line = false === v0 ? "false" : String(v0);
+    line = v0 ? String(v0) : "false";
   }
   if (typeof dartPrint == "function")
     dartPrint(line);
diff --git a/tests/compiler/dart2js/cps_ir/expected/operators_5.js b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
index 3ff812c..d2986cc 100644
--- a/tests/compiler/dart2js/cps_ir/expected/operators_5.js
+++ b/tests/compiler/dart2js/cps_ir/expected/operators_5.js
@@ -10,7 +10,7 @@
     if (!(v0 > 10)) {
       $.x = v0 = $.x + 1;
       if (!(v0 > 10)) {
-        line = false === false ? "false" : String(false);
+        line = "false";
         break L0;
       }
     }
diff --git a/tests/compiler/dart2js/cps_ir/expected/optimize_indexers.js b/tests/compiler/dart2js/cps_ir/expected/optimize_indexers.js
new file mode 100644
index 0000000..21c1d71
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/optimize_indexers.js
@@ -0,0 +1,37 @@
+// Expectation for test: 
+// // Method to test: function(test)
+// import 'package:expect/expect.dart';
+// 
+// // This example illustrates a case we wish to do better in terms of inlining and
+// // code generation.
+// //
+// // Today this function is compiled without inlining Wrapper.[], JSArray.[] and
+// // Wrapper.[]= because:
+// // JSArray.[] is too big (14 nodes)
+// // Wrapper.[] is too big if we force inlining of JSArray (15 nodes)
+// // Wrapper.[]= is even bigger (46 nodes)
+// //
+// // See #25478 for ideas on how to make this better.
+// @NoInline()
+// test(data, x) {
+//   data[x + 1] = data[x];
+// }
+// 
+// main() {
+//   var wrapper = new Wrapper();
+//   wrapper[33] = wrapper[1]; // make Wrapper.[]= and [] used more than once.
+//   print(test(new Wrapper(), int.parse('2')));
+// }
+// 
+// class Wrapper {
+//   final List arr = <bool>[true, false, false, true];
+//   operator[](int i) => this.arr[i];
+//   operator[]=(int i, v) {
+//     if (i > arr.length - 1) arr.length = i + 1;
+//     return arr[i] = v;
+//   }
+// }
+
+function(data, x) {
+  data.$indexSet(0, J.$add$ns(x, 1), C.JSArray_methods.$index(data.arr, x));
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js b/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js
new file mode 100644
index 0000000..a3a2ae0
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/expected/redundant_condition.js
@@ -0,0 +1,35 @@
+// Expectation for test: 
+// // This test illustrates an opportunity to remove redundant code by
+// // propagating inforamtion after inlining.
+// //
+// // The code below inlines `foo` twice, but we don't propagate that we already
+// // know from the first `foo` that `a` is an int, so the second check can be
+// // removed entirely.
+// 
+// import 'package:expect/expect.dart';
+// 
+// main() {
+//   var a = nextNumber();
+//   action(foo(a));
+//   action(foo(a));
+// }
+// 
+// foo(x) {
+//   if (x is! int) throw "error 1";
+//   return x + 5 % 100;
+// }
+// 
+// @NoInline() @AssumeDynamic()
+// nextNumber() => int.parse('33');
+// 
+// @NoInline()
+// action(v) => print(v);
+
+function() {
+  var a = V.nextNumber();
+  if (!(typeof a === "number" && Math.floor(a) === a))
+    throw H.wrapException("error 1");
+  a += 5;
+  V.action(a);
+  V.action(a);
+}
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_1.js b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
index 4c7ee26..cc601dd 100644
--- a/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_1.js
@@ -1,7 +1,7 @@
 // Expectation for test: 
 // class Base {
 //   m(x) {
-//     print(x+1);
+//     try { print(x+1); } finally { }
 //   }
 // }
 // class Sub extends Base {
@@ -12,15 +12,6 @@
 // }
 
 function() {
-  var line = "" + (100 + 10 + 1);
-  V.Sub$();
-  if (typeof dartPrint == "function")
-    dartPrint(line);
-  else if (typeof console == "object" && typeof console.log != "undefined")
-    console.log(line);
-  else if (!(typeof window == "object")) {
-    if (!(typeof print == "function"))
-      throw "Unable to print message: " + String(line);
-    print(line);
-  }
+  var v0 = V.Sub$();
+  V.Base.prototype.m$1.call(v0, 110);
 }
diff --git a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
index 13b1d21..27f6c2b 100644
--- a/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
+++ b/tests/compiler/dart2js/cps_ir/expected/supercall_2.js
@@ -25,5 +25,5 @@
 
 function() {
   var v0 = V.Sub$();
-  V.Base.prototype.$add.call(v0, v0, 10000 + 1);
+  V.Base.prototype.$add.call(v0, v0, 10001);
 }
diff --git a/tests/compiler/dart2js/cps_ir/input/closures_16.dart b/tests/compiler/dart2js/cps_ir/input/closures_16.dart
new file mode 100644
index 0000000..0d57270
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/closures_16.dart
@@ -0,0 +1,12 @@
+class Foo {
+  get getter {
+    print('getter');
+    return (x) { try { return x; } finally { } };  // Inhibit inlining.
+  }
+}
+main(x) {
+  // Getter may or may not be inlined.
+  var notTearOff = new Foo().getter;
+  // Closure is not inlined.
+  print(notTearOff(123));
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
index dd06bed..a7baf52 100644
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_2.dart
@@ -1,4 +1,4 @@
-foo(a) { print(a); return a; }
+foo(a) { try { print(a); } finally { return a; } }
 
 main() {
   while (true) {
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
index 51cead4..8335da4 100644
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_3.dart
@@ -1,4 +1,4 @@
-foo(a) { print(a); return a; }
+foo(a) { try { print(a); } finally { return a; } }
 
 main() {
   for (int i = 0; foo(true); i = foo(i)) {
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
index 881d8ce..dd9fa9c 100644
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_4.dart
@@ -1,4 +1,4 @@
-foo(a) { print(a); return a; }
+foo(a) { try { print(a); } finally { return a; } }
 
 main() {
  foo(false);
diff --git a/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
index 6efe03c..ee75818 100644
--- a/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
+++ b/tests/compiler/dart2js/cps_ir/input/control_flow_5.dart
@@ -1,4 +1,4 @@
-foo(a) { print(a); return a; }
+foo(a) { try { print(a); } finally { return a; } }
 
 main() {
  foo(false);
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_1.dart b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
index 05da19c..38b8f4f 100644
--- a/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_1.dart
@@ -1,5 +1,7 @@
+// Method to test: function(foo)
 foo(a, b) => ((a & 0xff0000) >> 1) & b;
 main() {
+  print(foo.toString());
   print(foo(123, 234));
   print(foo(0, 2));
 }
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_2.dart b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
index 56bebd9..f38e967 100644
--- a/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_2.dart
@@ -1,5 +1,7 @@
+// Method to test: function(foo)
 foo(a) => ~a;
 main() {
+  print(foo.toString());
   print(foo(1));
   print(foo(10));
 }
diff --git a/tests/compiler/dart2js/cps_ir/input/operators2_7.dart b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
index f2c68ee..225701b 100644
--- a/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
+++ b/tests/compiler/dart2js/cps_ir/input/operators2_7.dart
@@ -1,5 +1,7 @@
+// Method to test: function(foo)
 foo(a) => a ~/ 13;
 main() {
+  print(foo.toString());
   print(foo(5));
   print(foo(100));
 }
diff --git a/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart b/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart
new file mode 100644
index 0000000..084bc34
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/optimize_indexers.dart
@@ -0,0 +1,32 @@
+// Method to test: function(test)
+import 'package:expect/expect.dart';
+
+// This example illustrates a case we wish to do better in terms of inlining and
+// code generation.
+//
+// Today this function is compiled without inlining Wrapper.[], JSArray.[] and
+// Wrapper.[]= because:
+// JSArray.[] is too big (14 nodes)
+// Wrapper.[] is too big if we force inlining of JSArray (15 nodes)
+// Wrapper.[]= is even bigger (46 nodes)
+//
+// See #25478 for ideas on how to make this better.
+@NoInline()
+test(data, x) {
+  data[x + 1] = data[x];
+}
+
+main() {
+  var wrapper = new Wrapper();
+  wrapper[33] = wrapper[1]; // make Wrapper.[]= and [] used more than once.
+  print(test(new Wrapper(), int.parse('2')));
+}
+
+class Wrapper {
+  final List arr = <bool>[true, false, false, true];
+  operator[](int i) => this.arr[i];
+  operator[]=(int i, v) {
+    if (i > arr.length - 1) arr.length = i + 1;
+    return arr[i] = v;
+  }
+}
diff --git a/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart b/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart
new file mode 100644
index 0000000..913dfc5
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/input/redundant_condition.dart
@@ -0,0 +1,25 @@
+// This test illustrates an opportunity to remove redundant code by
+// propagating inforamtion after inlining.
+//
+// The code below inlines `foo` twice, but we don't propagate that we already
+// know from the first `foo` that `a` is an int, so the second check can be
+// removed entirely.
+
+import 'package:expect/expect.dart';
+
+main() {
+  var a = nextNumber();
+  action(foo(a));
+  action(foo(a));
+}
+
+foo(x) {
+  if (x is! int) throw "error 1";
+  return x + 5 % 100;
+}
+
+@NoInline() @AssumeDynamic()
+nextNumber() => int.parse('33');
+
+@NoInline()
+action(v) => print(v);
diff --git a/tests/compiler/dart2js/cps_ir/input/supercall_1.dart b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
index 04d5817..0ac95c8d 100644
--- a/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
+++ b/tests/compiler/dart2js/cps_ir/input/supercall_1.dart
@@ -1,6 +1,6 @@
 class Base {
   m(x) {
-    print(x+1);
+    try { print(x+1); } finally { }
   }
 }
 class Sub extends Base {
diff --git a/tests/compiler/dart2js/cps_ir/optimize_indexers_test.dart b/tests/compiler/dart2js/cps_ir/optimize_indexers_test.dart
new file mode 100644
index 0000000..eaf0b4a
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/optimize_indexers_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.optimize_indexers.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("optimize_indexers.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart b/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart
new file mode 100644
index 0000000..e97e0ac
--- /dev/null
+++ b/tests/compiler/dart2js/cps_ir/redundant_condition_test.dart
@@ -0,0 +1,15 @@
+// ---- AUTO-GENERATED -------------------
+// This file was autogenerated by running:
+//
+//     dart path/to/up_to_date_test.dart update
+//
+// Do not edit this file by hand.
+// ---------------------------------------
+
+library tests.compiler.dart2js.cps_ir.redundant_condition.dart;
+
+import 'runner.dart';
+
+main(args) {
+  runTest("redundant_condition.dart", update: args.length > 0 && args[0] == "update");
+}
diff --git a/tests/compiler/dart2js/cps_ir/runner.dart b/tests/compiler/dart2js/cps_ir/runner.dart
index a71bd9a..af77384 100644
--- a/tests/compiler/dart2js/cps_ir/runner.dart
+++ b/tests/compiler/dart2js/cps_ir/runner.dart
@@ -33,7 +33,20 @@
   var match = elementNameRegExp.firstMatch(source);
   var elementName = match?.group(1);
 
-  Map files = {TEST_MAIN_FILE: source};
+  Map files = {
+      TEST_MAIN_FILE: source,
+      'package:expect/expect.dart': '''
+          class NoInline {
+            const NoInline();
+          }
+          class TrustTypeAnnotations {
+            const TrustTypeAnnotations();
+          }
+          class AssumeDynamic {
+            const AssumeDynamic();
+          }
+       ''',
+   };
   asyncTest(() async {
     Uri uri = Uri.parse('memory:$TEST_MAIN_FILE');
     String found = null;
@@ -105,7 +118,7 @@
 String _getCodeForMain(CompilerImpl compiler) {
   Element mainFunction = compiler.mainFunction;
   js.Node ast = compiler.enqueuer.codegen.generatedCode[mainFunction];
-  return js.prettyPrint(ast, compiler).getText();
+  return js.prettyPrint(ast, compiler);
 }
 
 String _getCodeForMethod(CompilerImpl compiler,
@@ -125,5 +138,5 @@
   }
 
   js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
-  return js.prettyPrint(ast, compiler).getText();
+  return js.prettyPrint(ast, compiler);
 }
diff --git a/tests/compiler/dart2js/cps_ir/update_all.dart b/tests/compiler/dart2js/cps_ir/update_all.dart
index 726f2e4..5874a25 100644
--- a/tests/compiler/dart2js/cps_ir/update_all.dart
+++ b/tests/compiler/dart2js/cps_ir/update_all.dart
@@ -79,6 +79,7 @@
   runTest('closures_13.dart', update: true);
   runTest('closures_14.dart', update: true);
   runTest('closures_15.dart', update: true);
+  runTest('closures_16.dart', update: true);
   runTest('closures_2.dart', update: true);
   runTest('closures_3.dart', update: true);
   runTest('closures_4.dart', update: true);
@@ -132,6 +133,8 @@
   runTest('operators_6.dart', update: true);
   runTest('operators_7.dart', update: true);
   runTest('operators_8.dart', update: true);
+  runTest('optimize_indexers.dart', update: true);
+  runTest('redundant_condition.dart', update: true);
   runTest('runtime_types_1.dart', update: true);
   runTest('runtime_types_2.dart', update: true);
   runTest('runtime_types_3.dart', update: true);
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
index 2c68f48..781ef91 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_source_information_test.dart
@@ -60,7 +60,7 @@
   }
 
   js.Node ast = compiler.enqueuer.codegen.generatedCode[foundElement];
-  return js.prettyPrint(ast, compiler).getText();
+  return js.prettyPrint(ast, compiler);
 }
 
 runTests(List<TestEntry> tests) {
diff --git a/tests/compiler/dart2js/js_parser_statements_test.dart b/tests/compiler/dart2js/js_parser_statements_test.dart
index 2c12440..6c18de3 100644
--- a/tests/compiler/dart2js/js_parser_statements_test.dart
+++ b/tests/compiler/dart2js/js_parser_statements_test.dart
@@ -14,8 +14,7 @@
   jsAst.Node node = js.statement(statement, arguments);
   return MockCompiler.create((MockCompiler compiler) {
     String jsText =
-        jsAst.prettyPrint(node, compiler, allowVariableMinification: false)
-        .getText();
+        jsAst.prettyPrint(node, compiler, allowVariableMinification: false);
 
     Expect.stringEquals(expect.trim(), jsText.trim());
   });
diff --git a/tests/compiler/dart2js/js_parser_test.dart b/tests/compiler/dart2js/js_parser_test.dart
index 4022724..89d51070 100644
--- a/tests/compiler/dart2js/js_parser_test.dart
+++ b/tests/compiler/dart2js/js_parser_test.dart
@@ -15,7 +15,7 @@
     String jsText =
         jsAst.prettyPrint(node,
                           compiler,
-                          allowVariableMinification: false).getText();
+                          allowVariableMinification: false);
     if (expect == "") {
       Expect.stringEquals(expression, jsText);
     } else {
diff --git a/tests/compiler/dart2js/library_env_test.dart b/tests/compiler/dart2js/library_env_test.dart
new file mode 100644
index 0000000..0f0ff6d
--- /dev/null
+++ b/tests/compiler/dart2js/library_env_test.dart
@@ -0,0 +1,152 @@
+// 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.
+
+/// Check that 'dart:' libraries have their corresponding dart.library.X
+/// environment variable set.
+
+import "dart:io";
+
+import "dart:async";
+
+import "memory_source_file_helper.dart";
+
+import "package:async_helper/async_helper.dart";
+
+import 'package:expect/expect.dart' show
+    Expect;
+
+import 'package:compiler/src/elements/elements.dart' show
+    LibraryElement;
+
+import 'package:compiler/src/null_compiler_output.dart' show
+    NullCompilerOutput;
+
+import 'package:compiler/compiler_new.dart' show
+    CompilerInput,
+    CompilerDiagnostics;
+
+import 'package:sdk_library_metadata/libraries.dart' show
+    LibraryInfo;
+
+const clientPlatform = r'''
+[dart-spec]
+spec: 3rd edition.
+
+[features]
+# No extra features
+
+[libraries]
+mock.client: mock1.dart
+mock.shared: mock3.dart
+collection: collection/collection.dart
+html: html/dart2js/html_dart2js.dart
+''';
+
+const serverPlatform = r'''
+[dart-spec]
+spec: 3rd edition.
+
+[features]
+# No extra features
+
+[libraries]
+mock.server: mock2.dart
+mock.shared: mock3.dart
+collection: collection/collection.dart
+io: io/io.dart
+''';
+
+class DummyCompilerInput implements CompilerInput {
+  const DummyCompilerInput();
+
+  readFromUri(uri) async {
+    if (uri.toString().endsWith("dart_client.platform")) {
+      return clientPlatform;
+    } else if (uri.toString().endsWith("dart_server.platform")) {
+      return serverPlatform;
+    } else {
+      throw "should not be needed $uri";
+    }
+  }
+}
+
+class DummyCompilerDiagnostics implements CompilerDiagnostics {
+  const DummyCompilerDiagnostics();
+
+  report(code, uri, begin, end, text, kind) {
+    throw "should not be needed";
+  }
+}
+
+class CustomCompiler extends CompilerImpl {
+  CustomCompiler(
+      options,
+      environment)
+      : super(
+          const DummyCompilerInput(),
+          const NullCompilerOutput(),
+          const DummyCompilerDiagnostics(),
+          Uri.base.resolve("sdk/"),
+          null,
+          options,
+          environment);
+}
+
+runTest() async {
+  var compiler = new CustomCompiler(
+      [],
+      {});
+
+  await compiler.setupSdk();
+
+  // Core libraries are always present.
+  Expect.equals("true", compiler.fromEnvironment("dart.library.collection"));
+  // Non-existing entries in the environment return 'null'.
+  Expect.isNull(compiler.fromEnvironment("not in env"));
+  // Check for client libraries (default if there are no flags to the compiler).
+  Expect.equals("true", compiler.fromEnvironment("dart.library.mock.client"));
+  Expect.equals("true", compiler.fromEnvironment("dart.library.html"));
+  // Check for shared libraries..
+  Expect.equals("true", compiler.fromEnvironment("dart.library.mock.shared"));
+  // Check server libraries are not present.
+  Expect.equals(null, compiler.fromEnvironment("dart.library.mock.server"));
+  Expect.equals(null, compiler.fromEnvironment("dart.library.io"));
+
+  compiler = new CustomCompiler(
+      ['--categories=Server'],
+      {});
+
+  await compiler.setupSdk();
+
+  // Core libraries are always present.
+  Expect.equals("true", compiler.fromEnvironment("dart.library.collection"));
+  // Non-existing entries in the environment return 'null'.
+  Expect.isNull(compiler.fromEnvironment("not in env"));
+  // Check client libraries are not present.
+  Expect.equals(null, compiler.fromEnvironment("dart.library.mock.client"));
+  Expect.equals(null, compiler.fromEnvironment("dart.library.html"));
+  // Check for shared libraries..
+  Expect.equals("true", compiler.fromEnvironment("dart.library.mock.shared"));
+  // Check for server libraries.
+  Expect.equals("true", compiler.fromEnvironment("dart.library.mock.server"));
+  Expect.equals("true", compiler.fromEnvironment("dart.library.io"));
+
+  // Check that user-defined env-variables win.
+  compiler = new CustomCompiler(
+      [],
+      {'dart.library.collection': "false",
+       'dart.library.mock.client': "foo"});
+
+  await compiler.setupSdk();
+
+  Expect.equals("false", compiler.fromEnvironment("dart.library.collection"));
+  Expect.equals("foo", compiler.fromEnvironment("dart.library.mock.client"));
+}
+
+main() {
+  asyncStart();
+  runTest().then((_) {
+    asyncEnd();
+  });
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/message_kind_test.dart b/tests/compiler/dart2js/message_kind_test.dart
index c3954f0..a886f42 100644
--- a/tests/compiler/dart2js/message_kind_test.dart
+++ b/tests/compiler/dart2js/message_kind_test.dart
@@ -7,13 +7,19 @@
 import "package:async_helper/async_helper.dart";
 import 'package:compiler/src/diagnostics/messages.dart' show
     MessageKind,
-    MessageTemplate;
+    MessageTemplate,
+    SharedMessageKind;
 
 import 'message_kind_helper.dart';
 
 main(List<String> arguments) {
   List<MessageTemplate> examples = <MessageTemplate>[];
-  for (MessageKind kind in MessageKind.values) {
+  List allMessageKinds = []
+      ..addAll(MessageKind.values)
+      ..addAll(SharedMessageKind.values);
+  for (var kind in allMessageKinds) {
+    if (kind == SharedMessageKind.exampleMessage) continue;
+
     MessageTemplate template = MessageTemplate.TEMPLATES[kind];
     Expect.isNotNull(template, "No template for $kind.");
     Expect.equals(kind, template.kind,
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index 628f625..ef4387f 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -1548,7 +1548,6 @@
           }
           class Class extends A {
           }
-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+          """),
   ]);
 }
diff --git a/tests/compiler/dart2js/proxy_test.dart b/tests/compiler/dart2js/proxy_test.dart
index bdba67f..3a0af23 100644
--- a/tests/compiler/dart2js/proxy_test.dart
+++ b/tests/compiler/dart2js/proxy_test.dart
@@ -15,6 +15,9 @@
 const Map<String, dynamic> TESTS = const {
     'language/proxy_test.dart': null,
     'language/proxy2_test.dart': null,
+    'language/proxy3_test.dart': null,
+    'language/proxy4_test.dart': null,
+    'language/proxy5_test.dart': null,
 };
 
 void main(List<String> args) {
diff --git a/tests/compiler/dart2js/sourcemaps/diff_view.dart b/tests/compiler/dart2js/sourcemaps/diff_view.dart
new file mode 100644
index 0000000..0448a7f
--- /dev/null
+++ b/tests/compiler/dart2js/sourcemaps/diff_view.dart
@@ -0,0 +1,871 @@
+// 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 sourcemap.diff_view;
+
+import 'dart:async';
+import 'dart:io';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/diagnostics/invariant.dart';
+import 'package:compiler/src/io/position_information.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'sourcemap_helper.dart';
+import 'sourcemap_html_helper.dart';
+import 'trace_graph.dart';
+import 'js_tracer.dart';
+
+const String WITH_SOURCE_INFO_STYLE = 'background-color:#FF8080;';
+const String WITHOUT_SOURCE_INFO_STYLE = 'border: solid 1px #FF8080;';
+const String ADDITIONAL_SOURCE_INFO_STYLE = 'border: solid 1px #8080FF;';
+
+main(List<String> args) async {
+  DEBUG_MODE = true;
+  String out = 'out.js.diff_view.html';
+  String filename;
+  List<String> currentOptions = [];
+  List<List<String>> options = [currentOptions];
+  int argGroup = 0;
+  for (String arg in args) {
+    if (arg == '--') {
+      currentOptions = [];
+      options.add(currentOptions);
+      argGroup++;
+    } else if (arg.startsWith('-o')) {
+      out = arg.substring('-o'.length);
+    } else if (arg.startsWith('--out=')) {
+      out = arg.substring('--out='.length);
+    } else if (arg.startsWith('-')) {
+      currentOptions.add(arg);
+    } else {
+      filename = arg;
+    }
+  }
+  List<String> commonArguments = options[0];
+  List<String> options1;
+  List<String> options2;
+  if (options.length == 1) {
+    // Use default options; comparing SSA and CPS output using the new
+    // source information strategy.
+    options1 = [USE_NEW_SOURCE_INFO]..addAll(commonArguments);
+    options2 = [USE_NEW_SOURCE_INFO, Flags.useCpsIr]..addAll(commonArguments);
+  } else if (options.length == 2) {
+    // Use alternative options for the second output column.
+    options1 = commonArguments;
+    options2 = options[1]..addAll(commonArguments);
+  } else {
+    // Use specific options for both output columns.
+    options1 = options[1]..addAll(commonArguments);
+    options2 = options[2]..addAll(commonArguments);
+  }
+
+  print('Compiling ${options1.join(' ')} $filename');
+  CodeLinesResult result1 = await computeCodeLines(options1, filename);
+  print('Compiling ${options2.join(' ')} $filename');
+  CodeLinesResult result2 = await computeCodeLines(options2, filename);
+
+  StringBuffer sb = new StringBuffer();
+  sb.write('''
+<html>
+<head>
+<title>Diff for $filename</title>
+<style>
+.lineNumber {
+  font-size: smaller;
+  color: #888;
+}
+.header {
+  position: fixed;
+  width: 50%;
+  background-color: #400000;
+  color: #FFFFFF;
+  height: 20px;
+  top: 0px;
+  z-index: 1000;
+}
+.cell {
+  max-width:500px;
+  overflow-x:auto;
+  vertical-align:top;
+}
+.corresponding1 {
+  background-color: #FFFFE0;
+}
+.corresponding2 {
+  background-color: #EFEFD0;
+}
+.identical1 {
+  background-color: #E0F0E0;
+}
+.identical2 {
+  background-color: #C0E0C0;
+}
+</style>
+</head>
+<body>''');
+
+  sb.write('''
+<div class="header" style="left: 0px;">[${options1.join(',')}]</div>
+<div class="header" style="right: 0px;">[${options2.join(',')}]</div>
+<div style="position:absolute;top:22px;width:100%;height:18px;">
+  <span class="identical1">&nbsp;&nbsp;&nbsp;</span> 
+  <span class="identical2">&nbsp;&nbsp;&nbsp;</span>
+  identical blocks
+  <span class="corresponding1">&nbsp;&nbsp;&nbsp;</span>
+  <span class="corresponding2">&nbsp;&nbsp;&nbsp;</span> 
+  corresponding blocks
+  <span style="$WITH_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
+  offset with source information
+  <span style="$WITHOUT_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
+  offset without source information
+  <span style="$ADDITIONAL_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
+  offset with unneeded source information
+</div>
+<table style="position:absolute;top:40px;width:100%;"><tr>
+''');
+
+  void addCell(String content) {
+    sb.write('''
+<td class="cell"><pre>
+''');
+    sb.write(content);
+    sb.write('''
+</pre></td>
+''');
+  }
+
+  List<OutputStructure> structures = [
+      OutputStructure.parse(result1.codeLines),
+      OutputStructure.parse(result2.codeLines)];
+  List<List<CodeLine>> inputLines = [result1.codeLines, result2.codeLines];
+  List<List<HtmlPart>> outputLines = [<HtmlPart>[], <HtmlPart>[]];
+
+  /// Marker to alternate output colors.
+  bool alternating = false;
+
+  /// Enable 'corresponding' background colors for [f].
+  void withMatching(f()) {
+    HtmlPart start = new ConstHtmlPart(
+        '<div class="corresponding${alternating ? '1' : '2'}">');
+    HtmlPart end = new ConstHtmlPart('</div>');
+    alternating = !alternating;
+    outputLines[0].add(start);
+    outputLines[1].add(start);
+    f();
+    outputLines[0].add(end);
+    outputLines[1].add(end);
+  }
+
+  /// Enable 'identical' background colors for [f].
+  void withIdentical(f()) {
+    HtmlPart start = new ConstHtmlPart(
+        '<div class="identical${alternating ? '1' : '2'}">');
+    HtmlPart end = new ConstHtmlPart('</div>');
+    alternating = !alternating;
+    outputLines[0].add(start);
+    outputLines[1].add(start);
+    f();
+    outputLines[0].add(end);
+    outputLines[1].add(end);
+  }
+
+  /// Output code lines in [range] from input number [index], padding the other
+  /// column with empty lines.
+  void handleSkew(int index, Interval range) {
+    int from = range.from;
+    while (from < range.to) {
+      outputLines[1 - index].add(const ConstHtmlPart('\n'));
+      outputLines[index].add(
+          new CodeLineHtmlPart(inputLines[index][from++]));
+    }
+  }
+
+  /// Output code lines of the [indices] from the corresponding inputs.
+  void addBoth(List<int> indices) {
+    outputLines[0].add(new CodeLineHtmlPart(inputLines[0][indices[0]]));
+    outputLines[1].add(new CodeLineHtmlPart(inputLines[1][indices[1]]));
+  }
+
+  /// Output code lines of the [ranges] from the corresponding inputs.
+  void addBothLines(List<Interval> ranges) {
+    Interval range1 = ranges[0];
+    Interval range2 = ranges[1];
+    int offset = 0;
+    while (range1.from + offset < range1.to &&
+           range2.from + offset < range2.to) {
+      addBoth([range1.from + offset, range2.from + offset]);
+      offset++;
+    }
+    if (range1.from + offset < range1.to) {
+      handleSkew(0, new Interval(range1.from + offset, range1.to));
+    }
+    if (range2.from + offset < range2.to) {
+      handleSkew(1, new Interval(range2.from + offset, range2.to));
+    }
+  }
+
+  /// Merge the code lines in [range1] and [range2] of the corresponding input.
+  void addRaw(Interval range1, Interval range2) {
+    match(a, b) => a.code == b.code;
+
+    List<Interval> currentMatchedIntervals;
+
+    void flushMatching() {
+      if (currentMatchedIntervals != null) {
+        withIdentical(() {
+          addBothLines(currentMatchedIntervals);
+        });
+      }
+      currentMatchedIntervals = null;
+    }
+
+    align(
+        inputLines[0],
+        inputLines[1],
+        range1: range1,
+        range2: range2,
+        match: match,
+        handleSkew: (int listIndex, Interval range) {
+          flushMatching();
+          handleSkew(listIndex, range);
+        },
+        handleMatched: (List<int> indices) {
+          if (currentMatchedIntervals == null) {
+            currentMatchedIntervals = [
+              new Interval(indices[0], indices[0] + 1),
+              new Interval(indices[1], indices[1] + 1)];
+          } else {
+            currentMatchedIntervals[0] =
+                new Interval(currentMatchedIntervals[0].from, indices[0] + 1);
+            currentMatchedIntervals[1] =
+                new Interval(currentMatchedIntervals[1].from, indices[1] + 1);
+          }
+        },
+        handleUnmatched: (List<int> indices) {
+          flushMatching();
+          addBoth(indices);
+        });
+
+    flushMatching();
+  }
+
+  /// Output the lines of the library blocks in [childRange] in
+  /// `structures[index]`, padding the other column with empty lines.
+  void addBlock(int index, Interval childRange) {
+    handleSkew(index, structures[index].getChildInterval(childRange));
+  }
+
+  /// Output the members of the [classes] aligned.
+  void addMatchingClasses(List<LibraryClass> classes) {
+    withMatching(() {
+      addBothLines(classes.map((c) => c.header).toList());
+    });
+    align(classes[0].children, classes[1].children,
+        match: (a, b) => a.name == b.name,
+        handleSkew: (int listIndex, Interval childRange) {
+          handleSkew(listIndex,
+              classes[listIndex].getChildInterval(childRange));
+        },
+        handleMatched: (List<int> indices) {
+          List<Interval> intervals =  [
+              classes[0].getChild(indices[0]).interval,
+              classes[1].getChild(indices[1]).interval];
+          withMatching(() {
+            addBothLines(intervals);
+          });
+        },
+        handleUnmatched: (List<int> indices) {
+          List<Interval> intervals =  [
+              classes[0].getChild(indices[0]).interval,
+              classes[1].getChild(indices[1]).interval];
+          addBothLines(intervals);
+        });
+    withMatching(() {
+      addBothLines(classes.map((c) => c.footer).toList());
+    });
+  }
+
+  /// Output the library blocks in [indices] from the corresponding
+  /// [OutputStructure]s, aligning their content.
+  void addMatchingBlocks(List<int> indices) {
+    List<LibraryBlock> blocks = [
+      structures[0].getChild(indices[0]),
+      structures[1].getChild(indices[1])];
+
+    withMatching(() {
+      addBothLines(blocks.map((b) => b.header).toList());
+    });
+    align(blocks[0].children, blocks[1].children,
+        match: (a, b) => a.name == b.name,
+        handleSkew: (int listIndex, Interval childRange) {
+          handleSkew(listIndex, blocks[listIndex].getChildInterval(childRange));
+        },
+        handleMatched: (List<int> indices) {
+          List<BasicEntity> entities =  [
+              blocks[0].getChild(indices[0]),
+              blocks[1].getChild(indices[1])];
+          if (entities.every((e) => e is LibraryClass)) {
+            addMatchingClasses(entities);
+          } else {
+            withMatching(() {
+              addBothLines(entities.map((e) => e.interval).toList());
+            });
+          }
+        },
+        handleUnmatched: (List<int> indices) {
+          List<Interval> intervals =  [
+              blocks[0].getChild(indices[0]).interval,
+              blocks[1].getChild(indices[1]).interval];
+          addBothLines(intervals);
+        });
+    withMatching(() {
+      addBothLines(blocks.map((b) => b.footer).toList());
+    });
+  }
+
+  /// Output the lines of the blocks in [indices] from the corresponding
+  /// [OutputStructure]s.
+  void addUnmatchedBlocks(List<int> indices) {
+    List<LibraryBlock> blocks = [
+       structures[0].getChild(indices[0]),
+       structures[1].getChild(indices[1])];
+    addBothLines([blocks[0].interval, blocks[1].interval]);
+  }
+
+
+  addRaw(structures[0].header, structures[1].header);
+
+  align(structures[0].children,
+        structures[1].children,
+        match: (a, b) => a.name == b.name,
+        handleSkew: addBlock,
+        handleMatched: addMatchingBlocks,
+        handleUnmatched: addUnmatchedBlocks);
+
+  addRaw(structures[0].footer, structures[1].footer);
+
+  addCell(htmlPartsToString(outputLines[0], inputLines[0]));
+  addCell(htmlPartsToString(outputLines[1], inputLines[1]));
+
+  sb.write('''</tr><tr>''');
+  addCell(result1.coverage.getCoverageReport());
+  addCell(result2.coverage.getCoverageReport());
+
+  sb.write('''
+</tr></table>
+</body>
+</html>
+''');
+
+  new File(out).writeAsStringSync(sb.toString());
+  print('Diff generated in $out');
+}
+
+/// Align the content of [list1] and [list2].
+///
+/// If provided, [range1] and [range2] aligned the subranges of [list1] and
+/// [list2], otherwise the whole lists are aligned.
+///
+/// If provided, [match] determines the equality between members of [list1] and
+/// [list2], otherwise `==` is used.
+///
+/// [handleSkew] is called when a subrange of one list is not found in the
+/// other.
+///
+/// [handleMatched] is called when two indices match up.
+///
+/// [handleUnmatched] is called when two indices don't match up (none are found
+/// in the other list).
+void align(List list1,
+           List list2,
+           {Interval range1,
+            Interval range2,
+            bool match(a, b),
+            void handleSkew(int listIndex, Interval range),
+            void handleMatched(List<int> indices),
+            void handleUnmatched(List<int> indices)}) {
+  if (match == null) {
+    match = (a, b) => a == b;
+  }
+
+  if (range1 == null) {
+    range1 = new Interval(0, list1.length);
+  }
+  if (range2 == null) {
+    range2 = new Interval(0, list2.length);
+  }
+
+  Interval findInOther(
+      List thisLines, Interval thisRange,
+      List otherLines, Interval otherRange) {
+    for (int index = otherRange.from; index < otherRange.to; index++) {
+      if (match(thisLines[thisRange.from], otherLines[index])) {
+        int offset = 1;
+        while (thisRange.from + offset < thisRange.to &&
+               otherRange.from + offset < otherRange.to &&
+               match(thisLines[thisRange.from + offset],
+                     otherLines[otherRange.from + offset])) {
+          offset++;
+        }
+        return new Interval(index, index + offset);
+      }
+    }
+    return null;
+  }
+
+  int start1 = range1.from;
+  int end1 = range1.to;
+  int start2 = range2.from;
+  int end2 = range2.to;
+
+  const int ALIGN1 = -1;
+  const int UNMATCHED = 0;
+  const int ALIGN2 = 1;
+
+  while (start1 < end1 && start2 < end2) {
+    if (match(list1[start1], list2[start2])) {
+      handleMatched([start1++, start2++]);
+    } else {
+      Interval subrange1 = new Interval(start1, end1);
+      Interval subrange2 = new Interval(start2, end2);
+      Interval element2inList1 =
+          findInOther(list1, subrange1, list2, subrange2);
+      Interval element1inList2 =
+          findInOther(list2, subrange2, list1, subrange1);
+      int choice = 0;
+      if (element2inList1 != null) {
+        if (element1inList2 != null) {
+          if (element1inList2.length > 1 && element2inList1.length > 1) {
+            choice =
+                element2inList1.from < element1inList2.from ? ALIGN2 : ALIGN1;
+          } else if (element2inList1.length > 1) {
+            choice = ALIGN2;
+          } else if (element1inList2.length > 1) {
+            choice = ALIGN1;
+          } else {
+            choice =
+                element2inList1.from < element1inList2.from ? ALIGN2 : ALIGN1;
+          }
+        } else {
+          choice = ALIGN2;
+        }
+      } else if (element1inList2 != null) {
+        choice = ALIGN1;
+      }
+      switch (choice) {
+        case ALIGN1:
+          handleSkew(0, new Interval(start1, element1inList2.from));
+          start1 = element1inList2.from;
+          break;
+        case ALIGN2:
+          handleSkew(1, new Interval(start2, element2inList1.from));
+          start2 = element2inList1.from;
+          break;
+        case UNMATCHED:
+          handleUnmatched([start1++, start2++]);
+          break;
+      }
+    }
+  }
+  if (start1 < end1) {
+    handleSkew(0, new Interval(start1, end1));
+  }
+  if (start2 < end2) {
+    handleSkew(1, new Interval(start2, end2));
+  }
+}
+
+// Constants used to identify the subsection of the JavaScript output. These
+// are specifically for the unminified full_emitter output.
+const String HEAD = '  var dart = [';
+const String TAIL = '  }], ';
+const String END = '  setupProgram(dart';
+
+final RegExp TOP_LEVEL_VALUE = new RegExp(r'^    (".+?"):');
+final RegExp TOP_LEVEL_FUNCTION =
+    new RegExp(r'^    ([a-zA-Z0-9_$]+): \[?function');
+final RegExp TOP_LEVEL_CLASS = new RegExp(r'^    ([a-zA-Z0-9_$]+): \[?\{');
+
+final RegExp MEMBER_VALUE = new RegExp(r'^      (".+?"):');
+final RegExp MEMBER_FUNCTION =
+    new RegExp(r'^      ([a-zA-Z0-9_$]+): \[?function');
+final RegExp MEMBER_OBJECT = new RegExp(r'^      ([a-zA-Z0-9_$]+): \[?\{');
+
+/// Subrange of the JavaScript output.
+abstract class OutputEntity {
+  Interval get interval;
+  Interval get header;
+  Interval get footer;
+
+  List<OutputEntity> get children;
+
+  Interval getChildInterval(Interval childIndex) {
+    return new Interval(
+        children[childIndex.from].interval.from,
+        children[childIndex.to - 1].interval.to);
+
+  }
+
+  OutputEntity getChild(int index) {
+    return children[index];
+  }
+}
+
+/// The whole JavaScript output.
+class OutputStructure extends OutputEntity {
+  final List<CodeLine> lines;
+  final int headerEnd;
+  final int footerStart;
+  final List<LibraryBlock> children;
+
+  OutputStructure(
+      this.lines,
+      this.headerEnd,
+      this.footerStart,
+      this.children);
+
+  Interval get interval => new Interval(0, lines.length);
+
+  Interval get header => new Interval(0, headerEnd);
+
+  Interval get footer => new Interval(footerStart, lines.length);
+
+  /// Compute the structure of the JavaScript [lines].
+  static OutputStructure parse(List<CodeLine> lines) {
+
+    int findHeaderStart(List<CodeLine> lines) {
+      int index = 0;
+      for (CodeLine line in lines) {
+        if (line.code.startsWith(HEAD)) {
+          return index;
+        }
+        index++;
+      }
+      return lines.length;
+    }
+
+    int findHeaderEnd(int start, List<CodeLine> lines) {
+      int index = start;
+      for (CodeLine line in lines.skip(start)) {
+        if (line.code.startsWith(END)) {
+          return index;
+        }
+        index++;
+      }
+      return lines.length;
+    }
+
+    String readHeader(CodeLine line) {
+      String code = line.code;
+      String ssaLineHeader;
+      if (code.startsWith(HEAD)) {
+        return code.substring(HEAD.length);
+      } else if (code.startsWith(TAIL)) {
+        return code.substring(TAIL.length);
+      }
+      return null;
+    }
+
+    List<LibraryBlock> computeHeaderMap(
+        List<CodeLine> lines, int start, int end) {
+      List<LibraryBlock> libraryBlocks = <LibraryBlock>[];
+      LibraryBlock current;
+      for (int index = start; index < end; index++) {
+        String header = readHeader(lines[index]);
+        if (header != null) {
+          if (current != null) {
+            current.to = index;
+          }
+          libraryBlocks.add(current = new LibraryBlock(header, index));
+        }
+      }
+      if (current != null) {
+        current.to = end;
+      }
+      return libraryBlocks;
+    }
+
+    int headerEnd = findHeaderStart(lines);
+    int footerStart = findHeaderEnd(headerEnd, lines);
+    List<LibraryBlock> libraryBlocks =
+        computeHeaderMap(lines, headerEnd, footerStart);
+    for (LibraryBlock block in libraryBlocks) {
+      block.preprocess(lines);
+    }
+
+    return new OutputStructure(
+        lines, headerEnd, footerStart, libraryBlocks);
+  }
+}
+
+abstract class AbstractEntity extends OutputEntity {
+  final String name;
+  final int from;
+  int to;
+
+  AbstractEntity(this.name, this.from);
+
+  Interval get interval => new Interval(from, to);
+}
+
+/// A block defining the content of a Dart library.
+class LibraryBlock extends AbstractEntity {
+  List<BasicEntity> children = <BasicEntity>[];
+  int get headerEnd => from + 2;
+  int get footerStart => to - 1;
+
+  LibraryBlock(String name, int from) : super(name, from);
+
+  Interval get header => new Interval(from, headerEnd);
+
+  Interval get footer => new Interval(footerStart, to);
+
+  void preprocess(List<CodeLine> lines) {
+    int index = headerEnd;
+    BasicEntity current;
+    while (index < footerStart) {
+      String line = lines[index].code;
+      BasicEntity next;
+      Match matchFunction = TOP_LEVEL_FUNCTION.firstMatch(line);
+      if (matchFunction != null) {
+        next = new BasicEntity(matchFunction.group(1), index);
+      } else {
+        Match matchClass = TOP_LEVEL_CLASS.firstMatch(line);
+        if (matchClass != null) {
+          next = new LibraryClass(matchClass.group(1), index);
+        } else {
+          Match matchValue = TOP_LEVEL_VALUE.firstMatch(line);
+          if (matchValue != null) {
+            next = new BasicEntity(matchValue.group(1), index);
+          }
+        }
+      }
+      if (next != null) {
+        if (current != null) {
+          current.to = index;
+        }
+        children.add(current = next);
+      } else if (index == headerEnd) {
+        throw 'Failed to match first library block line:\n$line';
+      }
+
+      index++;
+    }
+    if (current != null) {
+      current.to = footerStart;
+    }
+
+    for (BasicEntity entity in children) {
+      entity.preprocess(lines);
+    }
+  }
+}
+
+/// A simple member of a library or class.
+class BasicEntity extends AbstractEntity {
+  BasicEntity(String name, int from) : super(name, from);
+
+  Interval get header => new Interval(from, to);
+
+  Interval get footer => new Interval(to, to);
+
+  List<OutputEntity> get children => const <OutputEntity>[];
+
+  void preprocess(List<CodeLine> lines) {}
+}
+
+/// A block defining a Dart class.
+class LibraryClass extends BasicEntity {
+  List<BasicEntity> children = <BasicEntity>[];
+  int get headerEnd => from + 1;
+  int get footerStart => to - 1;
+
+  LibraryClass(String name, int from) : super(name, from);
+
+  Interval get header => new Interval(from, headerEnd);
+
+  Interval get footer => new Interval(footerStart, to);
+
+  void preprocess(List<CodeLine> lines) {
+    int index = headerEnd;
+    BasicEntity current;
+    while (index < footerStart) {
+      String line = lines[index].code;
+      BasicEntity next;
+      Match matchFunction = MEMBER_FUNCTION.firstMatch(line);
+      if (matchFunction != null) {
+        next = new BasicEntity(matchFunction.group(1), index);
+      } else {
+        Match matchClass = MEMBER_OBJECT.firstMatch(line);
+        if (matchClass != null) {
+          next = new BasicEntity(matchClass.group(1), index);
+        } else {
+          Match matchValue = MEMBER_VALUE.firstMatch(line);
+          if (matchValue != null) {
+            next = new BasicEntity(matchValue.group(1), index);
+          }
+        }
+      }
+      if (next != null) {
+        if (current != null) {
+          current.to = index;
+        }
+        children.add(current = next);
+      } else if (index == headerEnd) {
+        throw 'Failed to match first library block line:\n$line';
+      }
+
+      index++;
+    }
+    if (current != null) {
+      current.to = footerStart;
+    }
+  }
+}
+
+class Interval {
+  final int from;
+  final int to;
+
+  const Interval(this.from, this.to);
+
+  int get length => to - from;
+}
+
+class HtmlPart {
+  void printHtmlOn(StringBuffer buffer) {}
+}
+
+class ConstHtmlPart implements HtmlPart {
+  final String html;
+
+  const ConstHtmlPart(this.html);
+
+  @override
+  void printHtmlOn(StringBuffer buffer) {
+    buffer.write(html);
+  }
+}
+
+class CodeLineHtmlPart implements HtmlPart {
+  final CodeLine line;
+
+  CodeLineHtmlPart(this.line);
+
+  @override
+  void printHtmlOn(StringBuffer buffer, [int lineNoWidth]) {
+    line.printHtmlOn(buffer, lineNoWidth);
+  }
+}
+
+/// Convert [parts] to an HTML string while checking invariants for [lines].
+String htmlPartsToString(List<HtmlPart> parts, List<CodeLine> lines) {
+  int lineNoWidth;
+  if (lines.isNotEmpty) {
+    lineNoWidth = '${lines.last.lineNo + 1}'.length;
+  }
+  StringBuffer buffer = new StringBuffer();
+  int expectedLineNo = 0;
+  for (HtmlPart part in parts) {
+    if (part is CodeLineHtmlPart) {
+      if (part.line.lineNo != expectedLineNo) {
+        print('Expected line no $expectedLineNo, found ${part.line.lineNo}');
+        if (part.line.lineNo < expectedLineNo) {
+          print('Duplicate lines:');
+          int index = part.line.lineNo;
+          while (index <= expectedLineNo) {
+            print(lines[index++].code);
+          }
+        } else {
+          print('Missing lines:');
+          int index = expectedLineNo;
+          while (index <= part.line.lineNo) {
+            print(lines[index++].code);
+          }
+        }
+        expectedLineNo = part.line.lineNo;
+      }
+      expectedLineNo++;
+      part.printHtmlOn(buffer, lineNoWidth);
+    } else {
+      part.printHtmlOn(buffer);
+    }
+  }
+  return buffer.toString();
+}
+
+class CodeLinesResult {
+  final List<CodeLine> codeLines;
+  final Coverage coverage;
+
+  CodeLinesResult(this.codeLines, this.coverage);
+}
+
+/// Compute [CodeLine]s and [Coverage] for [filename] using the given [options].
+Future<CodeLinesResult> computeCodeLines(
+    List<String> options,
+    String filename) async {
+  SourceMapProcessor processor = new SourceMapProcessor(filename);
+  List<SourceMapInfo> sourceMapInfoList =
+      await processor.process(options, perElement: false);
+
+  const int WITH_SOURCE_INFO = 0;
+  const int WITHOUT_SOURCE_INFO = 1;
+  const int ADDITIONAL_SOURCE_INFO = 2;
+
+  for (SourceMapInfo info in sourceMapInfoList) {
+    if (info.element != null) continue;
+
+    List<CodeLine> codeLines;
+    Coverage coverage = new Coverage();
+    List<Annotation> annotations = <Annotation>[];
+    String code = info.code;
+    TraceGraph graph = createTraceGraph(info, coverage);
+    Set<js.Node> mappedNodes = new Set<js.Node>();
+    for (TraceStep step in graph.steps) {
+      int offset;
+      if (options.contains(USE_NEW_SOURCE_INFO)) {
+        offset = step.offset.subexpressionOffset;
+      } else {
+        offset = info.jsCodePositions[step.node].startPosition;
+      }
+      if (offset != null) {
+        int id = step.sourceLocation != null
+            ? WITH_SOURCE_INFO : WITHOUT_SOURCE_INFO;
+        annotations.add(
+            new Annotation(id, offset, null));
+      }
+    }
+    if (!options.contains(USE_NEW_SOURCE_INFO)) {
+      for (js.Node node in info.nodeMap.nodes) {
+        if (!mappedNodes.contains(node)) {
+          int offset = info.jsCodePositions[node].startPosition;
+          annotations.add(
+                      new Annotation(ADDITIONAL_SOURCE_INFO, offset, null));
+        }
+      }
+    }
+    codeLines = convertAnnotatedCodeToCodeLines(
+        code,
+        annotations,
+        colorScheme: new CustomColorScheme(
+          single: (int id) {
+            if (id == WITH_SOURCE_INFO) {
+              return WITH_SOURCE_INFO_STYLE;
+            } else if (id == ADDITIONAL_SOURCE_INFO) {
+              return ADDITIONAL_SOURCE_INFO_STYLE;
+            }
+            return WITHOUT_SOURCE_INFO_STYLE;
+          },
+          multi: (List ids) {
+            if (ids.contains(WITH_SOURCE_INFO)) {
+              return WITH_SOURCE_INFO_STYLE;
+            } else if (ids.contains(ADDITIONAL_SOURCE_INFO)) {
+              return ADDITIONAL_SOURCE_INFO_STYLE;
+            }
+            return WITHOUT_SOURCE_INFO_STYLE;
+          }
+        ));
+    return new CodeLinesResult(codeLines, coverage);
+  }
+}
diff --git a/tests/compiler/dart2js/sourcemaps/js_tracer.dart b/tests/compiler/dart2js/sourcemaps/js_tracer.dart
new file mode 100644
index 0000000..1aa40fe
--- /dev/null
+++ b/tests/compiler/dart2js/sourcemaps/js_tracer.dart
@@ -0,0 +1,138 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library sourcemap.js_tracer;
+
+import 'package:compiler/src/io/source_information.dart';
+import 'package:compiler/src/io/position_information.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'sourcemap_helper.dart';
+import 'trace_graph.dart';
+
+/// Create a [TraceGraph] for [info] registering usage in [coverage].
+TraceGraph createTraceGraph(SourceMapInfo info, Coverage coverage) {
+  TraceGraph graph = new TraceGraph();
+  TraceListener listener = new StepTraceListener(graph);
+  CodePositionMap codePositions =
+      new CodePositionCoverage(info.jsCodePositions, coverage);
+  JavaScriptTracer tracer = new JavaScriptTracer(
+      codePositions, [new CoverageListener(coverage), listener]);
+  info.node.accept(tracer);
+  return graph;
+}
+
+class StepTraceListener extends TraceListener {
+  Map<js.Node, TraceStep> steppableMap = <js.Node, TraceStep>{};
+  final TraceGraph graph;
+
+  StepTraceListener(this.graph);
+
+  @override
+  void onStep(js.Node node, Offset offset, StepKind kind) {
+    SourceInformation sourceInformation = node.sourceInformation;
+    SourcePositionKind sourcePositionKind = SourcePositionKind.START;
+    List text = [node];
+    switch (kind) {
+      case StepKind.FUN:
+        sourcePositionKind = SourcePositionKind.INNER;
+        text = ['<exit>'];
+        break;
+      case StepKind.CALL:
+        CallPosition callPosition =
+            CallPosition.getSemanticPositionForCall(node);
+        sourcePositionKind = callPosition.sourcePositionKind;
+        break;
+      case StepKind.NEW:
+      case StepKind.RETURN:
+      case StepKind.BREAK:
+      case StepKind.CONTINUE:
+      case StepKind.THROW:
+      case StepKind.EXPRESSION_STATEMENT:
+        break;
+      case StepKind.IF_CONDITION:
+        js.If ifNode = node;
+        text = ['if(', ifNode.condition, ') ...'];
+        break;
+      case StepKind.FOR_INITIALIZER:
+        js.For forNode = node;
+        text = ['for(', forNode.init, '; ...) ...'];
+        break;
+      case StepKind.FOR_CONDITION:
+        js.For forNode = node;
+        text = ['for(...;', forNode.condition, '; ...) ...'];
+        break;
+      case StepKind.FOR_UPDATE:
+        js.For forNode = node;
+        text = ['for(...; ...', forNode.update, ') ...'];
+        break;
+      case StepKind.WHILE_CONDITION:
+        js.While whileNode = node;
+        text = ['while(', whileNode.condition, ') ...'];
+        break;
+      case StepKind.DO_CONDITION:
+        js.Do doNode = node;
+        text = ['do {... } (', doNode.condition, ')'];
+        break;
+      case StepKind.SWITCH_EXPRESSION:
+        js.Switch switchNode = node;
+        text = ['switch(', switchNode.key, ') ...'];
+        break;
+
+    }
+    createTraceStep(
+        node,
+        offset: offset,
+        sourceLocation: getSourceLocation(
+            node.sourceInformation, sourcePositionKind),
+        text: text);
+  }
+
+  void createTraceStep(
+      js.Node node,
+      {Offset offset,
+       List text,
+       String note,
+       SourceLocation sourceLocation}) {
+    int id = steppableMap.length;
+
+    if (text == null) {
+      text = [node];
+    }
+
+    TraceStep step = new TraceStep(
+        id, node,
+        offset,
+        text, sourceLocation);
+    graph.addStep(step);
+
+    steppableMap[node] = step;
+  }
+
+
+  void pushBranch(BranchKind kind, [value]) {
+    var branch;
+    switch (kind) {
+      case BranchKind.CONDITION:
+        branch = value ? 't' : 'f';
+        break;
+      case BranchKind.LOOP:
+        branch = 'l';
+        break;
+      case BranchKind.CATCH:
+        branch = 'c';
+        break;
+      case BranchKind.FINALLY:
+        branch = 'F';
+        break;
+      case BranchKind.CASE:
+        branch = '$value';
+        break;
+    }
+    graph.pushBranch(branch);
+  }
+
+  void popBranch() {
+    graph.popBranch();
+  }
+}
diff --git a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
index 9cb53e5..123cbe2 100644
--- a/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/sourcemap_helper.dart
@@ -11,8 +11,10 @@
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/helpers/helpers.dart';
 import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/io/code_output.dart';
 import 'package:compiler/src/io/source_file.dart';
 import 'package:compiler/src/io/source_information.dart';
+import 'package:compiler/src/io/position_information.dart';
 import 'package:compiler/src/js/js.dart' as js;
 import 'package:compiler/src/js/js_debug.dart';
 import 'package:compiler/src/js/js_source_mapping.dart';
@@ -21,15 +23,51 @@
 import '../memory_compiler.dart';
 import '../output_collector.dart';
 
+class SourceFileSink implements EventSink<String> {
+  final String filename;
+  StringBuffer sb = new StringBuffer();
+  SourceFile sourceFile;
+
+  SourceFileSink(this.filename);
+
+  @override
+  void add(String event) {
+    sb.write(event);
+  }
+
+  @override
+  void addError(errorEvent, [StackTrace stackTrace]) {
+    // Ignore.
+  }
+
+  @override
+  void close() {
+    sourceFile = new StringSourceFile.fromName(filename, sb.toString());
+  }
+}
+
 class OutputProvider implements CompilerOutput {
-  BufferedEventSink jsMapOutput;
+  Map<Uri, SourceFileSink> outputMap = <Uri, SourceFileSink>{};
+
+  SourceFile getSourceFile(Uri uri) {
+    SourceFileSink sink = outputMap[uri];
+    if (sink != null) {
+      return sink.sourceFile;
+    }
+    return null;
+  }
+
+  SourceFileSink createSourceFileSink(String name, String extension) {
+    String filename = '$name.$extension';
+    SourceFileSink sink = new SourceFileSink(filename);
+    Uri uri = Uri.parse(filename);
+    outputMap[uri] = sink;
+    return sink;
+  }
 
   @override
   EventSink<String> createEventSink(String name, String extension) {
-    if (extension == 'js.map') {
-      return jsMapOutput = new BufferedEventSink();
-    }
-    return new NullSink('$name.$extension');
+    return createSourceFileSink(name, extension);
   }
 }
 
@@ -42,11 +80,8 @@
   @override
   EventSink<String> createEventSink(String name, String extension) {
     EventSink<String> output = outputProvider(name, extension);
-    if (extension == 'js.map') {
-      output = new CloningEventSink(
-          [output, jsMapOutput = new BufferedEventSink()]);
-    }
-    return output;
+    return new CloningEventSink(
+        [output, createSourceFileSink(name, extension)]);
   }
 }
 
@@ -56,17 +91,23 @@
 
 class ProviderSourceFileManager implements SourceFileManager {
   final SourceFileProvider sourceFileProvider;
+  final OutputProvider outputProvider;
 
-  ProviderSourceFileManager(this.sourceFileProvider);
+  ProviderSourceFileManager(this.sourceFileProvider, this.outputProvider);
 
   @override
   SourceFile getSourceFile(uri) {
-    return sourceFileProvider.getSourceFile(uri);
+    SourceFile sourceFile = sourceFileProvider.getSourceFile(uri);
+    if (sourceFile == null) {
+      sourceFile = outputProvider.getSourceFile(uri);
+    }
+    return sourceFile;
   }
 }
 
 class RecordingPrintingContext extends LenientPrintingContext {
   CodePositionListener listener;
+  Map<js.Node, CodePosition> codePositions = <js.Node, CodePosition>{};
 
   RecordingPrintingContext(this.listener);
 
@@ -75,11 +116,163 @@
                 int startPosition,
                 int endPosition,
                 int closingPosition) {
+    codePositions[node] =
+        new CodePosition(startPosition, endPosition, closingPosition);
     listener.onPositions(
         node, startPosition, endPosition, closingPosition);
   }
 }
 
+/// A [SourceMapper] that records the source locations on each node.
+class RecordingSourceMapper implements SourceMapper {
+  final SourceMapper sourceMapper;
+  final _LocationRecorder nodeToSourceLocationsMap;
+
+  RecordingSourceMapper(this.sourceMapper, this.nodeToSourceLocationsMap);
+
+  @override
+  void register(js.Node node, int codeOffset, SourceLocation sourceLocation) {
+    nodeToSourceLocationsMap.register(node, codeOffset, sourceLocation);
+    sourceMapper.register(node, codeOffset, sourceLocation);
+  }
+}
+
+/// A wrapper of [SourceInformationProcessor] that records source locations and
+/// code positions.
+class RecordingSourceInformationProcessor
+    implements SourceInformationProcessor {
+  final RecordingSourceInformationStrategy wrapper;
+  final SourceInformationProcessor processor;
+  final CodePositionRecorder codePositions;
+  final LocationMap nodeToSourceLocationsMap;
+
+  RecordingSourceInformationProcessor(
+      this.wrapper,
+      this.processor,
+      this.codePositions,
+      this.nodeToSourceLocationsMap);
+
+  @override
+  void onPositions(js.Node node,
+                   int startPosition,
+                   int endPosition,
+                   int closingPosition) {
+    codePositions.registerPositions(
+        node, startPosition, endPosition, closingPosition);
+    processor.onPositions(node, startPosition, endPosition, closingPosition);
+  }
+
+  @override
+  void process(js.Node node, BufferedCodeOutput code) {
+    processor.process(node, code);
+    wrapper.registerProcess(
+        node, code, codePositions, nodeToSourceLocationsMap);
+  }
+}
+
+/// Information recording for a use of [SourceInformationProcessor].
+class RecordedSourceInformationProcess {
+  final js.Node root;
+  final String code;
+  final CodePositionRecorder codePositions;
+  final LocationMap nodeToSourceLocationsMap;
+
+  RecordedSourceInformationProcess(
+      this.root,
+      this.code,
+      this.codePositions,
+      this.nodeToSourceLocationsMap);
+}
+
+
+/// A wrapper of [JavaScriptSourceInformationStrategy] that records
+/// [RecordedSourceInformationProcess].
+class RecordingSourceInformationStrategy
+    extends JavaScriptSourceInformationStrategy {
+  final JavaScriptSourceInformationStrategy strategy;
+  final Map<RecordedSourceInformationProcess, js.Node> processMap =
+      <RecordedSourceInformationProcess, js.Node>{};
+  final Map<js.Node, RecordedSourceInformationProcess> nodeMap =
+      <js.Node, RecordedSourceInformationProcess>{};
+
+  RecordingSourceInformationStrategy(this.strategy);
+
+  @override
+  SourceInformationBuilder createBuilderForContext(AstElement element) {
+    return strategy.createBuilderForContext(element);
+  }
+
+  @override
+  SourceInformationProcessor createProcessor(SourceMapper sourceMapper) {
+    LocationMap nodeToSourceLocationsMap =
+        new _LocationRecorder();
+    CodePositionRecorder codePositions = new CodePositionRecorder();
+    return new RecordingSourceInformationProcessor(
+        this,
+        strategy.createProcessor(new RecordingSourceMapper(
+            sourceMapper, nodeToSourceLocationsMap)),
+            codePositions, nodeToSourceLocationsMap);
+  }
+
+  void registerProcess(js.Node root,
+                       BufferedCodeOutput code,
+                       CodePositionRecorder codePositions,
+                       LocationMap nodeToSourceLocationsMap) {
+    RecordedSourceInformationProcess subProcess =
+        new RecordedSourceInformationProcess(
+            root, code.getText(), codePositions, nodeToSourceLocationsMap);
+    processMap[subProcess] = root;
+  }
+
+  RecordedSourceInformationProcess subProcessForNode(js.Node node) {
+    return nodeMap.putIfAbsent(node, () {
+      for (RecordedSourceInformationProcess subProcess in processMap.keys) {
+        js.Node root = processMap[subProcess];
+        FindVisitor visitor = new FindVisitor(node);
+        root.accept(visitor);
+        if (visitor.found) {
+          return new RecordedSourceInformationProcess(
+              node,
+              subProcess.code,
+              subProcess.codePositions,
+              new _FilteredLocationMap(
+                  visitor.nodes, subProcess.nodeToSourceLocationsMap));
+        }
+        return null;
+      }
+    });
+  }
+}
+
+/// Visitor that collects all nodes that are within a function. Used by the
+/// [RecordingSourceInformationStrategy] to filter what is recorded in a
+/// [RecordedSourceInformationProcess].
+class FindVisitor extends js.BaseVisitor {
+  final js.Node soughtNode;
+  bool found = false;
+  bool add = false;
+  final Set<js.Node> nodes = new Set<js.Node>();
+
+  FindVisitor(this.soughtNode);
+
+  visitNode(js.Node node) {
+    if (node == soughtNode) {
+      found = true;
+      add = true;
+    }
+    if (add) {
+      nodes.add(node);
+    }
+    node.visitChildren(this);
+    if (node == soughtNode) {
+      add = false;
+    }
+  }
+}
+
+const String USE_NEW_SOURCE_INFO =  '--use-new-source-info';
+const String DISABLE_INLINING = '--disable-inlining';
+
 /// Processor that computes [SourceMapInfo] for the JavaScript compiled for a
 /// given Dart file.
 class SourceMapProcessor {
@@ -112,11 +305,12 @@
   /// Computes the [SourceMapInfo] for the compiled elements.
   Future<List<SourceMapInfo>> process(
       List<String> options,
-      {bool verbose: true}) async {
+      {bool verbose: true,
+       bool perElement: true}) async {
     OutputProvider outputProvider = outputToFile
-        ? new OutputProvider()
-        : new CloningOutputProvider(targetUri, sourceMapFileUri);
-    if (options.contains('--use-new-source-info')) {
+        ? new CloningOutputProvider(targetUri, sourceMapFileUri)
+        : new OutputProvider();
+    if (options.contains(USE_NEW_SOURCE_INFO)) {
       if (verbose) print('Using the new source information system.');
       useNewSourceInfo = true;
     }
@@ -125,7 +319,7 @@
         // TODO(johnniwinther): Use [verbose] to avoid showing diagnostics.
         options: ['--out=$targetUri', '--source-map=$sourceMapFileUri']
             ..addAll(options));
-    if (options.contains('--disable-inlining')) {
+    if (options.contains(DISABLE_INLINING)) {
       if (verbose) print('Inlining disabled');
       compiler.disableInlining = true;
     }
@@ -133,30 +327,58 @@
     JavaScriptBackend backend = compiler.backend;
     var handler = compiler.handler;
     SourceFileProvider sourceFileProvider = handler.provider;
-    sourceFileManager = new ProviderSourceFileManager(sourceFileProvider);
+    sourceFileManager = new ProviderSourceFileManager(
+        sourceFileProvider,
+        outputProvider);
+    RecordingSourceInformationStrategy strategy =
+        new RecordingSourceInformationStrategy(backend.sourceInformationStrategy);
+    backend.sourceInformationStrategy = strategy;
     await compiler.run(inputUri);
 
     List<SourceMapInfo> infoList = <SourceMapInfo>[];
-    backend.generatedCode.forEach((Element element, js.Expression node) {
-      js.JavaScriptPrintingOptions options =
-          new js.JavaScriptPrintingOptions();
-      JavaScriptSourceInformationStrategy sourceInformationStrategy =
-          compiler.backend.sourceInformationStrategy;
-      NodeToSourceLocationsMap nodeMap = new NodeToSourceLocationsMap();
-      SourceInformationProcessor sourceInformationProcessor =
-          sourceInformationStrategy.createProcessor(nodeMap);
-      RecordingPrintingContext printingContext =
-          new RecordingPrintingContext(sourceInformationProcessor);
-      new js.Printer(options, printingContext).visit(node);
-      sourceInformationProcessor.process(node);
-
-      String code = printingContext.getText();
+    if (perElement) {
+      backend.generatedCode.forEach((Element element, js.Expression node) {
+        RecordedSourceInformationProcess subProcess =
+            strategy.subProcessForNode(node);
+        if (subProcess == null) {
+          // TODO(johnniwinther): Find out when this is happening and if it
+          // is benign. (Known to happen for `bool#fromString`)
+          print('No subProcess found for $element');
+          return;
+        }
+        LocationMap nodeMap = subProcess.nodeToSourceLocationsMap;
+        String code = subProcess.code;
+        CodePositionRecorder codePositions = subProcess.codePositions;
+        CodePointComputer visitor =
+            new CodePointComputer(sourceFileManager, code, nodeMap);
+        visitor.apply(node);
+        List<CodePoint> codePoints = visitor.codePoints;
+        infoList.add(new SourceMapInfo(
+            element, code, node,
+            codePoints,
+            codePositions/*strategy.codePositions*/,
+            nodeMap));
+      });
+    } else {
+      // TODO(johnniwinther): Supported multiple output units.
+      RecordedSourceInformationProcess process = strategy.processMap.keys.first;
+      js.Node node = strategy.processMap[process];
+      String code;
+      LocationMap nodeMap;
+      CodePositionRecorder codePositions;
+      nodeMap = process.nodeToSourceLocationsMap;
+      code = process.code;
+      codePositions = process.codePositions;
       CodePointComputer visitor =
           new CodePointComputer(sourceFileManager, code, nodeMap);
       visitor.apply(node);
       List<CodePoint> codePoints = visitor.codePoints;
-      infoList.add(new SourceMapInfo(element, code, node, codePoints, nodeMap));
-    });
+      infoList.add(new SourceMapInfo(
+          null, code, node,
+          codePoints,
+          codePositions,
+          nodeMap));
+    }
 
     return infoList;
   }
@@ -167,19 +389,43 @@
   final String name;
   final Element element;
   final String code;
-  final js.Expression node;
+  final js.Node node;
   final List<CodePoint> codePoints;
-  final NodeToSourceLocationsMap nodeMap;
+  final CodePositionMap jsCodePositions;
+  final LocationMap nodeMap;
 
   SourceMapInfo(
-      Element element, this.code, this.node, this.codePoints, this.nodeMap)
-      : this.name = computeElementNameForSourceMaps(element),
+      Element element,
+      this.code,
+      this.node,
+      this.codePoints,
+      this.jsCodePositions,
+      this.nodeMap)
+      : this.name =
+          element != null ? computeElementNameForSourceMaps(element) : '',
         this.element = element;
+
+  String toString() {
+    return '$name:$element';
+  }
 }
 
 /// Collection of JavaScript nodes with their source mapped target offsets
 /// and source locations.
-class NodeToSourceLocationsMap implements SourceMapper {
+abstract class LocationMap {
+  Iterable<js.Node> get nodes;
+
+  Map<int, List<SourceLocation>> operator[] (js.Node node);
+
+  factory LocationMap.recorder() = _LocationRecorder;
+
+  factory LocationMap.filter(Set<js.Node> nodes, LocationMap map) =
+      _FilteredLocationMap;
+
+}
+
+class _LocationRecorder
+    implements SourceMapper, LocationMap {
   final Map<js.Node, Map<int, List<SourceLocation>>> _nodeMap = {};
 
   @override
@@ -196,11 +442,25 @@
   }
 }
 
+class _FilteredLocationMap implements LocationMap {
+  final Set<js.Node> _nodes;
+  final LocationMap map;
+
+  _FilteredLocationMap(this._nodes, this.map);
+
+  Iterable<js.Node> get nodes => map.nodes.where((n) => _nodes.contains(n));
+
+  Map<int, List<SourceLocation>> operator[] (js.Node node) {
+    return map[node];
+  }
+}
+
+
 /// Visitor that computes the [CodePoint]s for source mapping locations.
 class CodePointComputer extends js.BaseVisitor {
   final SourceFileManager sourceFileManager;
   final String code;
-  final NodeToSourceLocationsMap nodeMap;
+  final LocationMap nodeMap;
   List<CodePoint> codePoints = [];
 
   CodePointComputer(this.sourceFileManager, this.code, this.nodeMap);
diff --git a/tests/compiler/dart2js/sourcemaps/sourcemap_html_helper.dart b/tests/compiler/dart2js/sourcemaps/sourcemap_html_helper.dart
index 4227fee..52e871d 100644
--- a/tests/compiler/dart2js/sourcemaps/sourcemap_html_helper.dart
+++ b/tests/compiler/dart2js/sourcemaps/sourcemap_html_helper.dart
@@ -8,6 +8,7 @@
 library sourcemap.html.helper;
 
 import 'dart:convert';
+import 'dart:math' as Math;
 
 import 'package:compiler/src/io/source_file.dart';
 import 'package:compiler/src/io/source_information.dart';
@@ -40,9 +41,14 @@
   return 'linear-gradient(to right, ${startColor.toCss}, ${endColor.toCss})';
 }
 
-/// Return the html for the [index] line number.
-String lineNumber(int index) {
-  return '<span class="lineNumber">${index + 1} </span>';
+/// Return the html for the [index] line number. If [width] is provided, shorter
+/// line numbers will be prefixed with spaces to match the width.
+String lineNumber(int index, [int width]) {
+  String text = '${index + 1}';
+  if (width != null && text.length < width) {
+    text = (' ' * (width - text.length)) + text;
+  }
+  return '<span class="lineNumber">$text </span>';
 }
 
 /// Return the html escaped [text].
@@ -59,6 +65,10 @@
   SourceMapHtmlInfo(this.sourceMapInfo,
                     this.codeProcessor,
                     this.sourceLocationCollection);
+
+  String toString() {
+    return sourceMapInfo.toString();
+  }
 }
 
 /// A collection of source locations.
@@ -84,16 +94,98 @@
   }
 }
 
+abstract class CssColorScheme {
+  String singleLocationToCssColor(var id);
+
+  String multiLocationToCssColor(List ids);
+
+  bool get showLocationAsSpan;
+}
+
+class CustomColorScheme implements CssColorScheme {
+  final bool showLocationAsSpan;
+  final Function single;
+  final Function multi;
+
+  CustomColorScheme(
+      {this.showLocationAsSpan: false,
+       String this.single(var id),
+       String this.multi(List ids)});
+
+  String singleLocationToCssColor(var id) => single != null ? single(id) : null;
+
+  String multiLocationToCssColor(List ids) => multi != null ? multi(ids) : null;
+}
+
+class PatternCssColorScheme implements CssColorScheme {
+  const PatternCssColorScheme();
+
+  bool get showLocationAsSpan => true;
+
+  String singleLocationToCssColor(int index) {
+    return "background:${toPattern(index)};";
+  }
+
+  String multiLocationToCssColor(List<int> indices) {
+
+    StringBuffer sb = new StringBuffer();
+    double delta = 100.0 / (indices.length);
+    double position = 0.0;
+
+    void addColor(String color) {
+      sb.write(', ${color} ${position.toInt()}%');
+      position += delta;
+      sb.write(', ${color} ${position.toInt()}%');
+    }
+
+    for (int index in indices) {
+      addColor('${toColorCss(index)}');
+    }
+    return 'background: linear-gradient(to right${sb}); '
+           'background-size: 10px 10px;';
+  }
+}
+
+class SingleColorScheme implements CssColorScheme {
+  const SingleColorScheme();
+
+  bool get showLocationAsSpan => false;
+
+  String singleLocationToCssColor(int index) {
+    return "background:${toColorCss(index)};";
+  }
+
+  String multiLocationToCssColor(List<int> indices) {
+    StringBuffer sb = new StringBuffer();
+    double delta = 100.0 / (indices.length);
+    double position = 0.0;
+
+    void addColor(String color) {
+      sb.write(', ${color} ${position.toInt()}%');
+      position += delta;
+      sb.write(', ${color} ${position.toInt()}%');
+    }
+
+    for (int index in indices) {
+      addColor('${toColorCss(index)}');
+    }
+    return 'background: linear-gradient(to bottom${sb}); '
+           'background-size: 10px 3px;';
+  }
+}
+
 /// Processor that computes the HTML representation of a block of JavaScript
 /// code and collects the source locations mapped in the code.
 class CodeProcessor {
   int lineIndex = 0;
-  final String onclick;
+  final String name;
   int currentJsSourceOffset = 0;
   final SourceLocationCollection collection;
   final Map<int, List<SourceLocation>> codeLocations = {};
+  final CssColorScheme colorScheme;
 
-  CodeProcessor(this.onclick, this.collection);
+  CodeProcessor(this.name, this.collection,
+      {this.colorScheme: const PatternCssColorScheme()});
 
   void addSourceLocation(int targetOffset, SourceLocation sourceLocation) {
     codeLocations.putIfAbsent(targetOffset, () => []).add(sourceLocation);
@@ -101,102 +193,275 @@
   }
 
   String convertToHtml(String text) {
-    StringBuffer htmlBuffer = new StringBuffer();
-    int offset = 0;
-    int lineIndex = 0;
-    bool pendingSourceLocationsEnd = false;
-    htmlBuffer.write(lineNumber(lineIndex));
-    SourceLocation currentLocation;
-
-    void endCurrentLocation() {
-      if (currentLocation != null) {
-        htmlBuffer.write('</a>');
-      }
-      currentLocation = null;
-    }
-
-    void addSubstring(int until) {
-      if (until <= offset) return;
-
-      String substring = text.substring(offset, until);
-      offset = until;
-      bool first = true;
-      for (String line in substring.split('\n')) {
-        if (!first) {
-          endCurrentLocation();
-          htmlBuffer.write('\n');
-          lineIndex++;
-          htmlBuffer.write(lineNumber(lineIndex));
+    List<Annotation> annotations = <Annotation>[];
+    codeLocations.forEach((int codeOffset, List<SourceLocation> locations) {
+      for (SourceLocation location in locations) {
+        if (location != null) {
+          annotations.add(new Annotation(
+              collection.getIndex(location),
+              codeOffset,
+              location.shortText));
         }
-        htmlBuffer.write(escape(line));
-        first = false;
       }
-    }
-
-    void insertSourceLocations(List<SourceLocation> lastSourceLocations) {
-      endCurrentLocation();
-
-      String color;
-      int index;
-      String title;
-      if (lastSourceLocations.length == 1) {
-        SourceLocation sourceLocation = lastSourceLocations.single;
-        if (sourceLocation != null) {
-          index = collection.getIndex(sourceLocation);
-          color = "background:${toPattern(index)};";
-          title = sourceLocation.shortText;
-          currentLocation = sourceLocation;
-        }
-      } else {
-
-        index = collection.getIndex(lastSourceLocations.first);
-        StringBuffer sb = new StringBuffer();
-        double delta = 100.0 / (lastSourceLocations.length);
-        double position = 0.0;
-
-        void addColor(String color) {
-          sb.write(', ${color} ${position.toInt()}%');
-          position += delta;
-          sb.write(', ${color} ${position.toInt()}%');
-        }
-
-        for (SourceLocation sourceLocation in lastSourceLocations) {
-          if (sourceLocation == null) continue;
-          int colorIndex = collection.getIndex(sourceLocation);
-          addColor('${toColorCss(colorIndex)}');
-          currentLocation = sourceLocation;
-        }
-        color = 'background: linear-gradient(to right${sb}); '
-                'background-size: 10px 10px;';
-        title = lastSourceLocations.map((l) => l.shortText).join(',');
-      }
-      if (index != null) {
-        Set<int> indices =
-            lastSourceLocations.map((l) => collection.getIndex(l)).toSet();
-        String onmouseover = indices.map((i) => '\'$i\'').join(',');
-        htmlBuffer.write(
-            '<a name="js$index" href="#${index}" style="$color" title="$title" '
-            'onclick="${onclick}" onmouseover="highlight([${onmouseover}]);"'
-            'onmouseout="highlight([]);">');
-        pendingSourceLocationsEnd = true;
-      }
-      if (lastSourceLocations.last == null) {
-        endCurrentLocation();
-      }
-    }
-
-    for (int targetOffset in codeLocations.keys.toList()..sort()) {
-      List<SourceLocation> sourceLocations = codeLocations[targetOffset];
-      addSubstring(targetOffset);
-      insertSourceLocations(sourceLocations);
-    }
-
-    addSubstring(text.length);
-    endCurrentLocation();
-    return htmlBuffer.toString();
+    });
+    return convertAnnotatedCodeToHtml(
+        text, annotations, colorScheme: colorScheme,
+        elementScheme: new HighlightLinkScheme(name),
+        windowSize: 3);
   }
 }
 
+class Annotation {
+  final id;
+  final int codeOffset;
+  final String title;
+
+  Annotation(this.id, this.codeOffset, this.title);
+}
+
+class ElementScheme {
+  const ElementScheme();
+
+  String getName(var id, Set ids) => null;
+  String getHref(var id, Set ids) => null;
+  String onClick(var id, Set ids) => null;
+  String onMouseOver(var id, Set ids) => null;
+  String onMouseOut(var id, Set ids) => null;
+}
+
+class HighlightLinkScheme implements ElementScheme {
+  final String name;
+
+  HighlightLinkScheme(this.name);
+
+  @override
+  String getName(int id, Set<int> indices) {
+    return 'js$id';
+  }
+
+  @override
+  String getHref(int id, Set<int> indices) {
+    return "#${id}";
+  }
+
+  @override
+  String onClick(int id, Set<int> indices) {
+    return "show(\'$name\');";
+  }
+
+  @override
+  String onMouseOut(int id, Set<int> indices) {
+    String onmouseover = indices.map((i) => '\'$i\'').join(',');
+    return "highlight([${onmouseover}]);";
+  }
+
+  @override
+  String onMouseOver(int id, Set<int> indices) {
+    return "highlight([]);";
+  }
+}
+
+String convertAnnotatedCodeToHtml(
+    String code,
+    Iterable<Annotation> annotations,
+    {CssColorScheme colorScheme: const SingleColorScheme(),
+     ElementScheme elementScheme: const ElementScheme(),
+     int windowSize}) {
+  StringBuffer htmlBuffer = new StringBuffer();
+  List<CodeLine> lines = convertAnnotatedCodeToCodeLines(
+      code, annotations,
+      colorScheme: colorScheme,
+      elementScheme: elementScheme,
+      windowSize: windowSize);
+  int lineNoWidth;
+  if (lines.isNotEmpty) {
+    lineNoWidth = '${lines.last.lineNo + 1}'.length;
+  }
+  for (CodeLine line in lines) {
+    line.printHtmlOn(htmlBuffer, lineNoWidth);
+  }
+  return htmlBuffer.toString();
+}
+
+List<CodeLine> convertAnnotatedCodeToCodeLines(
+    String code,
+    Iterable<Annotation> annotations,
+    {CssColorScheme colorScheme: const SingleColorScheme(),
+     ElementScheme elementScheme: const ElementScheme(),
+     int windowSize}) {
+
+  List<CodeLine> lines = <CodeLine>[];
+  CodeLine currentLine;
+  int offset = 0;
+  int lineIndex = 0;
+  int firstLine;
+  int lastLine;
+  bool pendingSourceLocationsEnd = false;
+
+  void write(String code, String html) {
+    if (currentLine != null) {
+      currentLine.codeBuffer.write(code);
+      currentLine.htmlParts.add(html);
+    }
+  }
+
+  void startLine() {
+    lines.add(currentLine = new CodeLine(lines.length));
+  }
+
+  void endCurrentLocation() {
+    if (pendingSourceLocationsEnd) {
+      write('', '</a>');
+    }
+    pendingSourceLocationsEnd = false;
+  }
+
+  void addSubstring(int until, {bool isFirst: false, bool isLast: false}) {
+    if (until <= offset) return;
+    if (offset >= code.length) return;
+
+    String substring = code.substring(offset, until);
+    offset = until;
+    bool first = true;
+
+    if (isLast) {
+      lastLine = lineIndex;
+    }
+    if (isFirst) {
+      startLine();
+    }
+    for (String line in substring.split('\n')) {
+      if (!first) {
+        endCurrentLocation();
+        write('', '\n');
+        lineIndex++;
+        startLine();
+      }
+      if (pendingSourceLocationsEnd && !colorScheme.showLocationAsSpan) {
+        if (line.isNotEmpty) {
+          String before = line.substring(0, 1);
+          write(before, escape(before));
+          endCurrentLocation();
+          String after = line.substring(1);
+          write(after, escape(after));
+        }
+      } else {
+        write(line, escape(line));
+      }
+      first = false;
+    }
+    if (isFirst) {
+      firstLine = lineIndex;
+    }
+  }
+
+  void insertAnnotations(List<Annotation> annotations) {
+    endCurrentLocation();
+
+    String color;
+    var id;
+    String title;
+    if (annotations.length == 1) {
+      Annotation annotation = annotations.single;
+      if (annotation != null) {
+        id = annotation.id;
+        color = colorScheme.singleLocationToCssColor(id);
+        title = annotation.title;
+      }
+    } else {
+      id = annotations.first.id;
+      List ids = [];
+      for (Annotation annotation in annotations) {
+        ids.add(annotation.id);
+      }
+      color = colorScheme.multiLocationToCssColor(ids);
+      title = annotations.map((l) => l.title).join(',');
+    }
+    if (id != null) {
+      Set ids = annotations.map((l) => l.id).toSet();
+      String name = elementScheme.getName(id, ids);
+      String href = elementScheme.getHref(id, ids);
+      String onclick = elementScheme.onClick(id, ids);
+      String onmouseover = elementScheme.onMouseOver(id, ids);
+      String onmouseout = elementScheme.onMouseOut(id, ids);
+      write('', '<a');
+      if (href != null) {
+        write('', ' href="${href}"');
+      }
+      if (name != null) {
+        write('', ' name="${name}"');
+      }
+      if (title != null) {
+        write('', ' title="${escape(title)}"');
+      }
+      write('', ' style="${color}"');
+      if (onclick != null) {
+        write('', ' onclick="${onclick}"');
+      }
+      if (onmouseover != null) {
+        write('', ' onmouseover="${onmouseover}"');
+      }
+      if (onmouseout != null) {
+        write('', ' onmouseout="${onmouseout}"');
+      }
+      write('', '>');
+      pendingSourceLocationsEnd = true;
+    }
+    if (annotations.last == null) {
+      endCurrentLocation();
+    }
+  }
+
+  Map<int, List<Annotation>> annotationMap = <int, List<Annotation>>{};
+  for (Annotation annotation in annotations) {
+    annotationMap.putIfAbsent(annotation.codeOffset, () => <Annotation>[])
+                 .add(annotation);
+  }
+
+  bool first = true;
+  for (int codeOffset in annotationMap.keys.toList()..sort()) {
+    List<Annotation> annotationList = annotationMap[codeOffset];
+    addSubstring(codeOffset, isFirst: first);
+    insertAnnotations(annotationList);
+    first = false;
+  }
+
+  addSubstring(code.length, isFirst: first, isLast: true);
+  endCurrentLocation();
+
+  int start = 0;
+  int end = lines.length - 1;
+  if (windowSize != null) {
+    start = Math.max(firstLine - windowSize, start);
+    end = Math.min(lastLine + windowSize, end);
+  }
+  return lines.sublist(start, end);
+}
+
+class CodeLine {
+  final int lineNo;
+  final StringBuffer codeBuffer = new StringBuffer();
+  final List<String> htmlParts = <String>[];
+  String _code;
+
+  CodeLine(this.lineNo);
+
+  String get code {
+    if (_code == null) {
+      _code = codeBuffer.toString();
+    }
+    return _code;
+  }
+
+  void printHtmlOn(StringBuffer htmlBuffer, [int lineNoWidth]) {
+    htmlBuffer.write(lineNumber(lineNo, lineNoWidth));
+    for (String part in htmlParts) {
+      htmlBuffer.write(part);
+    }
+  }
+}
+
+
 /// Computes the HTML representation for a collection of JavaScript code blocks.
 String computeJsHtml(Iterable<SourceMapHtmlInfo> infoList) {
 
@@ -240,10 +505,10 @@
   js.Node node = info.node;
   String code = info.code;
   String name = info.name;
-  String onclick = 'show(\'$name\');';
   SourceLocationCollection subcollection =
       new SourceLocationCollection(collection);
-  CodeProcessor codeProcessor = new CodeProcessor(onclick, subcollection);
+  CodeProcessor codeProcessor = new CodeProcessor(name, subcollection);
+  //print('${info.element}:${info.nodeMap.nodes.length}');
   for (js.Node node in info.nodeMap.nodes) {
     info.nodeMap[node].forEach(
         (int targetOffset, List<SourceLocation> sourceLocations) {
@@ -312,6 +577,11 @@
 
     int firstLineIndex;
     int lastLineIndex;
+    List<int> lineIndices = uriMap.keys.toList()..sort();
+    int lineNoWidth;
+    if (lineIndices.isNotEmpty) {
+      lineNoWidth = '${lineIndices.last + windowSize + 1}'.length;
+    }
 
     void flush() {
       if (firstLineIndex != null && lastLineIndex != null) {
@@ -325,7 +595,7 @@
              line < firstLineIndex;
              line++) {
           if (line >= 0) {
-            dartCodeBuffer.write(lineNumber(line));
+            dartCodeBuffer.write(lineNumber(line, lineNoWidth));
             dartCodeBuffer.write(sourceFile.getLineText(line));
           }
         }
@@ -334,7 +604,7 @@
              line <= lastLineIndex + windowSize;
              line++) {
           if (line < sourceFile.lines) {
-            dartCodeBuffer.write(lineNumber(line));
+            dartCodeBuffer.write(lineNumber(line, lineNoWidth));
             dartCodeBuffer.write(sourceFile.getLineText(line));
           }
         }
@@ -345,7 +615,6 @@
       codeBuffer.clear();
     }
 
-    List<int> lineIndices = uriMap.keys.toList()..sort();
     lineIndices.forEach((int lineIndex) {
       List<SourceLocation> locations = uriMap[lineIndex];
       if (lastLineIndex != null &&
@@ -356,7 +625,7 @@
         firstLineIndex = lineIndex;
       } else {
         for (int line = lastLineIndex + 1; line < lineIndex; line++) {
-          codeBuffer.write(lineNumber(line));
+          codeBuffer.write(lineNumber(line, lineNoWidth));
           codeBuffer.write(sourceFile.getLineText(line));
         }
       }
@@ -371,7 +640,7 @@
           end = locations[i + 1].column;
         }
         if (i == 0) {
-          codeBuffer.write(lineNumber(lineIndex));
+          codeBuffer.write(lineNumber(lineIndex, lineNoWidth));
           codeBuffer.write(line.substring(0, start));
         }
         codeBuffer.write(
diff --git a/tests/compiler/dart2js/sourcemaps/trace_graph.dart b/tests/compiler/dart2js/sourcemaps/trace_graph.dart
new file mode 100644
index 0000000..b21014b
--- /dev/null
+++ b/tests/compiler/dart2js/sourcemaps/trace_graph.dart
@@ -0,0 +1,54 @@
+// 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 sourcemap.trace_graph;
+
+import 'dart:collection';
+
+import 'package:compiler/src/io/source_information.dart';
+import 'package:compiler/src/io/position_information.dart';
+
+import 'sourcemap_html_helper.dart';
+
+class TraceGraph {
+  List<TraceStep> steps = <TraceStep>[];
+  TraceStep entry;
+  Queue stack = new Queue();
+
+  void addStep(TraceStep step) {
+    steps.add(step);
+    step.stack = stack.toList();
+  }
+
+  void pushBranch(branch) {
+    stack.addLast(branch);
+  }
+
+  void popBranch() {
+    stack.removeLast();
+  }
+}
+
+class TraceStep {
+  final int id;
+  final node;
+  final Offset offset;
+  final List text;
+  final SourceLocation sourceLocation;
+
+  TraceStep next;
+  Map<dynamic, TraceStep> branchMap;
+
+  List stack;
+
+  TraceStep(
+      this.id,
+      this.node,
+      this.offset,
+      this.text,
+      [this.sourceLocation]);
+
+  String toString() => '<span style="background:${toColorCss(id)}">$id</span>';
+}
+
diff --git a/tests/compiler/dart2js/type_mask_disjoint_test.dart b/tests/compiler/dart2js/type_mask_disjoint_test.dart
new file mode 100644
index 0000000..4cc7a00
--- /dev/null
+++ b/tests/compiler/dart2js/type_mask_disjoint_test.dart
@@ -0,0 +1,184 @@
+// 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.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/types/types.dart';
+
+import 'compiler_helper.dart';
+
+const String CODE = """
+class A {}
+class B extends A {}
+class C extends A {}
+
+class D implements A {}
+
+class E {}
+class F extends E {}
+class G implements E {}
+
+class H {}
+class I implements H {}
+class J extends D implements I {}
+
+class K {}
+class M extends K with A {}
+
+main() {
+  print([new A(), new B(), new C(), new D(), new E(), new F(), new G(),
+      new H(), new I(), new J(), new K(), new M()]);
+}
+""";
+
+Uri uri = new Uri(scheme: 'source');
+var compiler = compilerFor(CODE, uri);
+var world = compiler.world;
+
+main() {
+  asyncTest(() => compiler.run(uri).then((_) {
+
+    // Empty
+    check(' ! ', ' ! ');  // both non-null
+    check(' ! ', '   ');  // one non-null
+    check('   ', ' ! ');  // one non-null
+    check('   ', '   ', areDisjoint: false); // null is common
+
+    // Exact
+    check('A!=', 'A!=', areDisjoint: false);
+    check('A!=', 'B!=');
+    check('A!=', 'E!=');
+    check('A =', 'E =', areDisjoint: false); // null is common
+    check('M!=', 'K!=');
+    check('M!=', 'A!=');
+
+    // Exact with subclass
+    check('A!=', 'A!<', areDisjoint: false);
+    check('B!=', 'A!<', areDisjoint: false);
+    check('A!=', 'B!<');
+    check('A!=', 'E!<');
+    check('A =', 'E!<');
+    check('A =', 'E <', areDisjoint: false);
+    check('M!=', 'K!<', areDisjoint: false);
+    check('M!=', 'A!<');
+
+    // Exact with subtype
+    check('A!=', 'A!*', areDisjoint: false);
+    check('B!=', 'A!*', areDisjoint: false);
+    check('A!=', 'B!*');
+    check('A!=', 'E!*');
+    check('A!=', 'I!*');
+    check('J!=', 'H!*', areDisjoint: false);
+    check('M!=', 'K!*', areDisjoint: false);
+    check('M!=', 'A!*', areDisjoint: false);
+
+    // Subclass with subclass
+    check('A!<', 'A!<', areDisjoint: false);
+    check('A!<', 'B!<', areDisjoint: false);
+    check('A!<', 'E!<');
+    check('A!<', 'H!<');
+    check('D!<', 'I!<');
+
+    // Subclass with subtype
+    check('A!<', 'A!*', areDisjoint: false);
+    check('A!<', 'B!*', areDisjoint: false);
+    check('A!<', 'E!*');
+    check('A!<', 'H!*');
+    check('D!<', 'I!*', areDisjoint: false);
+
+    // Subtype with subtype
+    check('A!*', 'A!*', areDisjoint: false);
+    check('A!*', 'B!*', areDisjoint: false);
+    check('A!*', 'E!*');
+    check('A!*', 'H!*', areDisjoint: false);
+    check('D!*', 'I!*', areDisjoint: false);
+
+    // Unions!
+    checkUnions(['B!=', 'C!='], ['A!=']);
+    checkUnions(['B!=', 'C!='], ['A =']);
+    checkUnions(['B!=', 'C ='], ['A ='], areDisjoint: false);
+
+    checkUnions(['B!=', 'C!='], ['A!<'], areDisjoint: false);
+    checkUnions(['B!=', 'C!='], ['B!='], areDisjoint: false);
+    checkUnions(['A!<', 'E!<'], ['C!='], areDisjoint: false);
+    checkUnions(['A!<', 'E!<'], ['F!='], areDisjoint: false);
+
+    checkUnions(['A!=', 'E!='], ['C!=', 'F!=']);
+    checkUnions(['A!=', 'E!='], ['A!=', 'F!='], areDisjoint: false);
+    checkUnions(['B!=', 'E!='], ['A!<', 'F!='], areDisjoint: false);
+    checkUnions(['A!<', 'E!<'], ['C!=', 'F!='], areDisjoint: false);
+    checkUnions(['A!=', 'E!='], ['C!=', 'F!=']);
+  }));
+}
+
+/// Checks the expectation of `isDisjoint` for two mask. Also checks that the
+/// result is consistent with an equivalent (but slower) implementation based on
+/// intersection.
+checkMask(TypeMask m1, TypeMask m2, {areDisjoint: false}) {
+  print('masks: $m1 $m2');
+  Expect.equals(areDisjoint, m1.isDisjoint(m2, world));
+  Expect.equals(areDisjoint, m2.isDisjoint(m1, world));
+  var i1 = m1.intersection(m2, world);
+  Expect.equals(areDisjoint, i1.isEmpty && !i1.isNullable);
+  var i2 = m2.intersection(m1, world);
+  Expect.equals(areDisjoint, i2.isEmpty && !i2.isNullable);
+}
+
+/// Checks the expectation of `isDisjoint` for two mask descriptors (see
+/// [maskOf] for details).
+check(String typeMaskDescriptor1, String typeMaskDescriptor2,
+    {areDisjoint: true}) {
+  print('[$typeMaskDescriptor1] & [$typeMaskDescriptor2]');
+  checkMask(maskOf(typeMaskDescriptor1), maskOf(typeMaskDescriptor2),
+      areDisjoint: areDisjoint);
+}
+
+
+checkUnions(List descriptors1, List descriptors2, {areDisjoint: true}) {
+  print('[$descriptors1] & [$descriptors2]');
+  var m1 = new TypeMask.unionOf(descriptors1.map(maskOf).toList(), world);
+  var m2 = new TypeMask.unionOf(descriptors2.map(maskOf).toList(), world);
+  checkMask(m1, m2, areDisjoint: areDisjoint);
+}
+
+Map _maskCache = {};
+Map _elementCache = {};
+
+/// Parses a descriptor of a flat mask. A descriptor is of the form "AXY" where:
+///   A: either a type T or " " (base class or empty)
+///   X: can be either ! or " " (nullable/nonnullable)
+///   Y: can be either " " (no flag), = (exact), < (subclass), * (subtype)
+///
+/// Examples:
+///   "-! " - empty, non-null
+///   "-  " - null
+///   "Type!=" - non-null exact Type
+///   "Type =" - nullable exact Type
+///   "Type!<" - non-null subclass of Type
+///   "Type!*" - non-null subtype of Type
+TypeMask maskOf(String descriptor) =>
+  _maskCache.putIfAbsent(descriptor, () {
+    Expect.isTrue(descriptor.length >= 3);
+    var type = descriptor.substring(0, descriptor.length - 2);
+    bool isNullable = descriptor[descriptor.length - 2] != '!';
+    bool isExact = descriptor[descriptor.length - 1] == '=';
+    bool isSubclass = descriptor[descriptor.length - 1] == '<';
+    bool isSubtype = descriptor[descriptor.length - 1] == '*';
+
+    if (type == " ") {
+      Expect.isFalse(isExact || isSubclass || isSubtype);
+      return isNullable ? new TypeMask.empty() : new TypeMask.nonNullEmpty();
+    }
+
+    Expect.isTrue(isExact || isSubclass || isSubtype);
+    var element = _elementCache.putIfAbsent(type,
+        () => type == " " ? null : findElement(compiler, type));
+
+    var mask = isExact
+        ? new TypeMask.nonNullExact(element, world)
+        : (isSubclass
+            ? new TypeMask.nonNullSubclass(element, world)
+            : new TypeMask.nonNullSubtype(element, world));
+    return isNullable ? mask.nullable() : mask;
+  });
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index 0a2d4e0..ce4f3c8 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -50,7 +50,7 @@
     }
 
     String stringify(Expression expression) {
-      return prettyPrint(expression, env.compiler).buffer.toString();
+      return prettyPrint(expression, env.compiler);
     }
 
     void expect(DartType type,
diff --git a/tests/compiler/dart2js/world_test.dart b/tests/compiler/dart2js/world_test.dart
index 13a0821..0109f8d 100644
--- a/tests/compiler/dart2js/world_test.dart
+++ b/tests/compiler/dart2js/world_test.dart
@@ -7,13 +7,22 @@
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
 import 'type_test_helper.dart';
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/elements/elements.dart'
        show Element, ClassElement;
+import 'package:compiler/src/universe/class_set.dart';
 import 'package:compiler/src/world.dart' show ClassWorld;
 
 void main() {
-  asyncTest(() => TypeEnvironment.create(r"""
-      class A {}
+  asyncTest(() async {
+    await testClassSets();
+    await testProperties();
+  });
+}
+
+testClassSets() async {
+  var env = await TypeEnvironment.create(r"""
+      class A implements X {}
       class B {}
       class C_Super extends A {}
       class C extends C_Super {}
@@ -21,6 +30,7 @@
       class E extends B implements A {}
       class F extends Object with A implements B {}
       class G extends Object with A, B {}
+      class X {}
       """,
       mainSource: r"""
       main() {
@@ -33,120 +43,283 @@
         new G();
       }
       """,
-      useMockCompiler: false).then((env) {
-    ClassWorld classWorld = env.compiler.world;
+      useMockCompiler: false);
+  ClassWorld classWorld = env.compiler.world;
 
-    ClassElement Object_ = env.getElement("Object");
-    ClassElement A = env.getElement("A");
-    ClassElement B = env.getElement("B");
-    ClassElement C = env.getElement("C");
-    ClassElement D = env.getElement("D");
-    ClassElement E = env.getElement("E");
-    ClassElement F = env.getElement("F");
-    ClassElement G = env.getElement("G");
+  ClassElement Object_ = env.getElement("Object");
+  ClassElement A = env.getElement("A");
+  ClassElement B = env.getElement("B");
+  ClassElement C = env.getElement("C");
+  ClassElement D = env.getElement("D");
+  ClassElement E = env.getElement("E");
+  ClassElement F = env.getElement("F");
+  ClassElement G = env.getElement("G");
+  ClassElement X = env.getElement("X");
 
-    void check(
-        String property,
-        ClassElement cls,
-        Iterable<ClassElement> foundClasses,
-        List<ClassElement> expectedClasses,
-        {bool exact: true}) {
-      for (ClassElement expectedClass in expectedClasses) {
-        Expect.isTrue(foundClasses.contains(expectedClass),
-            "Expect $expectedClass in '$property' on $cls. "
-            "Found:\n ${foundClasses.join('\n ')}");
+  void checkClasses(
+      String property,
+      ClassElement cls,
+      Iterable<ClassElement> foundClasses,
+      List<ClassElement> expectedClasses,
+      {bool exact: true}) {
+
+    for (ClassElement expectedClass in expectedClasses) {
+      Expect.isTrue(foundClasses.contains(expectedClass),
+          "Expect $expectedClass in '$property' on $cls. "
+          "Found:\n ${foundClasses.join('\n ')}\n"
+          "${env.compiler.world.dump(cls)}");
+    }
+    if (exact) {
+      Expect.equals(expectedClasses.length, foundClasses.length,
+          "Unexpected classes "
+          "${foundClasses.where((c) => !expectedClasses.contains(c))} "
+          "in '$property' on $cls.\n"
+          "${env.compiler.world.dump(cls)}");
+    }
+  }
+
+  void check(
+      String property,
+      ClassElement cls,
+      Iterable<ClassElement> foundClasses,
+      List<ClassElement> expectedClasses,
+      {bool exact: true,
+       void forEach(ClassElement cls, ForEachFunction f),
+       int getCount(ClassElement cls)}) {
+    checkClasses(property, cls, foundClasses, expectedClasses, exact: exact);
+
+    if (forEach != null) {
+      List<ClassElement> visited = <ClassElement>[];
+      forEach(cls, (ClassElement c) {
+        visited.add(c);
+      });
+      checkClasses(
+          'forEach($property)', cls, visited, expectedClasses, exact: exact);
+    }
+
+    if (getCount != null && exact) {
+      int count = getCount(cls);
+      Expect.equals(expectedClasses.length, count,
+          "Unexpected class count in '$property' on $cls.\n"
+          "${env.compiler.world.dump(cls)}");
+    }
+
+  }
+
+  void testSubclasses(
+      ClassElement cls,
+      List<ClassElement> expectedClasses,
+      {bool exact: true}) {
+    check(
+      'subclassesOf',
+      cls,
+      classWorld.subclassesOf(cls),
+      expectedClasses,
+      exact: exact);
+  }
+
+  void testStrictSubclasses(
+      ClassElement cls,
+      List<ClassElement> expectedClasses,
+      {bool exact: true}) {
+    check(
+      'strictSubclassesOf',
+      cls,
+      classWorld.strictSubclassesOf(cls),
+      expectedClasses,
+      exact: exact,
+      forEach: classWorld.forEachStrictSubclassOf,
+      getCount: classWorld.strictSubclassCount);
+  }
+
+  void testStrictSubtypes(
+      ClassElement cls,
+      List<ClassElement> expectedClasses,
+      {bool exact: true}) {
+    check(
+      'strictSubtypesOf',
+      cls,
+      classWorld.strictSubtypesOf(cls),
+      expectedClasses,
+      exact: exact,
+      forEach: classWorld.forEachStrictSubtypeOf,
+      getCount: classWorld.strictSubtypeCount);
+  }
+
+  void testMixinUses(
+      ClassElement cls,
+      List<ClassElement> expectedClasses,
+      {bool exact: true}) {
+    check(
+      'mixinUsesOf',
+      cls,
+      classWorld.mixinUsesOf(cls),
+      expectedClasses,
+      exact: exact);
+  }
+
+  testSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
+  testSubclasses(A, [A, C]);
+  testSubclasses(B, [B, E]);
+  testSubclasses(C, [C]);
+  testSubclasses(D, [D]);
+  testSubclasses(E, [E]);
+  testSubclasses(F, [F]);
+  testSubclasses(G, [G]);
+  testSubclasses(X, []);
+
+  testStrictSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
+  testStrictSubclasses(A, [C]);
+  testStrictSubclasses(B, [E]);
+  testStrictSubclasses(C, []);
+  testStrictSubclasses(D, []);
+  testStrictSubclasses(E, []);
+  testStrictSubclasses(F, []);
+  testStrictSubclasses(G, []);
+  testStrictSubclasses(X, []);
+
+  testStrictSubtypes(Object_, [A, B, C, D, E, F, G], exact: false);
+  testStrictSubtypes(A, [C, D, E, F, G]);
+  testStrictSubtypes(B, [E, F, G]);
+  testStrictSubtypes(C, []);
+  testStrictSubtypes(D, []);
+  testStrictSubtypes(E, []);
+  testStrictSubtypes(F, []);
+  testStrictSubtypes(G, []);
+  testStrictSubtypes(X, [A, C, D, E, F, G]);
+
+  testMixinUses(Object_, []);
+  testMixinUses(A, [F.superclass, G.superclass.superclass]);
+  testMixinUses(B, [G.superclass]);
+  testMixinUses(C, []);
+  testMixinUses(D, []);
+  testMixinUses(E, []);
+  testMixinUses(F, []);
+  testMixinUses(G, []);
+  testMixinUses(X, []);
+}
+
+testProperties() async {
+  var env = await TypeEnvironment.create(r"""
+      class A {}
+      class A1 extends A {}
+      class A2 implements A {}
+      class A3 extends Object with A {}
+
+      class B {}
+      class B1 extends B {}
+      class B2 implements B {}
+      class B3 extends Object with B {}
+
+      class C {}
+      class C1 extends C {}
+      class C2 implements C {}
+      class C3 extends Object with C {}
+
+      class D {}
+      class D1 extends D {}
+      class D2 implements D {}
+      class D3 extends Object with D {}
+
+      class E {}
+      class E1 extends E {}
+      class E2 implements E {}
+      class E3 extends Object with E {}
+
+      class F {}
+      class F1 extends F {}
+      class F2 implements F {}
+      class F3 extends Object with F {}
+
+      class G {}
+      class G1 extends G {}
+      class G2 extends G1 {}
+      class G3 extends G2 implements G {}
+      class G4 extends G2 with G {}
+
+      class H {}
+      class H1 extends H {}
+      class H2 extends H1 {}
+      class H3 extends H2 implements H {}
+      class H4 extends H2 with H {}
+      """,
+      mainSource: r"""
+      main() {
+        new B();
+        new C1();
+        new D2();
+        new E3();
+        new F1();
+        new F2();
+        new G2();
+        new G3();
+        new H4();
       }
-      if (exact) {
-        Expect.equals(expectedClasses.length, foundClasses.length,
-            "Unexpected classes "
-            "${foundClasses.where((c) => !expectedClasses.contains(c))} "
-            "in '$property' on $cls.");
-      }
-    }
+      """,
+      useMockCompiler: false);
+  ClassWorld classWorld = env.compiler.world;
 
-    void testSubclasses(
-        ClassElement cls,
-        List<ClassElement> expectedClasses,
-        {bool exact: true}) {
-      check(
-        'subclassesOf',
-        cls,
-        classWorld.subclassesOf(cls),
-        expectedClasses,
-        exact: exact);
-    }
+  check(String name,
+      {bool hasStrictSubtype,
+       bool hasOnlySubclasses}) {
+    ClassElement cls = env.getElement(name);
+    Expect.equals(hasStrictSubtype, classWorld.hasAnyStrictSubtype(cls),
+        "Unexpected hasAnyStrictSubtype property on $cls.");
+    Expect.equals(hasOnlySubclasses, classWorld.hasOnlySubclasses(cls),
+        "Unexpected hasOnlySubclasses property on $cls.");
+  }
 
-    void testStrictSubclasses(
-        ClassElement cls,
-        List<ClassElement> expectedClasses,
-        {bool exact: true}) {
-      check(
-        'strictSubclassesOf',
-        cls,
-        classWorld.strictSubclassesOf(cls),
-        expectedClasses,
-        exact: exact);
-    }
+  check("Object", hasStrictSubtype: true, hasOnlySubclasses: true);
 
-    void testStrictSubtypes(
-        ClassElement cls,
-        List<ClassElement> expectedClasses,
-        {bool exact: true}) {
-      check(
-        'strictSubtypesOf',
-        cls,
-        classWorld.strictSubtypesOf(cls),
-        expectedClasses,
-        exact: exact);
-    }
+  // No instantiated Ax classes.
+  check("A", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("A1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("A2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("A3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-    void testMixinUses(
-        ClassElement cls,
-        List<ClassElement> expectedClasses,
-        {bool exact: true}) {
-      check(
-        'mixinUsesOf',
-        cls,
-        classWorld.mixinUsesOf(cls),
-        expectedClasses,
-        exact: exact);
-    }
+  // class B instantiated
+  check("B", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("B1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("B2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("B3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-    testSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
-    testSubclasses(A, [A, C]);
-    testSubclasses(B, [B, E]);
-    testSubclasses(C, [C]);
-    testSubclasses(D, [D]);
-    testSubclasses(E, [E]);
-    testSubclasses(F, [F]);
-    testSubclasses(G, [G]);
+  // class C1 extends C instantiated
+  check("C", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("C1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("C2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("C3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-    testStrictSubclasses(Object_, [A, B, C, D, E, F, G], exact: false);
-    testStrictSubclasses(A, [C]);
-    testStrictSubclasses(B, [E]);
-    testStrictSubclasses(C, []);
-    testStrictSubclasses(D, []);
-    testStrictSubclasses(E, []);
-    testStrictSubclasses(F, []);
-    testStrictSubclasses(G, []);
+  // class D2 implements D instantiated
+  check("D", hasStrictSubtype: true, hasOnlySubclasses: false);
+  check("D1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("D2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("D3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-    testStrictSubtypes(Object_, [A, B, C, D, E, F, G], exact: false);
-    testStrictSubtypes(A, [C, D, E, F, G]);
-    testStrictSubtypes(B, [E, F, G]);
-    testStrictSubtypes(C, []);
-    testStrictSubtypes(D, []);
-    testStrictSubtypes(E, []);
-    testStrictSubtypes(F, []);
-    testStrictSubtypes(G, []);
+  // class E2 extends Object with E instantiated
+  check("E", hasStrictSubtype: true, hasOnlySubclasses: false);
+  check("E1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("E2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("E3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-    testMixinUses(Object_, []);
-    testMixinUses(A, [F.superclass, G.superclass.superclass]);
-    testMixinUses(B, [G.superclass]);
-    testMixinUses(C, []);
-    testMixinUses(D, []);
-    testMixinUses(E, []);
-    testMixinUses(F, []);
-    testMixinUses(G, []);
+  // class F1 extends F instantiated
+  // class F2 implements F instantiated
+  check("F", hasStrictSubtype: true, hasOnlySubclasses: false);
+  check("F1", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("F2", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("F3", hasStrictSubtype: false, hasOnlySubclasses: true);
 
-  }));
+  // class G2 extends G1 extends G instantiated
+  // class G3 extends G2 extends G1 extends G instantiated
+  check("G", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("G1", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("G2", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("G3", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("G4", hasStrictSubtype: false, hasOnlySubclasses: true);
+
+  // class H4 extends H2 with H extends H1 extends H instantiated
+  check("H", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("H1", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("H2", hasStrictSubtype: true, hasOnlySubclasses: true);
+  check("H3", hasStrictSubtype: false, hasOnlySubclasses: true);
+  check("H4", hasStrictSubtype: false, hasOnlySubclasses: true);
 }
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 3d00167..2cb3918 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-16407_test: Fail # Issue 16407
 class_test: Fail
 statements_test: Fail
 typed_locals_test: Fail
@@ -68,6 +67,4 @@
 big_allocation_expression_test: Crash # Issue 24635
 
 [ $compiler == dart2js && $cps_ir ]
-16407_test: Pass # Please triage this failure.
 async_stacktrace_test/asyncStar: Crash # (foo()async*{try {tr...  cannot handle sync*/async* functions
-switch_test/none: Crash # (switch (val){foo:ba...  continue to a labeled switch case
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 88b3ccd..407ea29 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -189,16 +189,6 @@
 [ $compiler == dart2js && $cps_ir ]
 data_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
 error_stack_trace1_test: Pass # H.unwrapException(...).get$stackTrace is not a function
-growable_list_test: RuntimeError # Typed lists
-iterable_empty_test: RuntimeError # Please triage this failure.
-iterable_return_type_test/none: RuntimeError # Please triage this failure.
-iterable_to_list_test: RuntimeError # Please triage this failure.
-iterable_to_set_test: RuntimeError # Please triage this failure.
-list_filled_type_argument_test: RuntimeError # Please triage this failure.
-list_unmodifiable_test: RuntimeError # Please triage this failure.
-map_values2_test: RuntimeError # Please triage this failure.
-map_values3_test: RuntimeError # Please triage this failure.
-map_values4_test: RuntimeError # Please triage this failure.
 package_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
 regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
 symbol_operator_test/03: RuntimeError # Issue 24878
diff --git a/tests/corelib/expando_test.dart b/tests/corelib/expando_test.dart
index d55aecf..a7fb1c4 100644
--- a/tests/corelib/expando_test.dart
+++ b/tests/corelib/expando_test.dart
@@ -18,7 +18,7 @@
       testUnnamedExpando(object);
     }
     for (var object in legal) {
-      Expect.equals(2, visits[object]);
+      Expect.equals(2, visits[object], "$object");
     }
     testIllegal();
     testIdentity();
@@ -65,19 +65,19 @@
   static testIllegal() {
     Expando<int> expando = new Expando<int>();
     Expect.throws(() => expando[null], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "null");
     Expect.throws(() => expando['string'], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "'string'");
     Expect.throws(() => expando['string'], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "'string'");
     Expect.throws(() => expando[42], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "42");
     Expect.throws(() => expando[42.87], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "42.87");
     Expect.throws(() => expando[true], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "true");
     Expect.throws(() => expando[false], (exception)
-                  => exception is ArgumentError);
+                  => exception is ArgumentError, "false");
   }
 
   static testIdentity() {
diff --git a/tests/corelib/uri_parameters_all_test.dart b/tests/corelib/uri_parameters_all_test.dart
new file mode 100644
index 0000000..ea40ad8
--- /dev/null
+++ b/tests/corelib/uri_parameters_all_test.dart
@@ -0,0 +1,39 @@
+// 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 "package:expect/expect.dart";
+import 'dart:convert';
+
+main() {
+  testAll(["a", "b", "c"]);
+  testAll([""]);
+  testAll(["a"]);
+  testAll(["",""]);
+  testAll(["baz"]);
+
+  testParse("z&y&w&z", {"z": ["", ""], "y": [""], "w": [""]});
+  testParse("x=42&y=42&x=37&y=37", {"x": ["42", "37"], "y": ["42", "37"]});
+  testParse("x&x&x&x&x", {"x": ["", "", "", "", ""]});
+  testParse("x=&&y", {"x": [""], "y": [""]});
+}
+
+testAll(List values) {
+  var uri = new Uri(scheme: "foo", path: "bar",
+                    queryParameters: {"baz": values});
+  var list = uri.queryParametersAll["baz"];
+  Expect.listEquals(values, list);
+}
+
+testParse(query, results) {
+  var uri = new Uri(scheme: "foo", path: "bar", query: query);
+  var params = uri.queryParametersAll;
+  for (var k in results.keys) {
+    Expect.listEquals(results[k], params[k]);
+  }
+  uri = new Uri(scheme: "foo", path: "bar", queryParameters: results);
+  params = uri.queryParametersAll;
+  for (var k in results.keys) {
+    Expect.listEquals(results[k], params[k]);
+  }
+}
diff --git a/tests/html/html.status b/tests/html/html.status
index cf5e043..402fe6e 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -429,3 +429,33 @@
 
 [ $compiler == dart2js && $cps_ir ]
 resource_http_test: Crash # (await for(var b in r.openRead()){bytes.addAll(b);}): await for
+
+[ $compiler == dart2js && $cps_ir && $browser ]
+custom/element_upgrade_test: RuntimeError # Please triage
+js_dart_to_string_test: RuntimeError # Please triage
+custom_elements_23127_test/c2t: RuntimeError # Please triage
+custom_elements_23127_test/c2: RuntimeError # Please triage
+custom_elements_23127_test/baseline: RuntimeError # Please triage
+keyboard_event_test: RuntimeError # Please triage
+js_typed_interop_test: RuntimeError # Please triage
+js_typed_interop_side_cast_test: RuntimeError # Please triage
+js_typed_interop_anonymous_exp_test: RuntimeError # Please triage
+custom_elements_test/register: RuntimeError # Please triage
+js_typed_interop_anonymous2_test: RuntimeError # Please triage
+js_typed_interop_anonymous_test: RuntimeError # Please triage
+js_array_test: RuntimeError # Please triage
+js_function_getter_test/call: RuntimeError # Please triage
+custom/mirrors_test: RuntimeError # Please triage
+custom/constructor_calls_created_synchronously_test: RuntimeError # Please triage
+input_element_test/attributes: Pass # Please triage
+js_function_getter_trust_types_test: RuntimeError # Please triage
+js_typed_interop_side_cast_exp_test: RuntimeError # Please triage
+js_typed_interop_anonymous2_exp_test: RuntimeError # Please triage
+mirrors_js_typed_interop_test: RuntimeError # Please triage
+js_function_getter_test: RuntimeError # Please triage
+custom_elements_23127_test/c1t: RuntimeError # Please triage
+custom_elements_test/innerHtml: RuntimeError # Please triage
+mouse_event_test: RuntimeError # Please triage
+js_test/JsObject_methods: RuntimeError # Please triage
+js_test/Dart_functions: RuntimeError # Please triage
+js_test/new_JsObject: RuntimeError # Please triage
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index 37c73ab..a902d59 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -322,7 +322,7 @@
 
   });
 
-  group('new JsObject()', () {
+  group('new_JsObject', () {
 
     test('new Foo()', () {
       var foo = new JsObject(context['Foo'], [42]);
@@ -649,7 +649,7 @@
 
   });
 
-  group('Dart functions', () {
+  group('Dart_functions', () {
     test('invoke Dart callback from JS', () {
       expect(() => context.callMethod('invokeCallback'), throws);
 
@@ -752,7 +752,7 @@
     });
   });
 
-  group('JsObject methods', () {
+  group('JsObject_methods', () {
 
     test('hashCode and ==', () {
       final o1 = context['Object'];
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index e11f91a..7e51060 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -56,9 +56,6 @@
 browser/issue_12474_test: CompileTimeError # Issue 22529
 enum_const_test/02: RuntimeError # Issue 21817
 
-[ $compiler == dart2js && $cps_ir ]
-isolate_current_test: RuntimeError # Please triage this failure.
-
 [ $compiler == dart2js && $runtime != d8 ]
 error_exit_at_spawn_test: Skip # Issue 23876
 error_at_spawn_test: Skip # Issue 23876
diff --git a/tests/language/built_in_identifier_prefix_test.dart b/tests/language/built_in_identifier_prefix_test.dart
deleted file mode 100644
index de995c9..0000000
--- a/tests/language/built_in_identifier_prefix_test.dart
+++ /dev/null
@@ -1,216 +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.
-
-// Test that built-in identifiers can be used as library prefixes.
-
-// From The Dart Programming Language Specification, section 11.30
-// "Identifier Reference":
-//
-// "A built-in identifier is one of the identifiers produced by the
-// production BUILT IN IDENTIFIER. It is a compile-time error if a
-// built-in identifier is used as the declared name of a class, type
-// parameter or type alias. It is a compile-time error to use a
-// built-in identifier other than dynamic as a type annotation."
-//
-// Observation: it is not illegal to use a built-in identifier as a library
-// prefix.
-//
-// Observation: it is not legal to use a built-in identifer as a type
-// annotation. A type annotation is not fully defined in the
-// specification, so we assume this means that the grammar production
-// "type" cannot match a built-in identifier. Unfortunately, this
-// doesn't prevent us from using built-in identifiers *in* type
-// annotations. For example, "final abstract foo;" is illegal as
-// "abstract" is used as a type annotation. However, "final
-// abstract<dynamic> foo;" is not illegal because "abstract" is used
-// as a typeName.
-
-import "package:expect/expect.dart";
-import 'built_in_identifier_prefix_library_abstract.dart' as abstract;
-import 'built_in_identifier_prefix_library_as.dart' as as;
-import 'built_in_identifier_prefix_library_dynamic.dart' as dynamic;
-import 'built_in_identifier_prefix_library_export.dart' as export;
-import 'built_in_identifier_prefix_library_external.dart' as external;
-import 'built_in_identifier_prefix_library_factory.dart' as factory;
-import 'built_in_identifier_prefix_library_get.dart' as get;
-import 'built_in_identifier_prefix_library_implements.dart' as implements;
-import 'built_in_identifier_prefix_library_import.dart' as import;
-import 'built_in_identifier_prefix_library_library.dart' as library;
-import 'built_in_identifier_prefix_library_operator.dart' as operator;
-import 'built_in_identifier_prefix_library_part.dart' as part;
-import 'built_in_identifier_prefix_library_set.dart' as set;
-import 'built_in_identifier_prefix_library_static.dart' as static;
-import 'built_in_identifier_prefix_library_typedef.dart' as typedef;
-
-abstract.A _abstract = new abstract.A();
-as.A _as = new as.A();
-dynamic.A _dynamic = new dynamic.A();
-export.A _export = new export.A();
-external.A _external = new external.A();
-factory.A _factory = new factory.A();
-get.A _get = new get.A();
-implements.A _implements = new implements.A();
-import.A _import = new import.A();
-library.A _library = new library.A();
-operator.A _operator = new operator.A();
-part.A _part = new part.A();
-set.A _set = new set.A();
-static.A _static = new static.A();
-typedef.A _typedef = new typedef.A();
-
-abstract<dynamic> generic_abstract = new abstract.A();
-as<dynamic> generic_as = new as.A();
-dynamic<dynamic> generic_dynamic = new dynamic.A();
-export<dynamic> generic_export = new export.A();
-external<dynamic> generic_external = new external.A();
-factory<dynamic> generic_factory = new factory.A();
-get<dynamic> generic_get = new get.A();
-implements<dynamic> generic_implements = new implements.A();
-import<dynamic> generic_import = new import.A();
-library<dynamic> generic_library = new library.A();
-operator<dynamic> generic_operator = new operator.A();
-part<dynamic> generic_part = new part.A();
-set<dynamic> generic_set = new set.A();
-static<dynamic> generic_static = new static.A();
-typedef<dynamic> generic_typedef = new typedef.A();
-
-abstract.B<dynamic> dynamic_B_abstract = new abstract.B();
-as.B<dynamic> dynamic_B_as = new as.B();
-dynamic.B<dynamic> dynamic_B_dynamic = new dynamic.B();
-export.B<dynamic> dynamic_B_export = new export.B();
-external.B<dynamic> dynamic_B_external = new external.B();
-factory.B<dynamic> dynamic_B_factory = new factory.B();
-get.B<dynamic> dynamic_B_get = new get.B();
-implements.B<dynamic> dynamic_B_implements = new implements.B();
-import.B<dynamic> dynamic_B_import = new import.B();
-library.B<dynamic> dynamic_B_library = new library.B();
-operator.B<dynamic> dynamic_B_operator = new operator.B();
-part.B<dynamic> dynamic_B_part = new part.B();
-set.B<dynamic> dynamic_B_set = new set.B();
-static.B<dynamic> dynamic_B_static = new static.B();
-typedef.B<dynamic> dynamic_B_typedef = new typedef.B();
-
-abstract.B<abstract<dynamic>> parameterized_B_abstract = new abstract.B();
-as.B<as<dynamic>> parameterized_B_as = new as.B();
-dynamic.B<dynamic<dynamic>> parameterized_B_dynamic = new dynamic.B();
-export.B<export<dynamic>> parameterized_B_export = new export.B();
-external.B<external<dynamic>> parameterized_B_external = new external.B();
-factory.B<factory<dynamic>> parameterized_B_factory = new factory.B();
-get.B<get<dynamic>> parameterized_B_get = new get.B();
-implements.B<implements<dynamic>> parameterized_B_implements =
-  new implements.B();
-import.B<import<dynamic>> parameterized_B_import = new import.B();
-library.B<library<dynamic>> parameterized_B_library = new library.B();
-operator.B<operator<dynamic>> parameterized_B_operator = new operator.B();
-part.B<part<dynamic>> parameterized_B_part = new part.B();
-set.B<set<dynamic>> parameterized_B_set = new set.B();
-static.B<static<dynamic>> parameterized_B_static = new static.B();
-typedef.B<typedef<dynamic>> parameterized_B_typedef = new typedef.B();
-
-class UseA {
-  abstract.A abstract = new abstract.A();
-  as.A as = new as.A();
-  dynamic.A dynamic = new dynamic.A();
-  export.A export = new export.A();
-  external.A external = new external.A();
-  factory.A factory = new factory.A();
-  get.A get = new get.A();
-  implements.A implements = new implements.A();
-  import.A import = new import.A();
-  library.A library = new library.A();
-  operator.A operator = new operator.A();
-  part.A part = new part.A();
-  set.A set = new set.A();
-  static.A static = new static.A();
-  typedef.A typedef = new typedef.A();
-}
-
-main() {
-  bool assertionsEnabled = false;
-  assert(assertionsEnabled = true);
-
-  Expect.isTrue(_abstract is abstract.A);
-  Expect.isTrue(_as is as.A);
-  Expect.isTrue(_dynamic is dynamic.A);
-  Expect.isTrue(_export is export.A);
-  Expect.isTrue(_external is external.A);
-  Expect.isTrue(_factory is factory.A);
-  Expect.isTrue(_get is get.A);
-  Expect.isTrue(_implements is implements.A);
-  Expect.isTrue(_import is import.A);
-  Expect.isTrue(_library is library.A);
-  Expect.isTrue(_operator is operator.A);
-  Expect.isTrue(_part is part.A);
-  Expect.isTrue(_set is set.A);
-  Expect.isTrue(_static is static.A);
-  Expect.isTrue(_typedef is typedef.A);
-
-  Expect.isTrue(dynamic_B_abstract is abstract.B);
-  Expect.isTrue(dynamic_B_as is as.B);
-  Expect.isTrue(dynamic_B_dynamic is dynamic.B);
-  Expect.isTrue(dynamic_B_export is export.B);
-  Expect.isTrue(dynamic_B_external is external.B);
-  Expect.isTrue(dynamic_B_factory is factory.B);
-  Expect.isTrue(dynamic_B_get is get.B);
-  Expect.isTrue(dynamic_B_implements is implements.B);
-  Expect.isTrue(dynamic_B_import is import.B);
-  Expect.isTrue(dynamic_B_library is library.B);
-  Expect.isTrue(dynamic_B_operator is operator.B);
-  Expect.isTrue(dynamic_B_part is part.B);
-  Expect.isTrue(dynamic_B_set is set.B);
-  Expect.isTrue(dynamic_B_static is static.B);
-  Expect.isTrue(dynamic_B_typedef is typedef.B);
-
-  var x = new UseA();
-  Expect.isTrue(x.abstract is abstract.A);
-  Expect.isTrue(x.as is as.A);
-  Expect.isTrue(x.dynamic is dynamic.A);
-  Expect.isTrue(x.export is export.A);
-  Expect.isTrue(x.external is external.A);
-  Expect.isTrue(x.factory is factory.A);
-  Expect.isTrue(x.get is get.A);
-  Expect.isTrue(x.implements is implements.A);
-  Expect.isTrue(x.import is import.A);
-  Expect.isTrue(x.library is library.A);
-  Expect.isTrue(x.operator is operator.A);
-  Expect.isTrue(x.part is part.A);
-  Expect.isTrue(x.set is set.A);
-  Expect.isTrue(x.static is static.A);
-  Expect.isTrue(x.typedef is typedef.A);
-
-  // Most of the following variables have malformed type annotations.
-  if (assertionsEnabled) return;
-
-  Expect.isTrue(generic_abstract is abstract.A);
-  Expect.isTrue(generic_as is as.A);
-  Expect.isTrue(generic_dynamic is dynamic.A);
-  Expect.isTrue(generic_export is export.A);
-  Expect.isTrue(generic_external is external.A);
-  Expect.isTrue(generic_factory is factory.A);
-  Expect.isTrue(generic_get is get.A);
-  Expect.isTrue(generic_implements is implements.A);
-  Expect.isTrue(generic_import is import.A);
-  Expect.isTrue(generic_library is library.A);
-  Expect.isTrue(generic_operator is operator.A);
-  Expect.isTrue(generic_part is part.A);
-  Expect.isTrue(generic_set is set.A);
-  Expect.isTrue(generic_static is static.A);
-  Expect.isTrue(generic_typedef is typedef.A);
-
-  Expect.isTrue(parameterized_B_abstract is abstract.B);
-  Expect.isTrue(parameterized_B_as is as.B);
-  Expect.isTrue(parameterized_B_dynamic is dynamic.B);
-  Expect.isTrue(parameterized_B_export is export.B);
-  Expect.isTrue(parameterized_B_external is external.B);
-  Expect.isTrue(parameterized_B_factory is factory.B);
-  Expect.isTrue(parameterized_B_get is get.B);
-  Expect.isTrue(parameterized_B_implements is implements.B);
-  Expect.isTrue(parameterized_B_import is import.B);
-  Expect.isTrue(parameterized_B_library is library.B);
-  Expect.isTrue(parameterized_B_operator is operator.B);
-  Expect.isTrue(parameterized_B_part is part.B);
-  Expect.isTrue(parameterized_B_set is set.B);
-  Expect.isTrue(parameterized_B_static is static.B);
-  Expect.isTrue(parameterized_B_typedef is typedef.B);
-}
diff --git a/tests/language/conflicting_type_variable_and_setter_test.dart b/tests/language/conflicting_type_variable_and_setter_test.dart
new file mode 100644
index 0000000..2aca0c3
--- /dev/null
+++ b/tests/language/conflicting_type_variable_and_setter_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class C<D> {
+  void set D(int value) {
+    field = value;
+  }
+
+  int field;
+}
+
+main() {
+  C<int> c = new C<int>();
+  c.D = 1;
+  Expect.equals(c.field, 1);
+}
diff --git a/tests/language/deep_nesting1_negative_test.dart b/tests/language/deep_nesting1_negative_test.dart
new file mode 100644
index 0000000..e85c11c
--- /dev/null
+++ b/tests/language/deep_nesting1_negative_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Deeply nested expression must not crash compiler due to stack overflow.
+
+main() {
+  var x =
+[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]];
+  print('okay');
+}
diff --git a/tests/language/deep_nesting2_negative_test.dart b/tests/language/deep_nesting2_negative_test.dart
new file mode 100644
index 0000000..cd49a07
--- /dev/null
+++ b/tests/language/deep_nesting2_negative_test.dart
@@ -0,0 +1,10012 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Deeply nested statements must not crash compiler due to stack overflow.
+
+var x = 0;
+
+main() {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  if (x == 0) {
+  }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+  print("survived!");
+}
diff --git a/tests/language/deferred_import_core_test.dart b/tests/language/deferred_import_core_test.dart
new file mode 100644
index 0000000..f3d6644
--- /dev/null
+++ b/tests/language/deferred_import_core_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Nothing in the language spec explicitly prohibits a deferred import of
+// 'dart:core'.  Make sure it doesn't lead to any strange behavior.
+
+import "dart:core" deferred as core;
+
+main() {
+  core.loadLibrary().then((_) => null);
+}
diff --git a/tests/language/export_not_shadowed_by_prefix_helper.dart b/tests/language/export_not_shadowed_by_prefix_helper.dart
new file mode 100644
index 0000000..3dcd016
--- /dev/null
+++ b/tests/language/export_not_shadowed_by_prefix_helper.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+export "export_not_shadowed_by_prefix_helper2.dart";
+import "dart:core" as f;
diff --git a/tests/language/export_not_shadowed_by_prefix_helper2.dart b/tests/language/export_not_shadowed_by_prefix_helper2.dart
new file mode 100644
index 0000000..ae2dca5
--- /dev/null
+++ b/tests/language/export_not_shadowed_by_prefix_helper2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+void f() {
+  f_called = true;
+}
+
+bool f_called = false;
diff --git a/tests/language/export_not_shadowed_by_prefix_test.dart b/tests/language/export_not_shadowed_by_prefix_test.dart
new file mode 100644
index 0000000..3af1b48
--- /dev/null
+++ b/tests/language/export_not_shadowed_by_prefix_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verify that import prefixes within an imported library don't shadow
+// names re-exported by that library.
+
+import "package:expect/expect.dart";
+import "export_not_shadowed_by_prefix_helper.dart";
+
+main() {
+  f();
+  Expect.isTrue(f_called);
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 65a750e..319fdb8 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -6,9 +6,13 @@
 # current state of the language.
 
 [ ($compiler == none || $compiler == precompiler) ]
-built_in_identifier_prefix_test: Fail # Issue 6970
 tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
-const_qq_test: Fail
+
+# These tests are skipped in the VM because it has "--supermixin"
+# functionality enabled unconditionally.  The tests should be removed
+# once the same is true for analyzer (#24478) and dart2js (#23773)
+mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
+mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
 
 # These bugs refer currently ongoing language discussions.
 constructor5_test: Fail # Issue 6422
@@ -38,7 +42,10 @@
 async_star_cancel_while_paused_test: RuntimeError
 async_star_await_pauses_test: Skip # Times out. Issue 23996
 
+library_env_test: RuntimeError
+
 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
+
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
 vm/debug_break_enabled_vm_test/01: Crash, OK # Expected to hit breakpoint.
@@ -101,7 +108,7 @@
 [ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
 gc_test: SkipSlow # Times out flakily. Issue 20956
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ( $arch == simarm || $arch == arm || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
+[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ( $arch == simarm || $arch == arm || $arch == simarmv6 || $arch == armv6 || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
 vm/load_to_load_unaligned_forwarding_vm_test: Pass, Crash # Unaligned offset. Issue 22151
 
 [ ($compiler == none || $compiler == precompiler) && $runtime == dartium ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 5ea3d0a..f549de2 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -7,9 +7,15 @@
 # Runtime negative test. No static errors or warnings.
 closure_call_wrong_argument_count_negative_test: skip
 
+deep_nesting1_negative_test: Crash # Issue 25558
+deep_nesting2_negative_test: Crash # Issue 25558
+
 enum_syntax_test/05: Fail # 21649
 enum_syntax_test/06: Fail # 21649
 
+mixin_illegal_constructor_test/20: MissingCompileTimeError # 25588
+mixin_illegal_constructor_test/21: MissingCompileTimeError # 25588
+
 tearoff_basic_test: Skip # Tear-off not supported
 tearoff_constructor_basic_test: Skip # Tear-off not supported
 
@@ -19,7 +25,6 @@
 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)
-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
@@ -305,11 +310,6 @@
 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 24478
-mixin_super_test: CompileTimeError # Issue 24478
-mixin_super_2_test: CompileTimeError # Issue 24478
-mixin_super_use_test: CompileTimeError # Issue 24478
-mixin_superclass_test: CompileTimeError # Issue 24478
 named_constructor_test/01: StaticWarning
 named_constructor_test/03: StaticWarning
 named_parameters2_test: StaticWarning
@@ -483,4 +483,4 @@
 # intentionally referring to a variable that's not in scope.
 transitive_private_library_access_test: StaticWarning
 
-const_qq_test: Fail
+conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 2dbad85..a1bb9e3 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -4,6 +4,7 @@
 
 [ $compiler == dart2js ]
 getter_setter_in_lib_test: Fail # Issue 23288
+method_name_test: Fail # issue 25574
 
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
 async_star_await_pauses_test: Fail, Timeout # Issue 22853
@@ -13,8 +14,21 @@
 try_catch_on_syntax_test/10: Fail # Issue 19823
 try_catch_on_syntax_test/11: Fail # Issue 19823
 
+mixin_illegal_constructor_test/20: MissingCompileTimeError # 25587
+mixin_illegal_constructor_test/21: MissingCompileTimeError # 25587
+
+deep_nesting1_negative_test: Crash # Issue 25557
+deep_nesting2_negative_test: Crash # Issue 25557
+
 call_function_apply_test: RuntimeError # Issue 23873
 
+# The following tests are supposed to fail.
+# When run for testing dart2js supports all dart:X libraries (because it
+# uses '--categories=all').
+library_env_test/has_no_html_support: RuntimeError, OK
+library_env_test/has_no_io_support: RuntimeError, OK
+library_env_test/has_no_mirror_support: RuntimeError, OK
+
 [ $compiler == dart2js && $runtime == jsshell ]
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
 async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
@@ -138,7 +152,6 @@
 branch_canonicalization_test: RuntimeError # Issue 638.
 identical_closure2_test: RuntimeError # Issue 1533, Issue 12596
 integer_division_by_zero_test: RuntimeError # Issue 8301
-built_in_identifier_prefix_test: CompileTimeError # Issue 6972
 number_identity2_test: RuntimeError # Issue 12596
 double_int_to_string_test: RuntimeError # Issue 1533
 mint_arithmetic_test: RuntimeError # Issue 1533
@@ -241,9 +254,9 @@
 async_await_syntax_test/d06a: Crash # (await for(var o in st){}): await for
 async_await_syntax_test/d09a: Crash # (()async*{yield 0;}): cannot handle sync*/async* functions
 async_await_syntax_test/d10a: Crash # (()async*{yield* [] ;}): cannot handle sync*/async* functions
-async_await_test/02: Crash # (switch (v){label:ca...  continue to a labeled switch case
-async_await_test/03: Crash # (switch (v){label:ca...  continue to a labeled switch case
-async_await_test/none: Crash # (switch (v){label:ca...  continue to a labeled switch case
+async_await_test/02: Crash # bailout: (await for
+async_await_test/03: Crash # bailout: (await for
+async_await_test/none: Crash # bailout: (await for
 async_or_generator_return_type_stacktrace_test/02: Crash # (void badReturnTypeAsyncStar()async*{}): cannot handle sync*/async* functions
 async_return_types_test/nestedFuture: Crash #  cannot handle sync*/async* functions
 async_return_types_test/none: Crash # cannot handle sync*/async* functions
@@ -267,26 +280,12 @@
 await_for_test: Crash # (await for(var x in infiniteStream()){i++ ;if(i>10)break;t4.record(x);}): await for
 await_for_use_local_test: Crash # (await for(var v in s){accum+= v;}): await for
 call_closurization_test: RuntimeError # Bad type inference for ".call" tear-off.
-closure_in_constructor_test: RuntimeError # Please triage this failure.
-closures_initializer_test: RuntimeError # Please triage this failure.
-constructor12_test: RuntimeError # Please triage this failure.
 deferred_super_dependency_test/01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 field3a_negative_test: Fail # Bogus result from type inference in case of invalid program.
-first_class_types_test: RuntimeError # Please triage this failure.
-generic2_test: RuntimeError # Please triage this failure.
-generic_instanceof_test: RuntimeError # Please triage this failure.
-generic_native_test: RuntimeError # Please triage this failure.
 gc_test: Crash # Internal Error: Pending statics (see above).
-infinite_switch_label_test: Crash # (switch (target){l0:...  continue to a labeled switch case
-instanceof2_test: RuntimeError # Please triage this failure.
-instanceof4_test/01: RuntimeError # Please triage this failure.
 invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
-list_is_test: RuntimeError # Please triage this failure.
-list_test: RuntimeError # Please triage this failure.
-many_generic_instanceof_test: RuntimeError # Please triage this failure.
-nested_switch_label_test: Crash # (switch (target){out...  continue to a labeled switch case
 regress_23500_test/01: Crash # (await for(var c in new Stream.fromIterable([] )){}): await for
-stack_trace_test: Fail # Stack trace not preserved when inlining?
+savannah_test: RuntimeError # Success depends on the variable hints.
 super_call4_test: RuntimeError # Please triage this failure.
 super_getter_setter_test: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
@@ -294,14 +293,7 @@
 super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
 super_operator_index_test/03: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
 super_operator_index_test/05: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
-switch_label2_test: Crash # (switch (target){cas...  continue to a labeled switch case
-switch_label_test: Crash # (switch (animal){cas...  continue to a labeled switch case
-switch_try_catch_test: Crash # (switch (0){_0:case ...  continue to a labeled switch case
-type_variable_closure2_test: RuntimeError # Issue 25309: T lost in List<T>
-type_variable_closure4_test: RuntimeError # T lost in <T,T>{}
-type_variable_field_initializer_closure_test: RuntimeError # Issue 25309: T lost in List<T>
-type_variable_field_initializer_test: RuntimeError # Issue 25309: T lost in List<T>
-type_variable_nested_test: RuntimeError # Issue 25309: T lost in List<T>
+switch8_test: Crash # Pending statics: JSArray
 
 [ $compiler == dart2js && $cps_ir && $host_checked == false ]
 regress_21795_test: Pass, RuntimeError # Due to inlining?
diff --git a/tests/language/library_env_test.dart b/tests/language/library_env_test.dart
new file mode 100644
index 0000000..d076ede
--- /dev/null
+++ b/tests/language/library_env_test.dart
@@ -0,0 +1,87 @@
+// 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 'package:expect/expect.dart';
+
+main() {
+  const NOT_PRESENT = null;
+
+  Expect.isTrue(const bool.fromEnvironment("dart.library.async"));
+  Expect.isTrue(const bool.fromEnvironment("dart.library.collection"));
+  Expect.isTrue(const bool.fromEnvironment("dart.library.convert"));
+  Expect.isTrue(const bool.fromEnvironment("dart.library.core"));
+  Expect.isTrue(const bool.fromEnvironment("dart.library.typed_data"));
+
+
+  bool hasHtmlSupport;
+  hasHtmlSupport = true;   /// has_html_support: ok
+  hasHtmlSupport = false;  /// has_no_html_support: ok
+
+  if (hasHtmlSupport != null) {
+    bool expectedResult = hasHtmlSupport ? true : NOT_PRESENT;
+
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.html",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.indexed_db",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.svg",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.web_audio",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.web_gl",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.web_sql",
+            defaultValue: NOT_PRESENT));
+  }
+
+  bool hasIoSupport;
+  hasIoSupport = true;   /// has_io_support: ok
+  hasIoSupport = false;  /// has_no_io_support: ok
+
+  if (hasIoSupport != null) {
+    bool expectedResult = hasIoSupport ? true : NOT_PRESENT;
+
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.io",
+            defaultValue: NOT_PRESENT));
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.developer",
+            defaultValue: NOT_PRESENT));
+  }
+
+  bool hasMirrorSupport;
+  hasMirrorSupport = true;   /// has_mirror_support: ok
+  hasMirrorSupport = false;  /// has_no_mirror_support: ok
+
+  if (hasMirrorSupport != null) {
+    bool expectedResult = hasMirrorSupport ? true : NOT_PRESENT;
+
+    Expect.equals(expectedResult,
+        const bool.fromEnvironment("dart.library.mirrors",
+            defaultValue: NOT_PRESENT));
+  }
+
+  Expect.equals(NOT_PRESENT,
+      const bool.fromEnvironment("dart.library.XYZ",
+          defaultValue: NOT_PRESENT));
+  Expect.equals(NOT_PRESENT,
+      const bool.fromEnvironment("dart.library.Collection",
+          defaultValue: NOT_PRESENT));
+  Expect.equals(NOT_PRESENT,
+      const bool.fromEnvironment("dart.library.converT",
+          defaultValue: NOT_PRESENT));
+  Expect.equals(NOT_PRESENT,
+      const bool.fromEnvironment("dart.library.",
+          defaultValue: NOT_PRESENT));
+  Expect.equals(NOT_PRESENT,
+      const bool.fromEnvironment("dart.library.core ",
+          defaultValue: NOT_PRESENT));
+
+}
diff --git a/tests/language/method_name_test.dart b/tests/language/method_name_test.dart
index b0199cf..ea9c7d2 100644
--- a/tests/language/method_name_test.dart
+++ b/tests/language/method_name_test.dart
@@ -12,6 +12,7 @@
   int get() {return 1;}
   int set() {return 2;}
   int operator() {return 3;}
+  int factory() { return 4; }
 }
 
 // Without return types.
@@ -19,6 +20,7 @@
   get() {return 1;}
   set() {return 2;}
   operator() {return 3;}
+  factory() { return 4; }
 }
 
 main() {
@@ -27,11 +29,13 @@
     Expect.equals(1, a.get());
     Expect.equals(2, a.set());
     Expect.equals(3, a.operator());
+    Expect.equals(4, a.factory());
   }
   {
     B b = new B();
     Expect.equals(1, b.get());
     Expect.equals(2, b.set());
     Expect.equals(3, b.operator());
+    Expect.equals(4, b.factory());
   }
 }
diff --git a/tests/language/mixin_illegal_constructor_test.dart b/tests/language/mixin_illegal_constructor_test.dart
index d0a59fb..8884084 100644
--- a/tests/language/mixin_illegal_constructor_test.dart
+++ b/tests/language/mixin_illegal_constructor_test.dart
@@ -15,7 +15,7 @@
   M2.named();
 }
 
-class C0 = Object with M0;
+class C0 = Object with M0;      /// 20: compile-time error
 class C1 = Object with M1;      /// 01: compile-time error
 class C2 = Object with M2;      /// 02: compile-time error
 class C3 = Object with M0, M1;  /// 03: compile-time error
@@ -23,7 +23,7 @@
 class C5 = Object with M0, M2;  /// 05: compile-time error
 class C6 = Object with M2, M0;  /// 06: compile-time error
 
-class D0 extends Object with M0 { }
+class D0 extends Object with M0 { }      /// 21: compile-time error
 class D1 extends Object with M1 { }      /// 07: compile-time error
 class D2 extends Object with M2 { }      /// 08: compile-time error
 class D3 extends Object with M0, M1 { }  /// 09: compile-time error
@@ -32,7 +32,7 @@
 class D6 extends Object with M2, M0 { }  /// 12: compile-time error
 
 main() {
-  new C0();
+  new C0();  /// 20: continued
   new C1();  /// 01: continued
   new C2();  /// 02: continued
   new C3();  /// 03: continued
@@ -40,16 +40,11 @@
   new C5();  /// 05: continued
   new C6();  /// 06: continued
 
-  new D0();
+  new D0();  /// 21: continued
   new D1();  /// 07: continued
   new D2();  /// 08: continued
   new D3();  /// 09: continued
   new D4();  /// 10: continued
   new D5();  /// 11: continued
   new D6();  /// 12: continued
-
-  new C0(1,2,3);   /// 13: static type warning, runtime error
-  new C0.named();  /// 14: static type warning, runtime error
-  new D0(1,2,3);   /// 15: static type warning, runtime error
-  new D0.named();  /// 16: static type warning, runtime error
 }
diff --git a/tests/language/mixin_illegal_super_use_test.dart b/tests/language/mixin_illegal_super_use_test.dart
new file mode 100644
index 0000000..7f0d64a
--- /dev/null
+++ b/tests/language/mixin_illegal_super_use_test.dart
@@ -0,0 +1,71 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class M {
+}
+
+class P0 {
+  foo() {
+    super.toString();    /// 01: compile-time error
+    super.foo();         /// 02: compile-time error
+    super.bar = 100;     /// 03: compile-time error
+
+    void inner() {
+      super.toString();  /// 04: compile-time error
+      super.foo();       /// 05: compile-time error
+      super.bar = 100;   /// 06: compile-time error
+    }
+    inner();
+
+    (() {
+      super.toString();  /// 07: compile-time error
+      super.foo();       /// 08: compile-time error
+      super.bar = 100;   /// 09: compile-time error
+    })();
+
+    return 42;
+  }
+}
+
+class P1 {
+  bar() {
+    super.toString();    /// 10: compile-time error
+    return 87;
+  }
+
+  // The test method is strategically placed here to try to force the
+  // P1 class and its bar method to be resolved before resolving the
+  // mixin applications.
+  test() {
+    new C();
+    var d = new D();
+    var e = new E();
+    var f = new F();
+    Expect.equals(42, d.foo());
+    Expect.equals(87, e.bar());
+    Expect.equals(99, f.baz());
+  }
+}
+
+class P2 {
+  baz() {
+    super.toString();   /// 11: compile-time error
+    return 99;
+  }
+}
+
+class C = Object with M;
+class D = Object with P0;
+class E = Object with M, P1;
+class F = Object with P2, M;
+
+main() {
+  var p1 = new P1();
+  var p2 = new P2();
+  Expect.equals(87, p1.bar());
+  p1.test();
+  Expect.equals(99, p2.baz());
+}
diff --git a/tests/language/mixin_illegal_superclass_test.dart b/tests/language/mixin_illegal_superclass_test.dart
new file mode 100644
index 0000000..03d2e6a
--- /dev/null
+++ b/tests/language/mixin_illegal_superclass_test.dart
@@ -0,0 +1,121 @@
+// 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.
+
+class S0 { }
+class S1 extends Object { }
+class S2 extends S0 { }
+
+class M0 { }
+class M1 extends Object { }
+class M2 extends M0 { }
+
+class C00 = S0 with M0;
+class C01 = S0 with M1;
+class C02 = S0 with M2;      /// 01: compile-time error
+class C03 = S0 with M0, M1;
+class C04 = S0 with M0, M2;  /// 02: compile-time error
+class C05 = S0 with M2, M0;  /// 03: compile-time error
+class C06 = S0 with M1, M2;  /// 04: compile-time error
+class C07 = S0 with M2, M1;  /// 05: compile-time error
+
+class C10 = S1 with M0;
+class C11 = S1 with M1;
+class C12 = S1 with M2;      /// 06: compile-time error
+class C13 = S1 with M0, M1;
+class C14 = S1 with M0, M2;  /// 07: compile-time error
+class C15 = S1 with M2, M0;  /// 08: compile-time error
+class C16 = S1 with M1, M2;  /// 09: compile-time error
+class C17 = S1 with M2, M1;  /// 10: compile-time error
+
+class C20 = S2 with M0;
+class C21 = S2 with M1;
+class C22 = S2 with M2;      /// 11: compile-time error
+class C23 = S2 with M0, M1;
+class C24 = S2 with M0, M2;  /// 12: compile-time error
+class C25 = S2 with M2, M0;  /// 13: compile-time error
+class C26 = S2 with M1, M2;  /// 14: compile-time error
+class C27 = S2 with M2, M1;  /// 15: compile-time error
+
+class D00 extends S0 with M0 { }
+class D01 extends S0 with M1 { }
+class D02 extends S0 with M2 { }      /// 16: compile-time error
+class D03 extends S0 with M0, M1 { }
+class D04 extends S0 with M0, M2 { }  /// 17: compile-time error
+class D05 extends S0 with M2, M0 { }  /// 18: compile-time error
+class D06 extends S0 with M1, M2 { }  /// 19: compile-time error
+class D07 extends S0 with M2, M1 { }  /// 20: compile-time error
+
+class D10 extends S1 with M0 { }
+class D11 extends S1 with M1 { }
+class D12 extends S1 with M2 { }      /// 21: compile-time error
+class D13 extends S1 with M0, M1 { }
+class D14 extends S1 with M0, M2 { }  /// 22: compile-time error
+class D15 extends S1 with M2, M0 { }  /// 23: compile-time error
+class D16 extends S1 with M1, M2 { }  /// 24: compile-time error
+class D17 extends S1 with M2, M1 { }  /// 25: compile-time error
+
+class D20 extends S2 with M0 { }
+class D21 extends S2 with M1 { }
+class D22 extends S2 with M2 { }      /// 26: compile-time error
+class D23 extends S2 with M0, M1 { }
+class D24 extends S2 with M0, M2 { }  /// 27: compile-time error
+class D25 extends S2 with M2, M0 { }  /// 28: compile-time error
+class D26 extends S2 with M1, M2 { }  /// 29: compile-time error
+class D27 extends S2 with M2, M1 { }  /// 30: compile-time error
+
+main() {
+  new C00();
+  new C01();
+  new C02();  /// 01: continued
+  new C03();
+  new C04();  /// 02: continued
+  new C05();  /// 03: continued
+  new C06();  /// 04: continued
+  new C07();  /// 05: continued
+
+  new C10();
+  new C11();
+  new C12();  /// 06: continued
+  new C13();
+  new C14();  /// 07: continued
+  new C15();  /// 08: continued
+  new C16();  /// 09: continued
+  new C17();  /// 10: continued
+
+  new C20();
+  new C21();
+  new C22();  /// 11: continued
+  new C23();
+  new C24();  /// 12: continued
+  new C25();  /// 13: continued
+  new C26();  /// 14: continued
+  new C27();  /// 15: continued
+
+  new D00();
+  new D01();
+  new D02();  /// 16: continued
+  new D03();
+  new D04();  /// 17: continued
+  new D05();  /// 18: continued
+  new D06();  /// 19: continued
+  new D07();  /// 20: continued
+
+  new D10();
+  new D11();
+  new D12();  /// 21: continued
+  new D13();
+  new D14();  /// 22: continued
+  new D15();  /// 23: continued
+  new D16();  /// 24: continued
+  new D17();  /// 25: continued
+
+  new D20();
+  new D21();
+  new D22();  /// 26: continued
+  new D23();
+  new D24();  /// 27: continued
+  new D25();  /// 28: continued
+  new D26();  /// 29: continued
+  new D27();  /// 30: continued
+}
diff --git a/tests/language/mixin_super_2_test.dart b/tests/language/mixin_super_2_test.dart
index ad86c08..91d68c6 100644
--- a/tests/language/mixin_super_2_test.dart
+++ b/tests/language/mixin_super_2_test.dart
@@ -1,6 +1,7 @@
 // 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.
+// SharedOptions=--supermixin
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/mixin_super_bound2_test.dart b/tests/language/mixin_super_bound2_test.dart
index c6fcd7a..87e8b7a 100644
--- a/tests/language/mixin_super_bound2_test.dart
+++ b/tests/language/mixin_super_bound2_test.dart
@@ -1,6 +1,7 @@
 // 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.
+// SharedOptions=--supermixin
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/mixin_super_test.dart b/tests/language/mixin_super_test.dart
index 6a5d5a3..8a4ee98 100644
--- a/tests/language/mixin_super_test.dart
+++ b/tests/language/mixin_super_test.dart
@@ -1,6 +1,7 @@
 // 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.
+// SharedOptions=--supermixin
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/mixin_super_use_test.dart b/tests/language/mixin_super_use_test.dart
index cd95846..614bb632c 100644
--- a/tests/language/mixin_super_use_test.dart
+++ b/tests/language/mixin_super_use_test.dart
@@ -1,6 +1,7 @@
 // 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.
+// SharedOptions=--supermixin
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/mixin_superclass_test.dart b/tests/language/mixin_superclass_test.dart
index ade41da..1e658e8 100644
--- a/tests/language/mixin_superclass_test.dart
+++ b/tests/language/mixin_superclass_test.dart
@@ -1,6 +1,7 @@
 // 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.
+// SharedOptions=--supermixin
 
 class S0 { }
 class S1 extends Object { }
diff --git a/tests/language/proxy4_test.dart b/tests/language/proxy4_test.dart
new file mode 100644
index 0000000..a7d44b5
--- /dev/null
+++ b/tests/language/proxy4_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for static warnings for member access on classes that inherit a
+// user defined noSuchMethod.
+
+class Mock {
+  noSuchMethod(i) => 42;
+}
+
+abstract class Foo { int foo(); }
+
+class DontWarnMe extends Mock implements Foo {}
+
+main() {
+  print(new DontWarnMe().foo());
+}
\ No newline at end of file
diff --git a/tests/language/proxy5_test.dart b/tests/language/proxy5_test.dart
new file mode 100644
index 0000000..41e63e6
--- /dev/null
+++ b/tests/language/proxy5_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for static warnings for member access on classes that inherit a
+// user defined noSuchMethod, even if it is abstract.
+
+import 'package:expect/expect.dart';
+
+abstract class Mock {
+  noSuchMethod(i);
+}
+
+abstract class Foo { int foo(); }
+
+class DontWarnMe extends Mock implements Foo {}
+
+main() {
+  Expect.throws(() => new DontWarnMe().foo());
+}
\ No newline at end of file
diff --git a/tests/language/regress_24567_test.dart b/tests/language/regress_24567_test.dart
new file mode 100644
index 0000000..e72750a
--- /dev/null
+++ b/tests/language/regress_24567_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:math' as math;
+
+class Random { }
+
+typedef F(Random r);
+
+main() {
+  f(Random r) { }
+  g(math.Random r) { }
+  Expect.isTrue(f is F);
+  Expect.isFalse(g is F);
+}
diff --git a/tests/lib/analyzer/analyze_library.status b/tests/lib/analyzer/analyze_library.status
index 4016986..3288d18 100644
--- a/tests/lib/analyzer/analyze_library.status
+++ b/tests/lib/analyzer/analyze_library.status
@@ -24,5 +24,5 @@
 lib/indexed_db/dartium/indexed_db_dartium: CompileTimeError # Issue 21647
 lib/web_audio/dartium/web_audio_dartium: CompileTimeError # Issue 21647
 lib/svg/dartium/svg_dartium: CompileTimeError # Issue 21647
-lib/_blink/dartium/_blink_dartium: CompileTimeError # Dartium JsInterop roll (js.JsObjectImpl)
-lib/js/dartium/js_dartium: CompileTimeError # Dartium JsInterop roll (js.JsObjectImpl)
+lib/_blink/dartium/_blink_dartium: CompileTimeError # Undefined Creates and Returns classes
+lib/js/dartium/js_dartium: CompileTimeError # Undefined Creates and Returns classes
\ No newline at end of file
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index d4cdafe..f5d5af2 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -170,7 +170,6 @@
 
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Pass, Slow # Issue 12029.
-mirrors/list_constructor_test/01: RuntimeError # Issue 19635.
 
 [ $compiler == dart2js ]
 convert/chunked_conversion_utf88_test: Slow, Pass
@@ -292,9 +291,6 @@
 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
 
@@ -308,7 +304,7 @@
 [ ($compiler == none || $compiler == precompiler) && $arch == mips ]
 async/timer_regress22626_test: Pass, RuntimeError # Issue 22626
 
-[ $arch == simarm || $arch == simarmv5te ]
+[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te ]
 convert/chunked_conversion_utf88_test: Skip  # Pass, Slow Issue 12644.
 convert/utf85_test: Skip  # Pass, Slow Issue 12644.
 
@@ -331,7 +327,7 @@
 [ ($runtime == vm || $runtime == dart_precompiled) && $mode == release && $arch == ia32 && $system == windows ]
 convert/json_test: RuntimeError # Issue 24908
 
-[ $mode == debug && $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te ]
+[ $mode == debug && $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv6 && $arch != simarmv5te ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification not yet implemented.
 
 [ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
@@ -341,6 +337,7 @@
 [ $compiler == dart2js && $cps_ir ]
 async/async_await_zones_test: Crash # (await for(var x in bar().take(100)){sum+= x;}): await for
 async/stream_iterator_test: Crash # (Stream createCancel...  cannot handle sync*/async* functions
+mirrors/parameter_annotation_mirror_test: Pass, Fail # Issue 25501.  Depends on inlining.
 mirrors/symbol_validation_test/none: RuntimeError # Please triage this failure.
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
diff --git a/tests/lib/mirrors/constructor_optional_args_test.dart b/tests/lib/mirrors/constructor_optional_args_test.dart
new file mode 100644
index 0000000..f9d9657
--- /dev/null
+++ b/tests/lib/mirrors/constructor_optional_args_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.constructor_test;
+
+@MirrorsUsed(targets: const [A])
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+class A {
+  factory A([x, y]) = B;
+  factory A.more([x, y]) = B.more;
+  factory A.oneMore(x, [y]) = B.more;
+}
+
+class B implements A {
+  final _x, _y, _z;
+
+  B([x = 'x', y = 'y']) : _x = x, _y = y, _z = null;
+
+  B.more([x = 'x', y = 'y', z = 'z']) : _x = x, _y = y, _z = z;
+
+  toString() => 'B(x=$_x, y=$_y, z=$_z)';
+}
+
+
+main() {
+  var d1 = new A(1);
+  Expect.equals('B(x=1, y=y, z=null)', '$d1', 'direct 1');
+
+  var d2 = new A.more(1);
+  Expect.equals('B(x=1, y=y, z=z)', '$d2', 'direct 2');
+
+  ClassMirror cm = reflectClass(A);
+
+  var v1 = cm.newInstance(const Symbol(''), []).reflectee;
+  var v2 = cm.newInstance(const Symbol(''), [1]).reflectee;
+  var v3 = cm.newInstance(const Symbol(''), [2, 3]).reflectee;
+
+  Expect.equals('B(x=x, y=y, z=null)', '$v1', 'unnamed 1');
+  Expect.equals('B(x=1, y=y, z=null)', '$v2', 'unnamed 2');
+  Expect.equals('B(x=2, y=3, z=null)', '$v3', 'unnamed 3');
+
+  var m1 = cm.newInstance(const Symbol('more'), []).reflectee;
+  var m2 = cm.newInstance(const Symbol('more'), [1]).reflectee;
+  var m3 = cm.newInstance(const Symbol('more'), [2, 3]).reflectee;
+
+  Expect.equals('B(x=x, y=y, z=z)', '$m1', 'more 1');
+  Expect.equals('B(x=1, y=y, z=z)', '$m2', 'more 2');
+  Expect.equals('B(x=2, y=3, z=z)', '$m3', 'more 3');
+
+  var o1 = cm.newInstance(const Symbol('oneMore'), [1]).reflectee;
+  var o2 = cm.newInstance(const Symbol('oneMore'), [2, 3]).reflectee;
+
+  Expect.equals('B(x=1, y=y, z=z)', '$o1', 'oneMore one arg');
+  Expect.equals('B(x=2, y=3, z=z)', '$o2', 'oneMore two args');
+}
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
index 912b855..e25bc1b 100644
--- a/tests/standalone/io/web_socket_compression_test.dart
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -130,6 +130,43 @@
     });
   }
 
+  void testContextSupport({CompressionOptions serverOpts,
+    CompressionOptions clientOpts,
+    int messages}) {
+    asyncStart();
+
+    createServer().then((server) {
+      server.listen((request) {
+        Expect.isTrue(WebSocketTransformer.isUpgradeRequest(request));
+        WebSocketTransformer.upgrade(request, compression: serverOpts)
+                            .then((webSocket) {
+            webSocket.listen((message) {
+              Expect.equals("Hello World", message);
+              webSocket.add(message);
+            });
+        });
+      });
+
+      var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
+      WebSocket.connect(url, compression: clientOpts).then((websocket) {
+        var i = 1;
+        websocket.listen((message) {
+          Expect.equals("Hello World", message);
+          if (i == messages) {
+            websocket.close();
+            return;
+          }
+          websocket.add("Hello World");
+          i++;
+        }, onDone: () {
+          server.close();
+          asyncEnd();
+        });
+        websocket.add("Hello World");
+      });
+    });
+  }
+
   void testCompressionHeaders() {
     asyncStart();
     createServer().then((server) {
@@ -271,6 +308,31 @@
     // Compression on server but not client.
     testCompressionSupport(server: true);
 
+    // Test Multiple messages with various context takeover configurations.
+    // no context takeover on the server.
+    var serverComp = new CompressionOptions(serverNoContextTakeover: true);
+    testContextSupport(serverOpts: serverComp,
+      clientOpts: serverComp,
+      messages: 5);
+    // no contexttakeover on the client.
+    var clientComp = new CompressionOptions(clientNoContextTakeover: true);
+    testContextSupport(serverOpts: clientComp,
+      clientOpts: clientComp,
+      messages: 5);
+    // no context takeover enabled for both.
+    var compression = new CompressionOptions(serverNoContextTakeover: true,
+                      clientNoContextTakeover: true);
+    testContextSupport(serverOpts: compression,
+      clientOpts: compression,
+      messages: 5);
+    // no context take over for opposing configurations.
+    testContextSupport(serverOpts: serverComp,
+      clientOpts: clientComp,
+      messages: 5);
+    testContextSupport(serverOpts: clientComp,
+      clientOpts: serverComp,
+      messages: 5);
+
     testCompressionHeaders();
     // Chrome headers
     testReturnHeaders('permessage-deflate; client_max_window_bits',
@@ -289,7 +351,7 @@
                       'client_no_context_takeover',
                       'permessage-deflate; client_max_window_bits=15');
     // Enable context Takeover and provide if requested.
-    var compression = new CompressionOptions(clientNoContextTakeover: true,
+    compression = new CompressionOptions(clientNoContextTakeover: true,
         serverNoContextTakeover: true);
     testReturnHeaders('permessage-deflate; client_max_window_bits; '
                       'client_no_context_takeover',
diff --git a/tests/standalone/precompilation_dart2js_test.dart b/tests/standalone/precompilation_dart2js_test.dart
index 5d3900e..d7a8b71 100644
--- a/tests/standalone/precompilation_dart2js_test.dart
+++ b/tests/standalone/precompilation_dart2js_test.dart
@@ -87,7 +87,7 @@
 
     var ld_library_path = new String.fromEnvironment("LD_LIBRARY_PATH");
     ld_library_path = "${ld_library_path}:${tmp.path}";
-    exec = "${dart_executable}_precompiled";
+    exec = "${dart_executable}_precompiled_runtime";
     args = ["--run-precompiled-snapshot", "ignored_script", "--version"];
     print("LD_LIBRARY_PATH=$ld_library_path $exec ${args.join(' ')}");
     result = Process.runSync(exec, args,
diff --git a/tests/standalone/precompilation_test.dart b/tests/standalone/precompilation_test.dart
index 751682e..e58c5fe 100644
--- a/tests/standalone/precompilation_test.dart
+++ b/tests/standalone/precompilation_test.dart
@@ -86,7 +86,7 @@
     ld_library_path = "${ld_library_path}:${tmp.path}";
 
     result = Process.runSync(
-       "${dart_executable}_precompiled",
+       "${dart_executable}_precompiled_runtime",
        ["--run-precompiled-snapshot", "ignored_script", "--hello"],
        workingDirectory: tmp.path,
        environment: {"LD_LIBRARY_PATH": ld_library_path});
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 590489e..8b09928 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -140,7 +140,7 @@
 [ $compiler == dart2js && $browser ]
 *: Skip
 
-[ $arch == simarm || $arch == simarmv5te || $arch == simmips ]
+[ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips ]
 out_of_memory_test: Skip # passes on Mac, crashes on Linux
 oom_error_stacktrace_test: Skip # Fails on Linux
 
@@ -268,4 +268,4 @@
 io/test_extension_test: RuntimeError # Platform.executable
 io/regress_7679_test: RuntimeError # Platform.executable
 
-io/process_*: Skip # Most use Platform.executable
\ No newline at end of file
+io/process_*: Skip # Most use Platform.executable
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index bf69360..e81c804 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -5,8 +5,10 @@
 [ $compiler == dart2js && $host_checked ]
 dummy_compiler_test: Crash # Issue 22809
 
-[ $compiler == dart2js ]
+[ $compiler == dart2js && $host_checked == false ]
 dummy_compiler_test: Slow, Pass
+
+[ $compiler == dart2js ]
 recursive_import_test: Slow, Pass
 source_mirrors_test: Slow, Pass
 
@@ -25,10 +27,5 @@
 recursive_import_test: Pass, RuntimeError # Issue 17662
 source_mirrors_test: Pass, RuntimeError # Issue 17662
 
-[ $compiler == dart2js && $cps_ir ]
-dummy_compiler_test: Crash # (switch (function.na...  continue to a labeled switch case
-recursive_import_test: Crash # (switch (function.na...  continue to a labeled switch case
-source_mirrors_test: Crash, Slow # (switch (function.na...  continue to a labeled switch case
-
 [ ($noopt || $compiler == precompiler) ]
 source_mirrors_test: SkipByDesign # Imports dart:mirrors
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 3f481f1..074f02f 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -11,4 +11,5 @@
 !7zip.tar.gz.sha1
 !firefox_jsshell
 !gsutil.tar.gz.sha1
-!clang.tar.gz.sha1
\ No newline at end of file
+!clang.tar.gz.sha1
+!unittest.tar.gz.sha1
diff --git a/third_party/boringssl/boringssl_configurations.gypi b/third_party/boringssl/boringssl_configurations.gypi
index 91c76c1..0a82431 100644
--- a/third_party/boringssl/boringssl_configurations.gypi
+++ b/third_party/boringssl/boringssl_configurations.gypi
@@ -66,6 +66,27 @@
           'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror off
         },
       },
+      # Disable hand-coded assembly routines on ARMv6 and ARMv5TE.
+      'Dart_armv6_Base': {
+        'abstract': 1,
+        'defines': [
+          'OPENSSL_NO_ASM',
+        ],
+      },
+      'Dart_armv5te_Base': {
+        'abstract': 1,
+        'defines': [
+          'OPENSSL_NO_ASM',
+        ],
+      },
+      # TODO(24321): Also disable temporarily on arm64. Reenable after the next
+      # roll.
+      'Dart_arm64_Base': {
+        'abstract': 1,
+        'defines': [
+          'OPENSSL_NO_ASM',
+        ],
+      },
       # When being built for Android nss expects __linux__ to be defined.
       'Dart_Android_Base': {
         'target_conditions': [
@@ -96,4 +117,4 @@
       },
     },
   },
-}
\ No newline at end of file
+}
diff --git a/third_party/pkg/unittest.tar.gz.sha1 b/third_party/pkg/unittest.tar.gz.sha1
new file mode 100644
index 0000000..2a8a5c2
--- /dev/null
+++ b/third_party/pkg/unittest.tar.gz.sha1
@@ -0,0 +1 @@
+fc9b8ccbfbecf20257255d69693d5a50f8692757
\ No newline at end of file
diff --git a/third_party/pkg_tested/pkg_tested.status b/third_party/pkg_tested/pkg_tested.status
index 031b82b..9a58476 100644
--- a/third_party/pkg_tested/pkg_tested.status
+++ b/third_party/pkg_tested/pkg_tested.status
@@ -23,7 +23,7 @@
 pub/test/run/app_can_read_from_stdin_test: Fail # Issue 19448
 pub/test/run/forwards_signal_posix_test: SkipByDesign
 
-[ $runtime == vm && ($mode == debug || $arch == mips || $arch == simmips || $arch == simarm || $arch == simarmv5te || $arch == simarm64 || $builder_tag == asan) ]
+[ $runtime == vm && ($mode == debug || $arch == mips || $arch == simmips || $arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simarm64 || $builder_tag == asan) ]
 dart_style/test/command_line_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators/mips.
 dart_style/test/formatter_test: Skip # The test controller does not take into account that tests take much longer in debug mode or on simulators/mips.
 
diff --git a/tools/VERSION b/tools/VERSION
index 4c7a8a0..a14f088 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 1
-MINOR 14
+MINOR 15
 PATCH 0
-PRERELEASE 7
-PRERELEASE_PATCH 2
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/build.py b/tools/build.py
index dac178f..91d6864 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -55,8 +55,8 @@
       default=False, action="store_true")
   result.add_option("-a", "--arch",
       help='Target architectures (comma-separated).',
-      metavar='[all,ia32,x64,simarm,arm,simarmv5te,armv5te,simmips,mips'
-              ',simarm64,arm64,]',
+      metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
+              'simmips,mips,simarm64,arm64,]',
       default=utils.GuessArchitecture())
   result.add_option("--os",
     help='Target OSs (comma-separated).',
@@ -101,8 +101,8 @@
       print "Unknown mode %s" % mode
       return False
   for arch in options.arch:
-    archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv5te', 'armv5te', 'simmips',
-             'mips', 'simarm64', 'arm64',]
+    archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
+             'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',]
     if not arch in archs:
       print "Unknown arch %s" % arch
       return False
@@ -119,7 +119,7 @@
         print ("Cross-compilation to %s is not supported on host os %s."
                % (os_name, HOST_OS))
         return False
-      if not arch in ['ia32', 'arm', 'armv5te', 'arm64', 'mips']:
+      if not arch in ['ia32', 'arm', 'armv6', 'armv5te', 'arm64', 'mips']:
         print ("Cross-compilation to %s is not supported for architecture %s."
                % (os_name, arch))
         return False
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index fbb0e6b..accf568 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -14,7 +14,7 @@
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
   "dartium_webkit_branch": "/blink/branches/dart/dartium",
-  "dartium_webkit_revision": "202748",
+  "dartium_webkit_revision": "202760",
 
   # We use mirrors of all github repos to guarantee reproducibility and
   # consistency between what users see and what the bots see.
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 92a5ed0..6d235b81 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -546,14 +546,10 @@
         if (wrap_unwrap_type_blink(type_id, type_registry)):
           type_is_callback = self.isCallback(type_registry, type_id)
           if (dart_js_interop and type_id == 'EventListener' and
-              (self.name == 'addEventListener')):
+              self.name in ['addEventListener', 'removeEventListener']):
               # Events fired need use a JsFunction not a anonymous closure to
               # insure the event can really be removed.
-              parameters.append('wrap_event_listener(this, %s)' % p.name)
-          elif (dart_js_interop and type_id == 'EventListener' and
-              (self.name == 'removeEventListener')):
-              # Find the JsFunction that corresponds to this Dart function.
-              parameters.append('_knownListeners[this.hashCode][identityHashCode(%s)]' % p.name)
+              parameters.append('unwrap_jso(js.allowInterop(%s))' % p.name)
           elif dart_js_interop and type_id == 'FontFaceSetForEachCallback':
               # forEach is supported in the DOM for FontFaceSet as it iterates
               # over the Javascript Object the callback parameters are also
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 24ecbb8..09c242d 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -614,9 +614,7 @@
     return new {0}._internalWrap();
   }}
 
-  factory {0}._internalWrap() {{
-    return new {0}.internal_();
-  }}
+  external factory {0}._internalWrap();
 
   @Deprecated("Internal Use Only")
   {0}.internal_() : super.internal_();
diff --git a/tools/dom/src/dartium_CustomElementSupport.dart b/tools/dom/src/dartium_CustomElementSupport.dart
index aec7b4a..e769e88 100644
--- a/tools/dom/src/dartium_CustomElementSupport.dart
+++ b/tools/dom/src/dartium_CustomElementSupport.dart
@@ -44,7 +44,7 @@
         throw new UnsupportedError('$tag is not registered.');
       }
       jsObject = unwrap_jso(element);
-    } else if (element.runtimeType == js.JsObjectImpl) {
+    } else if (element.runtimeType == js.JsObject) {
       // It's a Polymer core element (written in JS).
       jsObject = element;
     } else if (isNativeElementExtension) {
@@ -56,7 +56,7 @@
     } else if (tag != null && element.localName != tag) {
       throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected native Html or Svg element to extend.');
     } else if (tag == null) {
-      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObjectImpl.');
+      throw new UnsupportedError('Element is incorrect type. Got ${element.runtimeType}, expected HtmlElement/JsObject.');
     }
 
     // Remember Dart class to tagName for any upgrading done in wrap_jso.
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index c82e9b5..66a18e0 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -158,9 +158,9 @@
   '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
   // FIXME: Move these to better locations.
   'DateTime': () => DateTime,
-  'JsObject': () => js.JsObjectImpl,
-  'JsFunction': () => js.JsFunctionImpl,
-  'JsArray': () => js.JsArrayImpl,
+  'JsObject': () => js.JsObject,
+  'JsFunction': () => js.JsFunction,
+  'JsArray': () => js.JsArray,
 $!TYPE_MAP
 };
 
@@ -373,7 +373,7 @@
   } else if (runtimeType == TemplateElement) {
     // Data binding with a Dart class.
     tag = element.attributes['is'];
-  } else if (runtimeType == js.JsObjectImpl) {
+  } else if (runtimeType == js.JsObject) {
     // It's a Polymer core element (written in JS).
     // Make sure it's an element anything else we can ignore.
     if (element.hasProperty('nodeType') && element['nodeType'] == 1) {
@@ -386,7 +386,7 @@
       }
     }
   } else {
-    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObjectImpl.');
+    throw new UnsupportedError('Element is incorrect type. Got ${runtimeType}, expected HtmlElement/HtmlTemplate/JsObject.');
   }
 
   return tag;
@@ -394,15 +394,9 @@
 
 /// An abstract class for all DOM objects we wrap in dart:html and related
 ///  libraries.
-///
-/// ** Internal Use Only **
 @Deprecated("Internal Use Only")
-class DartHtmlDomObject {
-
-  /// The underlying JS DOM object.
-  @Deprecated("Internal Use Only")
-  js.JsObject blink_jsObject;
-
+class DartHtmlDomObject extends js.JSObject {
+  DartHtmlDomObject() : super.internal();
 }
 
 @Deprecated("Internal Use Only")
@@ -418,24 +412,6 @@
   }
 }
 
-// TODO(terry): Manage JS interop JsFunctions for each listener used for add/
-//              removeEventListener.  These JsFunctions will leak look at
-//              fixing with weak-refs in C++.  The key are the hashcodes of the
-//              user's this (this is needed for futures) and listener function.
-Map<int, Map<int, js.JsFunction>> _knownListeners = {};
-
-@Deprecated("Internal Use Only")
-js.JsFunction wrap_event_listener(theObject, Function listener) {
-  var thisHashCode = theObject.hashCode;
-  var listenerHashCode = identityHashCode(listener);
-
-  _knownListeners.putIfAbsent(thisHashCode, () => new Map<int, js.JsFunction>());
-  _knownListeners[thisHashCode].putIfAbsent(listenerHashCode, () =>
-    new js.JsFunction.withThis((theObject, event) => listener(wrap_jso(event))));
-
-  return _knownListeners[thisHashCode][listenerHashCode];
-}
-
 @Deprecated("Internal Use Only")
 Map<String, dynamic> convertNativeObjectToDartMap(js.JsObject jsObject) {
   var result = new Map();
diff --git a/tools/dom/templates/html/impl/impl_DOMException.darttemplate b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
index 9bbae84..498349b 100644
--- a/tools/dom/templates/html/impl/impl_DOMException.darttemplate
+++ b/tools/dom/templates/html/impl/impl_DOMException.darttemplate
@@ -52,12 +52,7 @@
     return new DomException._internalWrap();
   }
 
-  @Deprecated("Internal Use Only")
-  js.JsObject blink_jsObject;
-
-  factory DomException._internalWrap() {
-    return new DomException.internal_();
-  }
+  external factory DomException._internalWrap();
 
   @Deprecated("Internal Use Only")
   DomException.internal_() { }
diff --git a/tools/gyp/configurations.gypi b/tools/gyp/configurations.gypi
index 5b55362..ddf4647 100644
--- a/tools/gyp/configurations.gypi
+++ b/tools/gyp/configurations.gypi
@@ -17,9 +17,11 @@
       ['"<(target_arch)"=="ia32"', { 'dart_target_arch': 'IA32', }],
       ['"<(target_arch)"=="x64"', { 'dart_target_arch': 'X64', }],
       ['"<(target_arch)"=="arm"', { 'dart_target_arch': 'ARM', }],
+      ['"<(target_arch)"=="armv6"', { 'dart_target_arch': 'ARMV6', }],
       ['"<(target_arch)"=="armv5te"', { 'dart_target_arch': 'ARMV5TE', }],
       ['"<(target_arch)"=="arm64"', { 'dart_target_arch': 'ARM64', }],
       ['"<(target_arch)"=="simarm"', { 'dart_target_arch': 'SIMARM', }],
+      ['"<(target_arch)"=="simarmv6"', { 'dart_target_arch': 'SIMARMV6', }],
       ['"<(target_arch)"=="simarmv5te"', { 'dart_target_arch': 'SIMARMV5TE', }],
       ['"<(target_arch)"=="simarm64"', { 'dart_target_arch': 'SIMARM64', }],
       ['"<(target_arch)"=="mips"', { 'dart_target_arch': 'MIPS', }],
@@ -63,6 +65,14 @@
         ]
       },
 
+      'Dart_simarmv6_Base': {
+        'abstract': 1,
+        'defines': [
+          'TARGET_ARCH_ARM',
+          'TARGET_ARCH_ARM_6',
+        ]
+      },
+
       'Dart_simarmv5te_Base': {
         'abstract': 1,
         'defines': [
@@ -78,6 +88,14 @@
         ],
       },
 
+      'Dart_armv6_Base': {
+        'abstract': 1,
+        'defines': [
+          'TARGET_ARCH_ARM',
+          'TARGET_ARCH_ARM_6',
+        ],
+      },
+
       'Dart_armv5te_Base': {
         'abstract': 1,
         'defines': [
@@ -184,6 +202,27 @@
         ],
       },
 
+      'DebugSIMARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simarmv6_Base', 'Dart_Debug',
+          'Dart_<(dart_target_os)_Base',
+          'Dart_<(dart_target_os)_simarmv6_Base',
+          'Dart_<(dart_target_os)_Debug',
+        ],
+        'defines': [
+          'DEBUG',
+        ],
+      },
+
+      'ReleaseSIMARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simarmv6_Base', 'Dart_Release',
+          'Dart_<(dart_target_os)_Base',
+          'Dart_<(dart_target_os)_simarmv6_Base',
+          'Dart_<(dart_target_os)_Release',
+        ],
+      },
+
       'DebugSIMARMV5TE': {
         'inherit_from': [
           'Dart_Base', 'Dart_simarmv5te_Base', 'Dart_Debug',
@@ -285,6 +324,42 @@
         ],
       },
 
+      'DebugXARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_armv6_Base', 'Dart_Debug',
+          'Dart_Linux_Base',
+          'Dart_Linux_xarmv6_Base',
+          'Dart_Linux_Debug',
+        ],
+      },
+
+      'ReleaseXARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_armv6_Base', 'Dart_Release',
+          'Dart_Linux_Base',
+          'Dart_Linux_xarmv6_Base',
+          'Dart_Linux_Release',
+        ],
+      },
+
+      'DebugARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_armv6_Base', 'Dart_Debug',
+          'Dart_Linux_Base',
+          'Dart_Linux_armv6_Base',
+          'Dart_Linux_Debug',
+        ],
+      },
+
+      'ReleaseARMV6': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_armv6_Base', 'Dart_Release',
+          'Dart_Linux_Base',
+          'Dart_Linux_armv6_Base',
+          'Dart_Linux_Release',
+        ],
+      },
+
       'DebugXARMV5TE': {
         'inherit_from': [
           'Dart_Base', 'Dart_armv5te_Base', 'Dart_Debug',
diff --git a/tools/gyp/configurations_make.gypi b/tools/gyp/configurations_make.gypi
index ebaf935..307b1c2 100644
--- a/tools/gyp/configurations_make.gypi
+++ b/tools/gyp/configurations_make.gypi
@@ -76,6 +76,12 @@
         'ldflags': [ '-m32', ],
       },
 
+      'Dart_Linux_simarmv6_Base': {
+        'abstract': 1,
+        'cflags': [ '-O3', '-m32', '-msse2', '-mfpmath=sse' ],
+        'ldflags': [ '-m32', ],
+      },
+
       'Dart_Linux_simarmv5te_Base': {
         'abstract': 1,
         'cflags': [ '-O3', '-m32', '-msse2', '-mfpmath=sse' ],
@@ -117,6 +123,35 @@
         ],
       },
 
+      # ARMv6 cross-build
+      'Dart_Linux_xarmv6_Base': {
+        'abstract': 1,
+        'target_conditions': [
+        ['_toolset=="target"', {
+          'cflags': [
+            '-march=armv6',
+            '-mfpu=vfp',
+            '-Wno-psabi', # suppresses va_list warning
+            '-fno-strict-overflow',
+          ],
+        }],
+        ['_toolset=="host"', {
+          'cflags': ['-m32', '-msse2', '-mfpmath=sse' ],
+          'ldflags': ['-m32'],
+        }]]
+      },
+
+      # ARMv6 native build
+      'Dart_Linux_armv6_Base': {
+        'abstract': 1,
+        'cflags': [
+          '-march=armv6',
+          '-mfpu=vfp',
+          '-Wno-psabi', # suppresses va_list warning
+          '-fno-strict-overflow',
+        ],
+      },
+
       # ARMv5 cross-build
       'Dart_Linux_xarmv5te_Base': {
         'abstract': 1,
diff --git a/tools/gyp/configurations_msvs.gypi b/tools/gyp/configurations_msvs.gypi
index 3c859ce..c8b0fd3 100644
--- a/tools/gyp/configurations_msvs.gypi
+++ b/tools/gyp/configurations_msvs.gypi
@@ -24,6 +24,9 @@
       'Dart_Win_simarm_Base': {
         'abstract': 1,
       },
+      'Dart_Win_simarmv6_Base': {
+        'abstract': 1,
+      },
       'Dart_Win_simarmv5te_Base': {
         'abstract': 1,
       },
diff --git a/tools/gyp/configurations_xcode.gypi b/tools/gyp/configurations_xcode.gypi
index f709727..e3d04b6 100644
--- a/tools/gyp/configurations_xcode.gypi
+++ b/tools/gyp/configurations_xcode.gypi
@@ -78,6 +78,9 @@
       'Dart_Macos_simarm_Base': {
         'abstract': 1,
       },
+      'Dart_Macos_simarmv6_Base': {
+        'abstract': 1,
+      },
       'Dart_Macos_simarmv5te_Base': {
         'abstract': 1,
       },
diff --git a/tools/precompilation/test_linux.sh b/tools/precompilation/test_linux.sh
index 553dc18b..93de570 100755
--- a/tools/precompilation/test_linux.sh
+++ b/tools/precompilation/test_linux.sh
@@ -12,4 +12,4 @@
 
 gcc -m64 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart_precompiled --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugX64/dart_precompiled_runtime --run-precompiled-snapshot not_used.dart
diff --git a/tools/precompilation/test_linux_simarm.sh b/tools/precompilation/test_linux_simarm.sh
index e61b58b..8a8f36c 100755
--- a/tools/precompilation/test_linux_simarm.sh
+++ b/tools/precompilation/test_linux_simarm.sh
@@ -12,4 +12,4 @@
 
 gcc -m32 -shared -Wl,-soname,libprecompiled.so -o libprecompiled.so precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart_precompiled --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" gdb -ex run --args ./out/DebugSIMARM/dart_precompiled_runtime --run-precompiled-snapshot not_used.dart
diff --git a/tools/precompilation/test_macos.sh b/tools/precompilation/test_macos.sh
index 57e02dc..e853b1b 100755
--- a/tools/precompilation/test_macos.sh
+++ b/tools/precompilation/test_macos.sh
@@ -12,4 +12,4 @@
 
 clang -m64 -dynamiclib -o libprecompiled.dylib precompiled.S
 
-LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart_precompiled --run-precompiled-snapshot not_used.dart
+LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$PWD" lldb -- ./xcodebuild/DebugX64/dart_precompiled_runtime --run-precompiled-snapshot not_used.dart
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 55810eb..2978003 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -172,6 +172,8 @@
     switch (arch) {
       case 'simarm':
       case 'arm':
+      case 'simarmv6':
+      case 'armv6':
       case' simarmv5te':
       case 'armv5te':
       case 'simmips':
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 92514fe..852e86d 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -108,8 +108,8 @@
               'arch',
               'The architecture to run tests for',
               ['-a', '--arch'],
-              ['all', 'ia32', 'x64', 'arm', 'armv5te', 'arm64', 'mips',
-               'simarm', 'simarmv5te', 'simarm64', 'simmips'],
+              ['all', 'ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
+               'simarm', 'simarmv6', 'simarmv5te', 'simarm64', 'simmips'],
               'x64'),
           new _TestOptionSpecification(
               'system',
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 533c01c..fd67ebf 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -218,7 +218,7 @@
 
     if (dartExecutable == null || dartExecutable == '') {
       String suffix = executableBinarySuffix;
-      dartExecutable = '$buildDir/dart_precompiled$suffix';
+      dartExecutable = '$buildDir/dart_precompiled_runtime$suffix';
     }
 
     TestUtils.ensureExists(dartExecutable, configuration);
diff --git a/tools/utils.py b/tools/utils.py
index aaef94c..f2f0704 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -52,6 +52,8 @@
   os_id = platform.machine()
   if os_id.startswith('armv5te'):
     return 'armv5te'
+  elif os_id.startswith('armv6'):
+    return 'armv6'
   elif os_id.startswith('arm'):
     return 'arm'
   elif os_id.startswith('aarch64'):
@@ -228,10 +230,12 @@
   'ia32': 'ia32',
   'x64': 'ia32',
   'arm': 'arm',
+  'armv6': 'arm',
   'armv5te': 'arm',
   'arm64': 'arm',
   'mips': 'mips',
   'simarm': 'ia32',
+  'simarmv6': 'ia32',
   'simarmv5te': 'ia32',
   'simmips': 'ia32',
   'simarm64': 'ia32',
@@ -581,6 +585,9 @@
       # TODO(zra): This binary does not exist, yet. Check one in once we have
       # sufficient stability.
       return os.path.join(dart_binary_prefix, system, 'dart-armv5te')
+    elif arch == 'armv6':
+      # TODO(zra): Ditto.
+      return os.path.join(dart_binary_prefix, system, 'dart-armv6')
     elif arch == 'arm':
       return os.path.join(dart_binary_prefix, system, 'dart-arm')
     elif arch == 'arm64':
