Version 1.4.0-dev.1.0

svn merge -r 34866:34916 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@34925 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index 52c4124..8a91113 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -6469,6 +6469,7 @@
  * <pre>
  * importDirective ::=
  *     [Annotation] 'import' [StringLiteral] ('as' identifier)? [Combinator]* ';'
+ *   | [Annotation] 'import' [StringLiteral] 'deferred' 'as' identifier [Combinator]* ';'
  * </pre>
  */
 class ImportDirective extends NamespaceDirective {
@@ -6564,6 +6565,11 @@
   };
 
   /**
+   * The token representing the 'deferred' token, or `null` if the imported is not deferred.
+   */
+  Token deferredToken;
+
+  /**
    * The token representing the 'as' token, or `null` if the imported names are not prefixed.
    */
   Token asToken;
@@ -6581,12 +6587,13 @@
    * @param metadata the annotations associated with the directive
    * @param keyword the token representing the 'import' keyword
    * @param libraryUri the URI of the library being imported
+   * @param deferredToken the token representing the 'deferred' token
    * @param asToken the token representing the 'as' token
    * @param prefix the prefix to be used with the imported names
    * @param combinators the combinators used to control how names are imported
    * @param semicolon the semicolon terminating the directive
    */
-  ImportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, this.asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+  ImportDirective(Comment comment, List<Annotation> metadata, Token keyword, StringLiteral libraryUri, this.deferredToken, this.asToken, SimpleIdentifier prefix, List<Combinator> combinators, Token semicolon) : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
     this._prefix = becomeParentOf(prefix);
   }
 
@@ -12637,6 +12644,13 @@
         return element;
       }
     }
+    // try to get Polymer specific Element
+    {
+      Element element = null;
+      if (element != null) {
+        return element;
+      }
+    }
     // no Element
     return null;
   }
@@ -15769,7 +15783,7 @@
 
   @override
   ImportDirective visitImportDirective(ImportDirective node) {
-    ImportDirective directive = new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), node.keyword, _cloneNode(node.uri), node.asToken, _cloneNode(node.prefix), _cloneNodeList(node.combinators), node.semicolon);
+    ImportDirective directive = new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), node.keyword, _cloneNode(node.uri), node.deferredToken, node.asToken, _cloneNode(node.prefix), _cloneNodeList(node.combinators), node.semicolon);
     directive.source = node.source;
     directive.uriContent = node.uriContent;
     return directive;
@@ -16964,7 +16978,7 @@
   ImplementsClause visitImplementsClause(ImplementsClause node) => new ImplementsClause(_mapToken(node.keyword), _cloneNodeList(node.interfaces));
 
   @override
-  ImportDirective visitImportDirective(ImportDirective node) => new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), _mapToken(node.keyword), _cloneNode(node.uri), _mapToken(node.asToken), _cloneNode(node.prefix), _cloneNodeList(node.combinators), _mapToken(node.semicolon));
+  ImportDirective visitImportDirective(ImportDirective node) => new ImportDirective(_cloneNode(node.documentationComment), _cloneNodeList(node.metadata), _mapToken(node.keyword), _cloneNode(node.uri), _mapToken(node.deferredToken), _mapToken(node.asToken), _cloneNode(node.prefix), _cloneNodeList(node.combinators), _mapToken(node.semicolon));
 
   @override
   IndexExpression visitIndexExpression(IndexExpression node) {
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index e7aeff2..91815ec 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -17,7 +17,7 @@
 import 'resolver.dart' show TypeProvider;
 import 'engine.dart' show AnalysisEngine;
 import 'utilities_dart.dart' show ParameterKind;
-import 'utilities_collection.dart' show DirectedGraph;
+import 'utilities_collection.dart';
 
 /**
  * Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
@@ -312,11 +312,11 @@
    */
   void computeValues() {
     _declarationMap = _constantFinder.variableMap;
-    for (MapEntry<VariableElement, VariableDeclaration> entry in getMapEntrySet(_declarationMap)) {
-      VariableElement element = entry.getKey();
+    for (MapIterator<VariableElement, VariableDeclaration> iter = SingleMapIterator.forMap(_declarationMap); iter.moveNext();) {
+      VariableElement element = iter.key;
       ReferenceFinder referenceFinder = new ReferenceFinder(element, _referenceGraph);
       _referenceGraph.addNode(element);
-      entry.getValue().initializer.accept(referenceFinder);
+      iter.value.initializer.accept(referenceFinder);
     }
     while (!_referenceGraph.isEmpty) {
       VariableElement element = _referenceGraph.removeSink();
@@ -3938,9 +3938,9 @@
     } else if (count == 0) {
       return true;
     }
-    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
-      DartObjectImpl key = entry.getKey();
-      DartObjectImpl value = entry.getValue();
+    for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+      DartObjectImpl key = iter.key;
+      DartObjectImpl value = iter.value;
       DartObjectImpl otherValue = otherElements[key];
       if (value != otherValue) {
         return false;
@@ -3955,9 +3955,9 @@
   @override
   Map<Object, Object> get value {
     Map<Object, Object> result = new Map<Object, Object>();
-    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
-      DartObjectImpl key = entry.getKey();
-      DartObjectImpl value = entry.getValue();
+    for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+      DartObjectImpl key = iter.key;
+      DartObjectImpl value = iter.value;
       if (!key.hasExactValue || !value.hasExactValue) {
         return null;
       }
@@ -3968,8 +3968,8 @@
 
   @override
   bool get hasExactValue {
-    for (MapEntry<DartObjectImpl, DartObjectImpl> entry in getMapEntrySet(_entries)) {
-      if (!entry.getKey().hasExactValue || !entry.getValue().hasExactValue) {
+    for (MapIterator<DartObjectImpl, DartObjectImpl> iter = SingleMapIterator.forMap(_entries); iter.moveNext();) {
+      if (!iter.key.hasExactValue || !iter.value.hasExactValue) {
         return false;
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 85c655f..a10931f 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -412,6 +412,15 @@
    * @return the classes contained in this compilation unit
    */
   List<ClassElement> get types;
+
+  /**
+   * Return `true` if this compilation unit defines a top-level function named
+   * `loadLibrary`.
+   *
+   * @return `true` if this compilation unit defines a top-level function named
+   *         `loadLibrary`
+   */
+  bool get hasLoadLibraryFunction;
 }
 
 /**
@@ -785,17 +794,23 @@
 
   static const ElementKind PARAMETER = const ElementKind('PARAMETER', 26, "parameter");
 
-  static const ElementKind PREFIX = const ElementKind('PREFIX', 27, "import prefix");
+  static const ElementKind POLYMER_ATTRIBUTE = const ElementKind('POLYMER_ATTRIBUTE', 27, "Polymer attribute");
 
-  static const ElementKind SETTER = const ElementKind('SETTER', 28, "setter");
+  static const ElementKind POLYMER_TAG_DART = const ElementKind('POLYMER_TAG_DART', 28, "Polymer Dart tag");
 
-  static const ElementKind TOP_LEVEL_VARIABLE = const ElementKind('TOP_LEVEL_VARIABLE', 29, "top level variable");
+  static const ElementKind POLYMER_TAG_HTML = const ElementKind('POLYMER_TAG_HTML', 29, "Polymer HTML tag");
 
-  static const ElementKind FUNCTION_TYPE_ALIAS = const ElementKind('FUNCTION_TYPE_ALIAS', 30, "function type alias");
+  static const ElementKind PREFIX = const ElementKind('PREFIX', 30, "import prefix");
 
-  static const ElementKind TYPE_PARAMETER = const ElementKind('TYPE_PARAMETER', 31, "type parameter");
+  static const ElementKind SETTER = const ElementKind('SETTER', 31, "setter");
 
-  static const ElementKind UNIVERSE = const ElementKind('UNIVERSE', 32, "<universe>");
+  static const ElementKind TOP_LEVEL_VARIABLE = const ElementKind('TOP_LEVEL_VARIABLE', 32, "top level variable");
+
+  static const ElementKind FUNCTION_TYPE_ALIAS = const ElementKind('FUNCTION_TYPE_ALIAS', 33, "function type alias");
+
+  static const ElementKind TYPE_PARAMETER = const ElementKind('TYPE_PARAMETER', 34, "type parameter");
+
+  static const ElementKind UNIVERSE = const ElementKind('UNIVERSE', 35, "<universe>");
 
   static const List<ElementKind> values = const [
       ANGULAR_FILTER,
@@ -825,6 +840,9 @@
       METHOD,
       NAME,
       PARAMETER,
+      POLYMER_ATTRIBUTE,
+      POLYMER_TAG_DART,
+      POLYMER_TAG_HTML,
       PREFIX,
       SETTER,
       TOP_LEVEL_VARIABLE,
@@ -930,6 +948,12 @@
 
   R visitParameterElement(ParameterElement element);
 
+  R visitPolymerAttributeElement(PolymerAttributeElement element);
+
+  R visitPolymerTagDartElement(PolymerTagDartElement element);
+
+  R visitPolymerTagHtmlElement(PolymerTagHtmlElement element);
+
   R visitPrefixElement(PrefixElement element);
 
   R visitPropertyAccessorElement(PropertyAccessorElement element);
@@ -1084,6 +1108,11 @@
  */
 abstract class FunctionElement implements ExecutableElement, LocalElement {
   /**
+   * The name of the synthetic function defined for libraries that are deferred.
+   */
+  static final String LOAD_LIBRARY_NAME = "loadLibrary";
+
+  /**
    * Return the resolved [FunctionDeclaration] node that declares this [FunctionElement]
    * .
    *
@@ -1175,6 +1204,14 @@
   CompilationUnitElement get angularCompilationUnit;
 
   /**
+   * Return an array containing all of the [PolymerTagHtmlElement]s defined in the HTML file.
+   *
+   * @return the [PolymerTagHtmlElement]s elements in the HTML file (not `null`,
+   *         contains no `null`s)
+   */
+  List<PolymerTagHtmlElement> get polymerTags;
+
+  /**
    * Return an array containing all of the script elements contained in the HTML file. This includes
    * scripts with libraries that are defined by the content of a script tag as well as libraries
    * that are referenced in the {@core source} attribute of a script tag.
@@ -1235,6 +1272,13 @@
    * @return the offset of the prefix of this import
    */
   int get prefixOffset;
+
+  /**
+   * Return `true` if this import is for a deferred library.
+   *
+   * @return `true` if this import is for a deferred library
+   */
+  bool get isDeferred;
 }
 
 /**
@@ -1349,6 +1393,13 @@
   bool get hasExtUri;
 
   /**
+   * Return `true` if this library defines a top-level function named `loadLibrary`.
+   *
+   * @return `true` if this library defines a top-level function named `loadLibrary`
+   */
+  bool get hasLoadLibraryFunction;
+
+  /**
    * Return `true` if this library is created for Angular analysis. If this library has not
    * yet had toolkit references resolved, then `false` will be returned.
    *
@@ -1876,7 +1927,7 @@
  */
 abstract class AngularElement implements ToolkitObjectElement {
   /**
-   * An empty array of angular elements.
+   * An empty array of Angular elements.
    */
   static final List<AngularElement> EMPTY_ARRAY = new List<AngularElement>(0);
 
@@ -2087,6 +2138,87 @@
 }
 
 /**
+ * The interface `PolymerAttributeElement` defines an attribute in
+ * [PolymerTagHtmlElement].
+ *
+ * <pre>
+ * <polymer-element name="my-example" attributes='attrA attrB'>
+ * </polymer-element>
+ * </pre>
+ */
+abstract class PolymerAttributeElement implements PolymerElement {
+  /**
+   * An empty array of Polymer custom tag attributes.
+   */
+  static final List<PolymerAttributeElement> EMPTY_ARRAY = new List<PolymerAttributeElement>(0);
+
+  /**
+   * Return the [FieldElement] associated with this attribute. Maybe `null` if
+   * [PolymerTagDartElement] does not have a field associated with it.
+   */
+  FieldElement get field;
+}
+
+/**
+ * The interface `PolymerElement` defines the behavior of objects representing information
+ * about a Polymer specific element.
+ */
+abstract class PolymerElement implements ToolkitObjectElement {
+  /**
+   * An empty array of Polymer elements.
+   */
+  static final List<PolymerElement> EMPTY_ARRAY = new List<PolymerElement>(0);
+}
+
+/**
+ * The interface `PolymerTagDartElement` defines a Polymer custom tag in Dart.
+ *
+ * <pre>
+ * @CustomTag('my-example')
+ * </pre>
+ */
+abstract class PolymerTagDartElement implements PolymerElement {
+  /**
+   * Return the [ClassElement] that is associated with this Polymer custom tag. Not
+   * `null`, because [PolymerTagDartElement]s are created for [ClassElement]s
+   * marked with the `@CustomTag` annotation.
+   */
+  ClassElement get classElement;
+
+  /**
+   * Return the [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe `null` if
+   * it has not been resolved yet or there are no corresponding Dart part defined.
+   */
+  PolymerTagHtmlElement get htmlElement;
+}
+
+/**
+ * The interface `PolymerTagHtmlElement` defines a Polymer custom tag in HTML.
+ *
+ * <pre>
+ * <polymer-element name="my-example" attributes='attrA attrB'>
+ * </polymer-element>
+ * </pre>
+ */
+abstract class PolymerTagHtmlElement implements PolymerElement {
+  /**
+   * An empty array of [PolymerTagHtmlElement]s.
+   */
+  static final List<PolymerTagHtmlElement> EMPTY_ARRAY = new List<PolymerTagHtmlElement>(0);
+
+  /**
+   * Return an array containing all of the attributes declared by this tag.
+   */
+  List<PolymerAttributeElement> get attributes;
+
+  /**
+   * Return the [PolymerTagDartElement] part on this Polymer custom tag. Maybe `null` if
+   * it has not been resolved yet or there are no corresponding Dart part defined.
+   */
+  PolymerTagDartElement get dartElement;
+}
+
+/**
  * Instances of the class `GeneralizingElementVisitor` implement an element visitor that will
  * recursively visit all of the elements in an element model (like instances of the class
  * [RecursiveElementVisitor]). In addition, when an element of a specific type is visited not
@@ -2245,6 +2377,17 @@
   R visitParameterElement(ParameterElement element) => visitLocalElement(element);
 
   @override
+  R visitPolymerAttributeElement(PolymerAttributeElement element) => visitPolymerElement(element);
+
+  R visitPolymerElement(PolymerElement element) => visitToolkitObjectElement(element);
+
+  @override
+  R visitPolymerTagDartElement(PolymerTagDartElement element) => visitPolymerElement(element);
+
+  @override
+  R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => visitPolymerElement(element);
+
+  @override
   R visitPrefixElement(PrefixElement element) => visitElement(element);
 
   @override
@@ -2431,6 +2574,24 @@
   }
 
   @override
+  R visitPolymerAttributeElement(PolymerAttributeElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPolymerTagDartElement(PolymerTagDartElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) {
+    element.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitPrefixElement(PrefixElement element) {
     element.visitChildren(this);
     return null;
@@ -2541,6 +2702,15 @@
   R visitParameterElement(ParameterElement element) => null;
 
   @override
+  R visitPolymerAttributeElement(PolymerAttributeElement element) => null;
+
+  @override
+  R visitPolymerTagDartElement(PolymerTagDartElement element) => null;
+
+  @override
+  R visitPolymerTagHtmlElement(PolymerTagHtmlElement element) => null;
+
+  @override
   R visitPrefixElement(PrefixElement element) => null;
 
   @override
@@ -2652,6 +2822,16 @@
   @override
   accept(ElementVisitor visitor) => visitor.visitClassElement(this);
 
+  /**
+   * Set the toolkit specific information objects attached to this class.
+   *
+   * @param toolkitObjects the toolkit objects attached to this class
+   */
+  void addToolkitObjects(ToolkitObjectElement toolkitObject) {
+    (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
+    _toolkitObjects = ArrayUtils.add(_toolkitObjects, toolkitObject);
+  }
+
   @override
   List<PropertyAccessorElement> get accessors => _accessors;
 
@@ -3008,18 +3188,6 @@
   }
 
   /**
-   * Set the toolkit specific information objects attached to this class.
-   *
-   * @param toolkitObjects the toolkit objects attached to this class
-   */
-  void set toolkitObjects(List<ToolkitObjectElement> toolkitObjects) {
-    for (ToolkitObjectElement toolkitObject in toolkitObjects) {
-      (toolkitObject as ToolkitObjectElementImpl).enclosingElement = this;
-    }
-    this._toolkitObjects = toolkitObjects;
-  }
-
-  /**
    * Set whether this class is defined by a typedef construct to correspond to the given value.
    *
    * @param isTypedef `true` if the class is defined by a typedef construct
@@ -3274,6 +3442,16 @@
   @override
   int get hashCode => source.hashCode;
 
+  @override
+  bool get hasLoadLibraryFunction {
+    for (int i = 0; i < _functions.length; i++) {
+      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
+        return true;
+      }
+    }
+    return false;
+  }
+
   /**
    * Set the top-level accessors (getters and setters) contained in this compilation unit to the
    * given accessors.
@@ -4958,6 +5136,11 @@
   List<HtmlScriptElement> _scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
 
   /**
+   * The [PolymerTagHtmlElement]s defined in the HTML file.
+   */
+  List<PolymerTagHtmlElement> _polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
+
+  /**
    * The source that corresponds to this HTML file.
    */
   Source source;
@@ -4994,19 +5177,37 @@
   ElementKind get kind => ElementKind.HTML;
 
   @override
+  List<PolymerTagHtmlElement> get polymerTags => _polymerTags;
+
+  @override
   List<HtmlScriptElement> get scripts => _scripts;
 
   @override
   int get hashCode => source.hashCode;
 
   /**
+   * Set the [PolymerTagHtmlElement]s defined in the HTML file.
+   */
+  void set polymerTags(List<PolymerTagHtmlElement> polymerTags) {
+    if (polymerTags.length == 0) {
+      this._polymerTags = PolymerTagHtmlElement.EMPTY_ARRAY;
+      return;
+    }
+    for (PolymerTagHtmlElement tag in polymerTags) {
+      (tag as PolymerTagHtmlElementImpl).enclosingElement = this;
+    }
+    this._polymerTags = polymerTags;
+  }
+
+  /**
    * Set the scripts contained in the HTML file to the given scripts.
    *
    * @param scripts the scripts
    */
   void set scripts(List<HtmlScriptElement> scripts) {
     if (scripts.length == 0) {
-      scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
+      this._scripts = HtmlScriptElementImpl.EMPTY_ARRAY;
+      return;
     }
     for (HtmlScriptElement script in scripts) {
       (script as HtmlScriptElementImpl).enclosingElement = this;
@@ -5018,6 +5219,7 @@
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     safelyVisitChildren(_scripts, visitor);
+    safelyVisitChildren(_polymerTags, visitor);
   }
 
   @override
@@ -5088,6 +5290,18 @@
   ElementKind get kind => ElementKind.IMPORT;
 
   @override
+  bool get isDeferred => hasModifier(Modifier.DEFERRED);
+
+  /**
+   * Set whether this import is for a deferred library to correspond to the given value.
+   *
+   * @param isDeferred `true` if this import is for a deferred library
+   */
+  void set deferred(bool isDeferred) {
+    setModifier(Modifier.DEFERRED, isDeferred);
+  }
+
+  @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     safelyVisitChild(prefix, visitor);
@@ -5376,6 +5590,19 @@
   int get hashCode => _definingCompilationUnit.hashCode;
 
   @override
+  bool get hasLoadLibraryFunction {
+    if (_definingCompilationUnit.hasLoadLibraryFunction) {
+      return true;
+    }
+    for (int i = 0; i < _parts.length; i++) {
+      if (_parts[i].hasLoadLibraryFunction) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
   bool get isAngularHtml => _isAngularHtml;
 
   @override
@@ -5752,52 +5979,58 @@
   static const Modifier CONST = const Modifier('CONST', 1);
 
   /**
+   * Indicates that the import element represents a deferred library.
+   */
+  static const Modifier DEFERRED = const Modifier('DEFERRED', 2);
+
+  /**
    * Indicates that the modifier 'factory' was applied to the element.
    */
-  static const Modifier FACTORY = const Modifier('FACTORY', 2);
+  static const Modifier FACTORY = const Modifier('FACTORY', 3);
 
   /**
    * Indicates that the modifier 'final' was applied to the element.
    */
-  static const Modifier FINAL = const Modifier('FINAL', 3);
+  static const Modifier FINAL = const Modifier('FINAL', 4);
 
   /**
    * Indicates that the pseudo-modifier 'get' was applied to the element.
    */
-  static const Modifier GETTER = const Modifier('GETTER', 4);
+  static const Modifier GETTER = const Modifier('GETTER', 5);
 
   /**
    * 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', 5);
+  static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 6);
 
-  static const Modifier MIXIN = const Modifier('MIXIN', 6);
+  static const Modifier MIXIN = const Modifier('MIXIN', 7);
 
-  static const Modifier REFERENCES_SUPER = const Modifier('REFERENCES_SUPER', 7);
+  static const Modifier REFERENCES_SUPER = const Modifier('REFERENCES_SUPER', 8);
 
   /**
    * Indicates that the pseudo-modifier 'set' was applied to the element.
    */
-  static const Modifier SETTER = const Modifier('SETTER', 8);
+  static const Modifier SETTER = const Modifier('SETTER', 9);
 
   /**
    * Indicates that the modifier 'static' was applied to the element.
    */
-  static const Modifier STATIC = const Modifier('STATIC', 9);
+  static const Modifier STATIC = const Modifier('STATIC', 10);
 
   /**
    * 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', 10);
+  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 11);
 
-  static const Modifier TYPEDEF = const Modifier('TYPEDEF', 11);
+  static const Modifier TYPEDEF = const Modifier('TYPEDEF', 12);
 
   static const List<Modifier> values = const [
       ABSTRACT,
       CONST,
+      DEFERRED,
       FACTORY,
       FINAL,
       GETTER,
@@ -8012,6 +8245,128 @@
 }
 
 /**
+ * Implementation of `PolymerAttributeElement`.
+ */
+class PolymerAttributeElementImpl extends PolymerElementImpl implements PolymerAttributeElement {
+  /**
+   * The [FieldElement] associated with this attribute.
+   */
+  FieldElement field;
+
+  /**
+   * Initialize a newly created Polymer attribute to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  PolymerAttributeElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPolymerAttributeElement(this);
+
+  @override
+  ElementKind get kind => ElementKind.POLYMER_ATTRIBUTE;
+}
+
+/**
+ * Implementation of `PolymerElement`.
+ */
+abstract class PolymerElementImpl extends ToolkitObjectElementImpl implements PolymerElement {
+  /**
+   * Initialize a newly created Polymer element to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  PolymerElementImpl(String name, int nameOffset) : super(name, nameOffset);
+}
+
+/**
+ * Implementation of `PolymerTagDartElement`.
+ */
+class PolymerTagDartElementImpl extends PolymerElementImpl implements PolymerTagDartElement {
+  /**
+   * The [ClassElement] that is associated with this Polymer custom tag.
+   */
+  final ClassElement classElement;
+
+  /**
+   * The [PolymerTagHtmlElement] part of this Polymer custom tag. Maybe `null` if it has
+   * not been resolved yet or there are no corresponding Dart part defined.
+   */
+  PolymerTagHtmlElement htmlElement;
+
+  /**
+   * Initialize a newly created Dart part of a Polymer tag to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  PolymerTagDartElementImpl(String name, int nameOffset, this.classElement) : super(name, nameOffset);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPolymerTagDartElement(this);
+
+  @override
+  ElementKind get kind => ElementKind.POLYMER_TAG_DART;
+}
+
+/**
+ * Implementation of `PolymerTagHtmlElement`.
+ */
+class PolymerTagHtmlElementImpl extends PolymerElementImpl implements PolymerTagHtmlElement {
+  /**
+   * The [PolymerTagDartElement] part of this Polymer custom tag. Maybe `null` if it has
+   * not been resolved yet or there are no corresponding Dart part defined.
+   */
+  PolymerTagDartElement dartElement;
+
+  /**
+   * The array containing all of the attributes declared by this tag.
+   */
+  List<PolymerAttributeElement> _attributes = PolymerAttributeElement.EMPTY_ARRAY;
+
+  /**
+   * Initialize a newly created HTML part of a Polymer tag to have the given name.
+   *
+   * @param name the name of this element
+   * @param nameOffset the offset of the name of this element in the file that contains the
+   *          declaration of this element
+   */
+  PolymerTagHtmlElementImpl(String name, int nameOffset) : super(name, nameOffset);
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitPolymerTagHtmlElement(this);
+
+  @override
+  List<PolymerAttributeElement> get attributes => _attributes;
+
+  @override
+  ElementKind get kind => ElementKind.POLYMER_TAG_HTML;
+
+  /**
+   * Set an array containing all of the attributes declared by this tag.
+   *
+   * @param attributes the properties to set
+   */
+  void set attributes(List<PolymerAttributeElement> attributes) {
+    for (PolymerAttributeElement property in attributes) {
+      encloseElement(property as PolymerAttributeElementImpl);
+    }
+    this._attributes = attributes;
+  }
+
+  @override
+  void visitChildren(ElementVisitor visitor) {
+    safelyVisitChildren(_attributes, visitor);
+    super.visitChildren(visitor);
+  }
+}
+
+/**
  * The unique instance of the class `BottomTypeImpl` implements the type `bottom`.
  */
 class BottomTypeImpl extends TypeImpl {
@@ -8140,12 +8495,10 @@
     if (secondTypes.length != firstTypes.length) {
       return false;
     }
-    JavaIterator<MapEntry<String, DartType>> firstIterator = new JavaIterator(getMapEntrySet(firstTypes));
-    JavaIterator<MapEntry<String, DartType>> secondIterator = new JavaIterator(getMapEntrySet(secondTypes));
-    while (firstIterator.hasNext) {
-      MapEntry<String, DartType> firstEntry = firstIterator.next();
-      MapEntry<String, DartType> secondEntry = secondIterator.next();
-      if (firstEntry.getKey() != secondEntry.getKey() || !(firstEntry.getValue() as TypeImpl).internalEquals(secondEntry.getValue(), visitedElementPairs)) {
+    MapIterator<String, DartType> firstIterator = SingleMapIterator.forMap(firstTypes);
+    MapIterator<String, DartType> secondIterator = SingleMapIterator.forMap(secondTypes);
+    while (firstIterator.moveNext() && secondIterator.moveNext()) {
+      if (firstIterator.key != secondIterator.key || !(firstIterator.value as TypeImpl).internalEquals(secondIterator.value, visitedElementPairs)) {
         return false;
       }
     }
@@ -8221,15 +8574,15 @@
           needsComma = false;
         }
         builder.append("{");
-        for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterTypes)) {
+        for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(namedParameterTypes); iter.moveNext();) {
           if (needsComma) {
             builder.append(", ");
           } else {
             needsComma = true;
           }
-          builder.append(entry.getKey());
+          builder.append(iter.key);
           builder.append(": ");
-          builder.append(entry.getValue().displayName);
+          builder.append(iter.value.displayName);
         }
         builder.append("}");
         needsComma = true;
@@ -8400,14 +8753,13 @@
       }
       // Loop through each element in S verifying that T has a matching parameter name and that the
       // corresponding type is more specific then the type in S.
-      JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
-      while (iteratorS.hasNext) {
-        MapEntry<String, DartType> entryS = iteratorS.next();
-        DartType typeT = namedTypesT[entryS.getKey()];
+      MapIterator<String, DartType> iteratorS = SingleMapIterator.forMap(namedTypesS);
+      while (iteratorS.moveNext()) {
+        DartType typeT = namedTypesT[iteratorS.key];
         if (typeT == null) {
           return false;
         }
-        if (!(typeT as TypeImpl).isMoreSpecificThan2(entryS.getValue(), withDynamic, visitedTypePairs)) {
+        if (!(typeT as TypeImpl).isMoreSpecificThan2(iteratorS.value, withDynamic, visitedTypePairs)) {
           return false;
         }
       }
@@ -8520,15 +8872,15 @@
         needsComma = false;
       }
       builder.append("{");
-      for (MapEntry<String, DartType> entry in getMapEntrySet(namedParameterTypes)) {
+      for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(namedParameterTypes); iter.moveNext();) {
         if (needsComma) {
           builder.append(", ");
         } else {
           needsComma = true;
         }
-        builder.append(entry.getKey());
+        builder.append(iter.key);
         builder.append(": ");
-        (entry.getValue() as TypeImpl).appendTo(builder);
+        (iter.value as TypeImpl).appendTo(builder);
       }
       builder.append("}");
       needsComma = true;
@@ -8616,14 +8968,13 @@
       }
       // Loop through each element in S verifying that T has a matching parameter name and that the
       // corresponding type is assignable to the type in S.
-      JavaIterator<MapEntry<String, DartType>> iteratorS = new JavaIterator(getMapEntrySet(namedTypesS));
-      while (iteratorS.hasNext) {
-        MapEntry<String, DartType> entryS = iteratorS.next();
-        DartType typeT = namedTypesT[entryS.getKey()];
+      MapIterator<String, DartType> iteratorS = SingleMapIterator.forMap(namedTypesS);
+      while (iteratorS.moveNext()) {
+        DartType typeT = namedTypesT[iteratorS.key];
         if (typeT == null) {
           return false;
         }
-        if (!(typeT as TypeImpl).isAssignableTo2(entryS.getValue(), visitedTypePairs)) {
+        if (!(typeT as TypeImpl).isAssignableTo2(iteratorS.value, visitedTypePairs)) {
           return false;
         }
       }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index b16d920..18d00f7 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -827,6 +827,13 @@
   bool get analyzeFunctionBodies;
 
   /**
+   * Return `true` if analysis is to analyze Polymer.
+   *
+   * @return `true` if analysis is to analyze Polymer
+   */
+  bool get analyzePolymer;
+
+  /**
    * Return the maximum number of sources for which AST structures should be kept in the cache.
    *
    * @return the maximum number of sources for which AST structures should be kept in the cache
@@ -1186,14 +1193,6 @@
   }
 
   /**
-   * Return a collection containing all of the map entries mapping sources to cache entries. Clients
-   * should not modify the returned collection.
-   *
-   * @return a collection containing all of the map entries mapping sources to cache entries
-   */
-  Iterable<MapEntry<Source, SourceEntry>> entrySet() => getMapEntrySet(_sourceMap);
-
-  /**
    * Return the entry associated with the given source.
    *
    * @param source the source whose entry is to be returned
@@ -1202,6 +1201,13 @@
   SourceEntry get(Source source) => _sourceMap[source];
 
   /**
+   * Return an iterator returning all of the map entries mapping sources to cache entries.
+   *
+   * @return an iterator returning all of the map entries mapping sources to cache entries
+   */
+  MapIterator<Source, SourceEntry> iterator() => new SingleMapIterator<Source, SourceEntry>(_sourceMap);
+
+  /**
    * Associate the given entry with the given source.
    *
    * @param source the source with which the entry is to be associated
@@ -1402,6 +1408,11 @@
   static final DataDescriptor<List<AnalysisError>> ANGULAR_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.ANGULAR_ERRORS");
 
   /**
+   * The data descriptor representing the errors reported while building an element model.
+   */
+  static final DataDescriptor<List<AnalysisError>> BUILD_ELEMENT_ERRORS = new DataDescriptor<List<AnalysisError>>("DartEntry.BUILD_ELEMENT_ERRORS");
+
+  /**
    * The data descriptor representing the list of libraries that contain this compilation unit.
    */
   static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES = new DataDescriptor<List<Source>>("DartEntry.CONTAINING_LIBRARIES");
@@ -1757,6 +1768,7 @@
     ListUtilities.addAll(errors, _parseErrors);
     DartEntryImpl_ResolutionState state = _resolutionState;
     while (state != null) {
+      ListUtilities.addAll(errors, state._buildElementErrors);
       ListUtilities.addAll(errors, state._resolutionErrors);
       ListUtilities.addAll(errors, state._verificationErrors);
       ListUtilities.addAll(errors, state._hints);
@@ -1880,7 +1892,9 @@
     DartEntryImpl_ResolutionState state = _resolutionState;
     while (state != null) {
       if (librarySource == state._librarySource) {
-        if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+        if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+          return state._buildElementErrorsState;
+        } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
           return state._resolutionErrorsState;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
           return state._resolvedUnitState;
@@ -1895,7 +1909,7 @@
       state = state._nextState;
     }
     ;
-    if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+    if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
       return CacheState.INVALID;
     } else {
       throw new IllegalArgumentException("Invalid descriptor: ${descriptor}");
@@ -1942,7 +1956,9 @@
     DartEntryImpl_ResolutionState state = _resolutionState;
     while (state != null) {
       if (librarySource == state._librarySource) {
-        if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+        if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+          return state._buildElementErrors;
+        } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
           return state._resolutionErrors;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
           return state._resolvedUnit;
@@ -1957,7 +1973,7 @@
       state = state._nextState;
     }
     ;
-    if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+    if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
       return AnalysisError.NO_ERRORS;
     } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
       return null;
@@ -1999,10 +2015,12 @@
       return _sourceKindState == CacheState.INVALID;
     } else if (identical(descriptor, DartEntry.TOKEN_STREAM)) {
       return _tokenStreamState == CacheState.INVALID;
-    } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
+    } else if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS) || identical(descriptor, DartEntry.RESOLUTION_ERRORS) || identical(descriptor, DartEntry.RESOLVED_UNIT) || identical(descriptor, DartEntry.VERIFICATION_ERRORS) || identical(descriptor, DartEntry.HINTS)) {
       DartEntryImpl_ResolutionState state = _resolutionState;
       while (state != null) {
-        if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+        if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+          return state._buildElementErrorsState == CacheState.INVALID;
+        } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
           return state._resolutionErrorsState == CacheState.INVALID;
         } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
           return state._resolvedUnitState == CacheState.INVALID;
@@ -2361,7 +2379,10 @@
    */
   void setStateInLibrary(DataDescriptor descriptor, Source librarySource, CacheState cacheState) {
     DartEntryImpl_ResolutionState state = _getOrCreateResolutionState(librarySource);
-    if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+    if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+      state._buildElementErrors = updatedValue(cacheState, state._buildElementErrors, AnalysisError.NO_ERRORS);
+      state._buildElementErrorsState = cacheState;
+    } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
       state._resolutionErrors = updatedValue(cacheState, state._resolutionErrors, AnalysisError.NO_ERRORS);
       state._resolutionErrorsState = cacheState;
     } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -2435,7 +2456,10 @@
    */
   void setValueInLibrary(DataDescriptor descriptor, Source librarySource, Object value) {
     DartEntryImpl_ResolutionState state = _getOrCreateResolutionState(librarySource);
-    if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
+    if (identical(descriptor, DartEntry.BUILD_ELEMENT_ERRORS)) {
+      state._buildElementErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
+      state._buildElementErrorsState = CacheState.VALID;
+    } else if (identical(descriptor, DartEntry.RESOLUTION_ERRORS)) {
       state._resolutionErrors = value == null ? AnalysisError.NO_ERRORS : (value as List<AnalysisError>);
       state._resolutionErrorsState = CacheState.VALID;
     } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
@@ -2595,6 +2619,17 @@
   Source _librarySource;
 
   /**
+   * The state of the cached errors reported while building an element model.
+   */
+  CacheState _buildElementErrorsState = CacheState.INVALID;
+
+  /**
+   * The errors produced while building an element model, or an empty array if the errors are not
+   * currently cached.
+   */
+  List<AnalysisError> _buildElementErrors = AnalysisError.NO_ERRORS;
+
+  /**
    * The state of the cached resolved compilation unit.
    */
   CacheState _resolvedUnitState = CacheState.INVALID;
@@ -2646,6 +2681,8 @@
    */
   void copyFrom(DartEntryImpl_ResolutionState other) {
     _librarySource = other._librarySource;
+    _buildElementErrorsState = other._buildElementErrorsState;
+    _buildElementErrors = other._buildElementErrors;
     _resolvedUnitState = other._resolvedUnitState;
     _resolvedUnit = other._resolvedUnit;
     _resolutionErrorsState = other._resolutionErrorsState;
@@ -2673,7 +2710,7 @@
     }
   }
 
-  bool get hasErrorState => _resolvedUnitState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _verificationErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || (_nextState != null && _nextState.hasErrorState);
+  bool get hasErrorState => _buildElementErrorsState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _verificationErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || (_nextState != null && _nextState.hasErrorState);
 
   /**
    * Invalidate all of the resolution information associated with the compilation unit.
@@ -2681,6 +2718,8 @@
   void invalidateAllResolutionInformation() {
     _nextState = null;
     _librarySource = null;
+    _buildElementErrorsState = CacheState.INVALID;
+    _buildElementErrors = AnalysisError.NO_ERRORS;
     _resolvedUnitState = CacheState.INVALID;
     _resolvedUnit = null;
     _resolutionErrorsState = CacheState.INVALID;
@@ -2697,6 +2736,8 @@
    * will not change the state of any parse results.
    */
   void recordResolutionError() {
+    _buildElementErrorsState = CacheState.ERROR;
+    _buildElementErrors = AnalysisError.NO_ERRORS;
     _resolvedUnitState = CacheState.ERROR;
     _resolvedUnit = null;
     _resolutionErrorsState = CacheState.ERROR;
@@ -2715,6 +2756,9 @@
    * were invalidated before they could be recorded.
    */
   void recordResolutionNotInProcess() {
+    if (_buildElementErrorsState == CacheState.IN_PROCESS) {
+      _buildElementErrorsState = CacheState.INVALID;
+    }
     if (_resolvedUnitState == CacheState.IN_PROCESS) {
       _resolvedUnitState = CacheState.INVALID;
     }
@@ -2740,6 +2784,8 @@
    */
   void writeOn(JavaStringBuilder builder) {
     if (_librarySource != null) {
+      builder.append("; buildElementErrors = ");
+      builder.append(_buildElementErrorsState);
       builder.append("; resolvedUnit = ");
       builder.append(_resolvedUnitState);
       builder.append("; resolutionErrors = ");
@@ -2840,6 +2886,16 @@
   static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.RESOLUTION_ERRORS");
 
   /**
+   * The data descriptor representing the status of Polymer elements in the source.
+   */
+  static final DataDescriptor<List<AnalysisError>> POLYMER_BUILD_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.POLYMER_BUILD_ERRORS");
+
+  /**
+   * The data descriptor representing the errors reported during Polymer resolution.
+   */
+  static final DataDescriptor<List<AnalysisError>> POLYMER_RESOLUTION_ERRORS = new DataDescriptor<List<AnalysisError>>("HtmlEntry.POLYMER_RESOLUTION_ERRORS");
+
+  /**
    * Return all of the errors associated with the compilation unit that are currently cached.
    *
    * @return all of the errors associated with the compilation unit
@@ -2978,6 +3034,28 @@
   List<AnalysisError> _hints = AnalysisError.NO_ERRORS;
 
   /**
+   * The state of the Polymer elements.
+   */
+  CacheState _polymerBuildErrorsState = CacheState.INVALID;
+
+  /**
+   * The hints produced while performing Polymer HTML elements building, or an empty array if the
+   * error are not currently cached.
+   */
+  List<AnalysisError> _polymerBuildErrors = AnalysisError.NO_ERRORS;
+
+  /**
+   * The state of the Polymer resolution errors.
+   */
+  CacheState _polymerResolutionErrorsState = CacheState.INVALID;
+
+  /**
+   * The hints produced while performing Polymer resolution, or an empty array if the error are not
+   * currently cached.
+   */
+  List<AnalysisError> _polymerResolutionErrors = AnalysisError.NO_ERRORS;
+
+  /**
    * Flush any AST structures being maintained by this entry.
    */
   void flushAstStructures() {
@@ -3020,6 +3098,16 @@
         errors.add(error);
       }
     }
+    if (_polymerBuildErrors != null) {
+      for (AnalysisError error in _polymerBuildErrors) {
+        errors.add(error);
+      }
+    }
+    if (_polymerResolutionErrors != null) {
+      for (AnalysisError error in _polymerResolutionErrors) {
+        errors.add(error);
+      }
+    }
     if (errors.length == 0) {
       return AnalysisError.NO_ERRORS;
     }
@@ -3066,6 +3154,10 @@
       return _resolutionErrorsState;
     } else if (identical(descriptor, HtmlEntry.HINTS)) {
       return _hintsState;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+      return _polymerBuildErrorsState;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+      return _polymerResolutionErrorsState;
     }
     return super.getState(descriptor);
   }
@@ -3094,6 +3186,10 @@
       return _resolutionErrors;
     } else if (identical(descriptor, HtmlEntry.HINTS)) {
       return _hints;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+      return _polymerBuildErrors;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+      return _polymerResolutionErrors;
     }
     return super.getValue(descriptor);
   }
@@ -3127,6 +3223,10 @@
     _angularEntryState = CacheState.INVALID;
     _angularErrors = AnalysisError.NO_ERRORS;
     _angularErrorsState = CacheState.INVALID;
+    _polymerBuildErrors = AnalysisError.NO_ERRORS;
+    _polymerBuildErrorsState = CacheState.INVALID;
+    _polymerResolutionErrors = AnalysisError.NO_ERRORS;
+    _polymerResolutionErrorsState = CacheState.INVALID;
     _element = null;
     _elementState = CacheState.INVALID;
     _resolutionErrors = AnalysisError.NO_ERRORS;
@@ -3163,6 +3263,8 @@
     setState(HtmlEntry.ELEMENT, CacheState.ERROR);
     setState(HtmlEntry.RESOLUTION_ERRORS, CacheState.ERROR);
     setState(HtmlEntry.HINTS, CacheState.ERROR);
+    setState(HtmlEntry.POLYMER_BUILD_ERRORS, CacheState.ERROR);
+    setState(HtmlEntry.POLYMER_RESOLUTION_ERRORS, CacheState.ERROR);
   }
 
   @override
@@ -3200,6 +3302,12 @@
     } else if (identical(descriptor, HtmlEntry.HINTS)) {
       _hints = updatedValue(state, _hints, AnalysisError.NO_ERRORS);
       _hintsState = state;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+      _polymerBuildErrors = updatedValue(state, _polymerBuildErrors, null);
+      _polymerBuildErrorsState = state;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+      _polymerResolutionErrors = updatedValue(state, _polymerResolutionErrors, null);
+      _polymerResolutionErrorsState = state;
     } else {
       super.setState(descriptor, state);
     }
@@ -3240,6 +3348,12 @@
     } else if (identical(descriptor, HtmlEntry.HINTS)) {
       _hints = value as List<AnalysisError>;
       _hintsState = CacheState.VALID;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_BUILD_ERRORS)) {
+      _polymerBuildErrors = value as List<AnalysisError>;
+      _polymerBuildErrorsState = CacheState.VALID;
+    } else if (identical(descriptor, HtmlEntry.POLYMER_RESOLUTION_ERRORS)) {
+      _polymerResolutionErrors = value as List<AnalysisError>;
+      _polymerResolutionErrorsState = CacheState.VALID;
     } else {
       super.setValue(descriptor, value);
     }
@@ -3265,16 +3379,20 @@
     _resolvedUnit = other._resolvedUnit;
     _referencedLibrariesState = other._referencedLibrariesState;
     _referencedLibraries = other._referencedLibraries;
-    _resolutionErrors = other._resolutionErrors;
     _resolutionErrorsState = other._resolutionErrorsState;
+    _resolutionErrors = other._resolutionErrors;
     _elementState = other._elementState;
     _element = other._element;
-    _hints = other._hints;
     _hintsState = other._hintsState;
+    _hints = other._hints;
+    _polymerBuildErrorsState = other._polymerBuildErrorsState;
+    _polymerBuildErrors = other._polymerBuildErrors;
+    _polymerResolutionErrorsState = other._polymerResolutionErrorsState;
+    _polymerResolutionErrors = other._polymerResolutionErrors;
   }
 
   @override
-  bool get hasErrorState => super.hasErrorState || _parsedUnitState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _parseErrorsState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _referencedLibrariesState == CacheState.ERROR || _elementState == CacheState.ERROR || _angularErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR;
+  bool get hasErrorState => super.hasErrorState || _parsedUnitState == CacheState.ERROR || _resolvedUnitState == CacheState.ERROR || _parseErrorsState == CacheState.ERROR || _resolutionErrorsState == CacheState.ERROR || _referencedLibrariesState == CacheState.ERROR || _elementState == CacheState.ERROR || _angularErrorsState == CacheState.ERROR || _hintsState == CacheState.ERROR || _polymerBuildErrorsState == CacheState.ERROR || _polymerResolutionErrorsState == CacheState.ERROR;
 
   @override
   void writeOn(JavaStringBuilder builder) {
@@ -3300,6 +3418,10 @@
     builder.append(_angularEntryState);
     builder.append("; angularErrors = ");
     builder.append(_angularErrorsState);
+    builder.append("; polymerBuildErrors = ");
+    builder.append(_polymerBuildErrorsState);
+    builder.append("; polymerResolutionErrors = ");
+    builder.append(_polymerResolutionErrorsState);
   }
 }
 
@@ -3940,9 +4062,10 @@
       // only re-analyze those libraries.
       //        logInformation("Added Dart sources, invalidating all resolution information");
       List<Source> sourcesToInvalidate = new List<Source>();
-      for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
-        Source source = mapEntry.getKey();
-        SourceEntry sourceEntry = mapEntry.getValue();
+      MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+      while (iterator.moveNext()) {
+        Source source = iterator.key;
+        SourceEntry sourceEntry = iterator.value;
         if (!source.isInSystemLibrary && sourceEntry is DartEntry) {
           sourcesToInvalidate.add(source);
         }
@@ -4134,11 +4257,13 @@
   InternalAnalysisContext extractContextInto(SourceContainer container, InternalAnalysisContext newContext) {
     List<Source> sourcesToRemove = new List<Source>();
     // Move sources in the specified directory to the new context
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      Source source = entry.getKey();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
+      SourceEntry sourceEntry = iterator.value;
       if (container.contains(source)) {
         sourcesToRemove.add(source);
-        newContext.addSourceInfo(source, entry.getValue().writableCopy);
+        newContext.addSourceInfo(source, sourceEntry.writableCopy);
       }
     }
     return newContext;
@@ -4241,12 +4366,13 @@
       if (sourceKind == SourceKind.LIBRARY) {
       } else if (sourceKind == SourceKind.PART) {
         List<Source> librarySources = getLibrariesContaining(source);
-        for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-          SourceEntry sourceEntry = entry.getValue();
+        MapIterator<Source, SourceEntry> partIterator = _cache.iterator();
+        while (partIterator.moveNext()) {
+          SourceEntry sourceEntry = partIterator.value;
           if (sourceEntry.kind == SourceKind.HTML) {
             List<Source> referencedLibraries = (sourceEntry as HtmlEntry).getValue(HtmlEntry.REFERENCED_LIBRARIES);
             if (_containsAny(referencedLibraries, librarySources)) {
-              htmlSources.add(entry.getKey());
+              htmlSources.add(partIterator.key);
             }
           }
         }
@@ -4276,9 +4402,10 @@
     // TODO(brianwilkerson) This needs to filter out libraries that do not reference dart:html,
     // either directly or indirectly.
     List<Source> sources = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      Source source = entry.getKey();
-      SourceEntry sourceEntry = entry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
+      SourceEntry sourceEntry = iterator.value;
       if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
         //          DartEntry dartEntry = (DartEntry) sourceEntry;
         //          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
@@ -4293,9 +4420,10 @@
     // TODO(brianwilkerson) This needs to filter out libraries that reference dart:html, either
     // directly or indirectly.
     List<Source> sources = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      Source source = entry.getKey();
-      SourceEntry sourceEntry = entry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
+      SourceEntry sourceEntry = iterator.value;
       if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
         //          DartEntry dartEntry = (DartEntry) sourceEntry;
         //          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
@@ -4317,14 +4445,15 @@
   @override
   List<Source> getLibrariesDependingOn(Source librarySource) {
     List<Source> dependentLibraries = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      SourceEntry sourceEntry = entry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      SourceEntry sourceEntry = iterator.value;
       if (sourceEntry.kind == SourceKind.LIBRARY) {
         if (_contains((sourceEntry as DartEntry).getValue(DartEntry.EXPORTED_LIBRARIES), librarySource)) {
-          dependentLibraries.add(entry.getKey());
+          dependentLibraries.add(iterator.key);
         }
         if (_contains((sourceEntry as DartEntry).getValue(DartEntry.IMPORTED_LIBRARIES), librarySource)) {
-          dependentLibraries.add(entry.getKey());
+          dependentLibraries.add(iterator.key);
         }
       }
     }
@@ -4407,11 +4536,12 @@
   @override
   List<Source> get refactoringUnsafeSources {
     List<Source> sources = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      SourceEntry sourceEntry = entry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      SourceEntry sourceEntry = iterator.value;
       if (sourceEntry is DartEntry) {
         if (!sourceEntry.isRefactoringSafe) {
-          sources.add(entry.getKey());
+          sources.add(iterator.key);
         }
       }
     }
@@ -4467,8 +4597,9 @@
     //
     // Look for non-priority sources that need to be analyzed.
     //
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      _getSourcesNeedingProcessing(entry.getKey(), entry.getValue(), false, hintsEnabled, sources);
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      _getSourcesNeedingProcessing(iterator.key, iterator.value, false, hintsEnabled, sources);
     }
     return new List<Source>.from(sources);
   }
@@ -4477,12 +4608,12 @@
   AnalysisContentStatistics get statistics {
     bool hintsEnabled = _options.hint;
     AnalysisContentStatisticsImpl statistics = new AnalysisContentStatisticsImpl();
-    for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
-      statistics.addSource(mapEntry.getKey());
-      SourceEntry entry = mapEntry.getValue();
-      if (entry is DartEntry) {
-        Source source = mapEntry.getKey();
-        DartEntry dartEntry = entry;
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      SourceEntry sourceEntry = iterator.value;
+      if (sourceEntry is DartEntry) {
+        Source source = iterator.key;
+        DartEntry dartEntry = sourceEntry;
         SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
         // get library independent values
         statistics.putCacheItem(dartEntry, SourceEntry.LINE_INFO);
@@ -4509,8 +4640,8 @@
             }
           }
         }
-      } else if (entry is HtmlEntry) {
-        HtmlEntry htmlEntry = entry;
+      } else if (sourceEntry is HtmlEntry) {
+        HtmlEntry htmlEntry = sourceEntry;
         statistics.putCacheItem(htmlEntry, SourceEntry.LINE_INFO);
         statistics.putCacheItem(htmlEntry, HtmlEntry.PARSE_ERRORS);
         statistics.putCacheItem(htmlEntry, HtmlEntry.PARSED_UNIT);
@@ -4559,12 +4690,13 @@
       return;
     }
     // TODO(brianwilkerson) This does not lock against the other context's cacheLock.
-    for (MapEntry<Source, SourceEntry> entry in (context as AnalysisContextImpl)._cache.entrySet()) {
-      Source newSource = entry.getKey();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source newSource = iterator.key;
       SourceEntry existingEntry = _getReadableSourceEntry(newSource);
       if (existingEntry == null) {
         // TODO(brianwilkerson) Decide whether we really need to copy the info.
-        _cache.put(newSource, entry.getValue().writableCopy);
+        _cache.put(newSource, iterator.value.writableCopy);
       } else {
       }
     }
@@ -4619,16 +4751,16 @@
   @override
   void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
     Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
-    for (MapEntry<Source, LibraryElement> entry in getMapEntrySet(elementMap)) {
-      Source librarySource = entry.getKey();
-      LibraryElement library = entry.getValue();
+    for (MapIterator<Source, LibraryElement> iter = SingleMapIterator.forMap(elementMap); iter.moveNext();) {
+      Source librarySource = iter.key;
+      LibraryElement library = iter.value;
       //
       // Cache the element in the library's info.
       //
       DartEntry dartEntry = _getReadableDartEntry(librarySource);
       if (dartEntry != null) {
         DartEntryImpl dartCopy = dartEntry.writableCopy;
-        _recordElementData(dartEntry, dartCopy, library, library.source, htmlSource);
+        _recordElementData(dartCopy, library, library.source, htmlSource);
         _cache.put(librarySource, dartCopy);
       }
     }
@@ -4813,24 +4945,14 @@
             CompilationUnit unit = library.getAST(source);
             List<AnalysisError> errors = errorListener.getErrorsForSource(source);
             LineInfo lineInfo = getLineInfo(source);
-            DartEntry dartEntry = _cache.get(source) as DartEntry;
-            int sourceTime = getModificationStamp(source);
-            if (dartEntry.modificationTime != sourceTime) {
-              // The source has changed without the context being notified. Simulate notification.
-              _sourceChanged(source);
-              dartEntry = _getReadableDartEntry(source);
-              if (dartEntry == null) {
-                throw new AnalysisException.con1("A Dart file became a non-Dart file: ${source.fullName}");
-              }
-            }
-            DartEntryImpl dartCopy = dartEntry.writableCopy;
+            DartEntryImpl dartCopy = _cache.get(source).writableCopy as DartEntryImpl;
             if (thrownException == null) {
               dartCopy.setValue(SourceEntry.LINE_INFO, lineInfo);
               dartCopy.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
               dartCopy.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
               dartCopy.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
               if (source == librarySource) {
-                _recordElementData(dartEntry, dartCopy, library.libraryElement, librarySource, htmlSource);
+                _recordElementData(dartCopy, library.libraryElement, librarySource, htmlSource);
               }
               _cache.storedAst(source);
             } else {
@@ -4955,7 +5077,7 @@
               dartCopy.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
               dartCopy.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource, errors);
               if (source == librarySource) {
-                _recordElementData(dartEntry, dartCopy, library.libraryElement, librarySource, htmlSource);
+                _recordElementData(dartCopy, library.libraryElement, librarySource, htmlSource);
               }
               _cache.storedAst(source);
             } else {
@@ -5044,8 +5166,9 @@
    * @param container the source container containing the sources to be added to the list
    */
   void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      Source source = entry.getKey();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
       if (container.contains(source)) {
         sources.add(source);
       }
@@ -5536,6 +5659,42 @@
   }
 
   /**
+   * Create a [PolymerBuildHtmlTask] for the given source, marking the Polymer elements as
+   * being in-process.
+   *
+   * @param source the source whose content is to be processed
+   * @param htmlEntry the entry for the source
+   * @return task data representing the created task
+   */
+  AnalysisContextImpl_TaskData _createPolymerBuildHtmlTask(Source source, HtmlEntry htmlEntry) {
+    if (htmlEntry.getState(HtmlEntry.RESOLVED_UNIT) != CacheState.VALID) {
+      return _createResolveHtmlTask(source, htmlEntry);
+    }
+    HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+    htmlCopy.setState(HtmlEntry.POLYMER_BUILD_ERRORS, CacheState.IN_PROCESS);
+    _cache.put(source, htmlCopy);
+    return new AnalysisContextImpl_TaskData(new PolymerBuildHtmlTask(this, source, htmlCopy.modificationTime, htmlEntry.getValue(SourceEntry.LINE_INFO), htmlCopy.getValue(HtmlEntry.RESOLVED_UNIT)), false);
+  }
+
+  /**
+   * Create a [PolymerResolveHtmlTask] for the given source, marking the Polymer errors as
+   * being in-process.
+   *
+   * @param source the source whose content is to be resolved
+   * @param htmlEntry the entry for the source
+   * @return task data representing the created task
+   */
+  AnalysisContextImpl_TaskData _createPolymerResolveHtmlTask(Source source, HtmlEntry htmlEntry) {
+    if (htmlEntry.getState(HtmlEntry.RESOLVED_UNIT) != CacheState.VALID) {
+      return _createResolveHtmlTask(source, htmlEntry);
+    }
+    HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+    htmlCopy.setState(HtmlEntry.POLYMER_RESOLUTION_ERRORS, CacheState.IN_PROCESS);
+    _cache.put(source, htmlCopy);
+    return new AnalysisContextImpl_TaskData(new PolymerResolveHtmlTask(this, source, htmlCopy.modificationTime, htmlEntry.getValue(SourceEntry.LINE_INFO), htmlCopy.getValue(HtmlEntry.RESOLVED_UNIT)), false);
+  }
+
+  /**
    * Create a [ResolveAngularComponentTemplateTask] for the given source, marking the angular
    * errors as being in-process.
    *
@@ -6182,6 +6341,21 @@
           return _createResolveAngularComponentTemplateTask(source, htmlEntry);
         }
       }
+      //
+      // Polymer support
+      //
+      if (_options.analyzePolymer) {
+        // Build elements.
+        CacheState polymerBuildErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_BUILD_ERRORS);
+        if (polymerBuildErrorsState == CacheState.INVALID || (isPriority && polymerBuildErrorsState == CacheState.FLUSHED)) {
+          return _createPolymerBuildHtmlTask(source, htmlEntry);
+        }
+        // Resolve references.
+        CacheState polymerResolutionErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_RESOLUTION_ERRORS);
+        if (polymerResolutionErrorsState == CacheState.INVALID || (isPriority && polymerResolutionErrorsState == CacheState.FLUSHED)) {
+          return _createPolymerResolveHtmlTask(source, htmlEntry);
+        }
+      }
     }
     return new AnalysisContextImpl_TaskData(null, false);
   }
@@ -6287,9 +6461,10 @@
    */
   List<Source> _getSources(SourceKind kind) {
     List<Source> sources = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      if (entry.getValue().kind == kind) {
-        sources.add(entry.getKey());
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      if (iterator.value.kind == kind) {
+        sources.add(iterator.key);
       }
     }
     return new List.from(sources);
@@ -6396,6 +6571,19 @@
           }
         }
       }
+      // Polymer
+      if (_options.analyzePolymer) {
+        // Elements building.
+        CacheState polymerBuildErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_BUILD_ERRORS);
+        if (polymerBuildErrorsState == CacheState.INVALID || (isPriority && polymerBuildErrorsState == CacheState.FLUSHED)) {
+          sources.add(source);
+        }
+        // Resolution.
+        CacheState polymerResolutionErrorsState = htmlEntry.getState(HtmlEntry.POLYMER_RESOLUTION_ERRORS);
+        if (polymerResolutionErrorsState == CacheState.INVALID || (isPriority && polymerResolutionErrorsState == CacheState.FLUSHED)) {
+          sources.add(source);
+        }
+      }
     }
   }
 
@@ -6406,19 +6594,20 @@
    */
   void _invalidateAllResolutionInformation() {
     Map<Source, List<Source>> oldPartMap = new Map<Source, List<Source>>();
-    for (MapEntry<Source, SourceEntry> mapEntry in _cache.entrySet()) {
-      Source source = mapEntry.getKey();
-      SourceEntry sourceEntry = mapEntry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
+      SourceEntry sourceEntry = iterator.value;
       if (sourceEntry is HtmlEntry) {
         HtmlEntryImpl htmlCopy = sourceEntry.writableCopy;
         htmlCopy.invalidateAllResolutionInformation();
-        mapEntry.setValue(htmlCopy);
+        iterator.value = htmlCopy;
       } else if (sourceEntry is DartEntry) {
         DartEntry dartEntry = sourceEntry;
         oldPartMap[source] = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
         DartEntryImpl dartCopy = dartEntry.writableCopy;
         dartCopy.invalidateAllResolutionInformation();
-        mapEntry.setValue(dartCopy);
+        iterator.value = dartCopy;
         _workManager.add(source, SourcePriority.UNKNOWN);
       }
     }
@@ -6618,16 +6807,112 @@
   }
 
   /**
+   * Record the results produced by performing a [BuildDartElementModelTask]. If the results
+   * were computed from data that is now out-of-date, then the results will not be recorded.
+   *
+   * @param task the task that was performed
+   * @return an entry containing the recorded results
+   * @throws AnalysisException if the results could not be recorded
+   */
+  DartEntry _recordBuildDartElementModelTask(BuildDartElementModelTask task) {
+    Source targetLibrary = task.targetLibrary;
+    List<ResolvableLibrary> builtLibraries = task.librariesInCycle;
+    AnalysisException thrownException = task.exception;
+    DartEntry targetEntry = null;
+    if (_allModificationTimesMatch(builtLibraries)) {
+      Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
+      RecordingErrorListener errorListener = task.errorListener;
+      for (ResolvableLibrary library in builtLibraries) {
+        Source librarySource = library.librarySource;
+        for (Source source in library.compilationUnitSources) {
+          CompilationUnit unit = library.getAST(source);
+          List<AnalysisError> errors = errorListener.getErrorsForSource(source);
+          LineInfo lineInfo = getLineInfo(source);
+          DartEntryImpl dartCopy = _cache.get(source).writableCopy as DartEntryImpl;
+          if (thrownException == null) {
+            dartCopy.setValueInLibrary(DartEntry.BUILD_ELEMENT_ERRORS, librarySource, errors);
+            if (source == librarySource) {
+              LibraryElementImpl libraryElement = library.libraryElement;
+              dartCopy.setValue(DartEntry.ELEMENT, libraryElement);
+              dartCopy.setValue(DartEntry.IS_LAUNCHABLE, libraryElement.entryPoint != null);
+              dartCopy.setValue(DartEntry.IS_CLIENT, _isClient(libraryElement, htmlSource, new Set<LibraryElement>()));
+            }
+          } else {
+            dartCopy.recordResolutionError();
+            _cache.remove(source);
+          }
+          dartCopy.exception = thrownException;
+          _cache.put(source, dartCopy);
+          if (source != librarySource) {
+            _workManager.add(librarySource, SourcePriority.PRIORITY_PART);
+          }
+          if (source == targetLibrary) {
+            targetEntry = dartCopy;
+          }
+          ChangeNoticeImpl notice = _getNotice(source);
+          notice.compilationUnit = unit;
+          notice.setErrors(dartCopy.allErrors, lineInfo);
+        }
+      }
+    } else {
+      PrintStringWriter writer = new PrintStringWriter();
+      writer.println("Build element model results discarded for");
+      for (ResolvableLibrary library in builtLibraries) {
+        for (Source source in library.compilationUnitSources) {
+          DartEntry dartEntry = _getReadableDartEntry(source);
+          if (dartEntry != null) {
+            int resultTime = library.getModificationTime(source);
+            writer.println("  ${_debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, resultTime = ${resultTime}, cacheTime = ${dartEntry.modificationTime}");
+            DartEntryImpl dartCopy = dartEntry.writableCopy;
+            if (thrownException == null || resultTime >= 0) {
+              //
+              // The analysis was performed on out-of-date sources. Mark the cache so that the
+              // sources will be re-analyzed using the up-to-date sources.
+              //
+              dartCopy.recordResolutionNotInProcess();
+            } else {
+              //
+              // We could not determine whether the sources were up-to-date or out-of-date. Mark
+              // the cache so that we won't attempt to re-analyze the sources until there's a
+              // good chance that we'll be able to do so without error.
+              //
+              dartCopy.recordResolutionError();
+              _cache.remove(source);
+            }
+            dartCopy.exception = thrownException;
+            _cache.put(source, dartCopy);
+            if (source == targetLibrary) {
+              targetEntry = dartCopy;
+            }
+          } else {
+            writer.println("  ${_debuggingString(source)}; sourceTime = ${getModificationStamp(source)}, no entry");
+          }
+        }
+      }
+      _logInformation(writer.toString());
+    }
+    if (thrownException != null) {
+      throw thrownException;
+    }
+    if (targetEntry == null) {
+      targetEntry = _getReadableDartEntry(targetLibrary);
+      if (targetEntry == null) {
+        throw new AnalysisException.con1("A Dart file became a non-Dart file: ${targetLibrary.fullName}");
+      }
+    }
+    return targetEntry;
+  }
+
+  /**
    * Given a cache entry and a library element, record the library element and other information
    * gleaned from the element in the cache entry.
    *
-   * @param dartEntry the original cache entry from which the copy was made
    * @param dartCopy the cache entry in which data is to be recorded
    * @param library the library element used to record information
    * @param librarySource the source for the library used to record information
    * @param htmlSource the source for the HTML library
    */
-  void _recordElementData(DartEntry dartEntry, DartEntryImpl dartCopy, LibraryElement library, Source librarySource, Source htmlSource) {
+  void _recordElementData(DartEntryImpl dartCopy, LibraryElement library, Source librarySource, Source htmlSource) {
     dartCopy.setValue(DartEntry.ELEMENT, library);
     dartCopy.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
     dartCopy.setValue(DartEntry.IS_CLIENT, _isClient(library, htmlSource, new Set<LibraryElement>()));
@@ -6742,9 +7027,9 @@
       _cache.put(librarySource, dartCopy);
       throw thrownException;
     }
-    for (MapEntry<Source, TimestampedData<List<AnalysisError>>> entry in getMapEntrySet(hintMap)) {
-      Source unitSource = entry.getKey();
-      TimestampedData<List<AnalysisError>> results = entry.getValue();
+    for (MapIterator<Source, TimestampedData<List<AnalysisError>>> iter = SingleMapIterator.forMap(hintMap); iter.moveNext();) {
+      Source unitSource = iter.key;
+      TimestampedData<List<AnalysisError>> results = iter.value;
       SourceEntry sourceEntry = _cache.get(unitSource);
       if (sourceEntry is! DartEntry) {
         // This shouldn't be possible because we should never have performed the task if the source
@@ -7075,6 +7360,148 @@
   }
 
   /**
+   * Record the results produced by performing a [PolymerBuildHtmlTask]. If the results were
+   * computed from data that is now out-of-date, then the results will not be recorded.
+   *
+   * @param task the task that was performed
+   * @throws AnalysisException if the results could not be recorded
+   */
+  HtmlEntry _recordPolymerBuildHtmlTaskResults(PolymerBuildHtmlTask task) {
+    Source source = task.source;
+    AnalysisException thrownException = task.exception;
+    HtmlEntry htmlEntry = null;
+    SourceEntry sourceEntry = _cache.get(source);
+    if (sourceEntry == null) {
+      throw new ObsoleteSourceAnalysisException(source);
+    } else if (sourceEntry is! HtmlEntry) {
+      // This shouldn't be possible because we should never have performed the task if the source
+      // didn't represent an HTML file, but check to be safe.
+      throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}");
+    }
+    htmlEntry = sourceEntry as HtmlEntry;
+    int sourceTime = getModificationStamp(source);
+    int resultTime = task.modificationTime;
+    if (sourceTime == resultTime) {
+      if (htmlEntry.modificationTime != sourceTime) {
+        // The source has changed without the context being notified. Simulate notification.
+        _sourceChanged(source);
+        htmlEntry = _getReadableHtmlEntry(source);
+        if (htmlEntry == null) {
+          throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+        }
+      }
+      HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+      if (thrownException == null) {
+        htmlCopy.setValue(HtmlEntry.POLYMER_BUILD_ERRORS, task.errors);
+        // notify about errors
+        ChangeNoticeImpl notice = _getNotice(source);
+        notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
+      } else {
+        htmlCopy.recordResolutionError();
+      }
+      htmlCopy.exception = thrownException;
+      _cache.put(source, htmlCopy);
+      htmlEntry = htmlCopy;
+    } else {
+      HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+      if (thrownException == null || resultTime >= 0) {
+        //
+        // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+        // will be re-analyzed using the up-to-date sources.
+        //
+        htmlCopy.invalidateAllInformation();
+        htmlCopy.modificationTime = sourceTime;
+        _cache.removedAst(source);
+      } else {
+        //
+        // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+        // cache so that we won't attempt to re-analyze the sources until there's a good chance
+        // that we'll be able to do so without error.
+        //
+        htmlCopy.recordResolutionError();
+      }
+      htmlCopy.exception = thrownException;
+      _cache.put(source, htmlCopy);
+      htmlEntry = htmlCopy;
+    }
+    if (thrownException != null) {
+      throw thrownException;
+    }
+    return htmlEntry;
+  }
+
+  /**
+   * Record the results produced by performing a [PolymerResolveHtmlTask]. If the results were
+   * computed from data that is now out-of-date, then the results will not be recorded.
+   *
+   * @param task the task that was performed
+   * @throws AnalysisException if the results could not be recorded
+   */
+  HtmlEntry _recordPolymerResolveHtmlTaskResults(PolymerResolveHtmlTask task) {
+    Source source = task.source;
+    AnalysisException thrownException = task.exception;
+    HtmlEntry htmlEntry = null;
+    SourceEntry sourceEntry = _cache.get(source);
+    if (sourceEntry == null) {
+      throw new ObsoleteSourceAnalysisException(source);
+    } else if (sourceEntry is! HtmlEntry) {
+      // This shouldn't be possible because we should never have performed the task if the source
+      // didn't represent an HTML file, but check to be safe.
+      throw new AnalysisException.con1("Internal error: attempting to resolve non-HTML file as an HTML file: ${source.fullName}");
+    }
+    htmlEntry = sourceEntry as HtmlEntry;
+    int sourceTime = getModificationStamp(source);
+    int resultTime = task.modificationTime;
+    if (sourceTime == resultTime) {
+      if (htmlEntry.modificationTime != sourceTime) {
+        // The source has changed without the context being notified. Simulate notification.
+        _sourceChanged(source);
+        htmlEntry = _getReadableHtmlEntry(source);
+        if (htmlEntry == null) {
+          throw new AnalysisException.con1("An HTML file became a non-HTML file: ${source.fullName}");
+        }
+      }
+      HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+      if (thrownException == null) {
+        htmlCopy.setValue(HtmlEntry.POLYMER_RESOLUTION_ERRORS, task.errors);
+        // notify about errors
+        ChangeNoticeImpl notice = _getNotice(source);
+        notice.setErrors(htmlCopy.allErrors, htmlCopy.getValue(SourceEntry.LINE_INFO));
+      } else {
+        htmlCopy.recordResolutionError();
+      }
+      htmlCopy.exception = thrownException;
+      _cache.put(source, htmlCopy);
+      htmlEntry = htmlCopy;
+    } else {
+      HtmlEntryImpl htmlCopy = htmlEntry.writableCopy;
+      if (thrownException == null || resultTime >= 0) {
+        //
+        // The analysis was performed on out-of-date sources. Mark the cache so that the sources
+        // will be re-analyzed using the up-to-date sources.
+        //
+        htmlCopy.invalidateAllInformation();
+        htmlCopy.modificationTime = sourceTime;
+        _cache.removedAst(source);
+      } else {
+        //
+        // We could not determine whether the sources were up-to-date or out-of-date. Mark the
+        // cache so that we won't attempt to re-analyze the sources until there's a good chance
+        // that we'll be able to do so without error.
+        //
+        htmlCopy.recordResolutionError();
+      }
+      htmlCopy.exception = thrownException;
+      _cache.put(source, htmlCopy);
+      htmlEntry = htmlCopy;
+    }
+    if (thrownException != null) {
+      throw thrownException;
+    }
+    return htmlEntry;
+  }
+
+  /**
    * Record the results produced by performing a [ResolveAngularComponentTemplateTask]. If the
    * results were computed from data that is now out-of-date, then the results will not be recorded.
    *
@@ -7516,9 +7943,9 @@
    * @param oldPartMap the table containing the parts associated with each library
    */
   void _removeFromPartsUsingMap(Map<Source, List<Source>> oldPartMap) {
-    for (MapEntry<Source, List<Source>> entry in getMapEntrySet(oldPartMap)) {
-      Source librarySource = entry.getKey();
-      List<Source> oldParts = entry.getValue();
+    for (MapIterator<Source, List<Source>> iter = SingleMapIterator.forMap(oldPartMap); iter.moveNext();) {
+      Source librarySource = iter.key;
+      List<Source> oldParts = iter.value;
       for (int i = 0; i < oldParts.length; i++) {
         Source partSource = oldParts[i];
         if (partSource != librarySource) {
@@ -7667,9 +8094,10 @@
     int consistencyCheckStart = JavaSystem.nanoTime();
     List<Source> changedSources = new List<Source>();
     List<Source> missingSources = new List<Source>();
-    for (MapEntry<Source, SourceEntry> entry in _cache.entrySet()) {
-      Source source = entry.getKey();
-      SourceEntry sourceEntry = entry.getValue();
+    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key;
+      SourceEntry sourceEntry = iterator.value;
       int sourceTime = getModificationStamp(source);
       if (sourceTime != sourceEntry.modificationTime) {
         changedSources.add(source);
@@ -7716,6 +8144,9 @@
   AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
 
   @override
+  DartEntry visitBuildDartElementModelTask(BuildDartElementModelTask task) => AnalysisContextImpl_this._recordBuildDartElementModelTask(task);
+
+  @override
   DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
 
   @override
@@ -7734,6 +8165,12 @@
   HtmlEntry visitParseHtmlTask(ParseHtmlTask task) => AnalysisContextImpl_this._recordParseHtmlTaskResults(task);
 
   @override
+  HtmlEntry visitPolymerBuildHtmlTask(PolymerBuildHtmlTask task) => AnalysisContextImpl_this._recordPolymerBuildHtmlTaskResults(task);
+
+  @override
+  HtmlEntry visitPolymerResolveHtmlTask(PolymerResolveHtmlTask task) => AnalysisContextImpl_this._recordPolymerResolveHtmlTaskResults(task);
+
+  @override
   HtmlEntry visitResolveAngularComponentTemplateTask(ResolveAngularComponentTemplateTask task) => AnalysisContextImpl_this._recordResolveAngularComponentTemplateTaskResults(task);
 
   @override
@@ -8419,6 +8856,11 @@
   bool analyzeAngular = true;
 
   /**
+   * A flag indicating whether analysis is to analyze Polymer.
+   */
+  bool analyzePolymer = true;
+
+  /**
    * Initialize a newly created set of analysis options to have their default values.
    */
   AnalysisOptionsImpl();
@@ -9836,11 +10278,6 @@
  */
 class PerformanceStatistics {
   /**
-   * The [TimeCounter] for time spent in Angular analysis.
-   */
-  static TimeCounter angular = new TimeCounter();
-
-  /**
    * The [TimeCounter] for time spent in reading files.
    */
   static TimeCounter io = new TimeCounter();
@@ -9861,6 +10298,16 @@
   static TimeCounter resolve = new TimeCounter();
 
   /**
+   * The [TimeCounter] for time spent in Angular analysis.
+   */
+  static TimeCounter angular = new TimeCounter();
+
+  /**
+   * The [TimeCounter] for time spent in Polymer analysis.
+   */
+  static TimeCounter polymer = new TimeCounter();
+
+  /**
    * The [TimeCounter] for time spent in error verifier.
    */
   static TimeCounter errors = new TimeCounter();
@@ -9879,6 +10326,7 @@
     parse = new TimeCounter();
     resolve = new TimeCounter();
     angular = new TimeCounter();
+    polymer = new TimeCounter();
     errors = new TimeCounter();
     hints = new TimeCounter();
   }
@@ -9912,14 +10360,14 @@
    * @return an array of errors (not `null`, contains no `null`s)
    */
   List<AnalysisError> get errors {
-    Iterable<MapEntry<Source, Set<AnalysisError>>> entrySet = getMapEntrySet(_errors);
-    int numEntries = entrySet.length;
+    Iterable<Set<AnalysisError>> errorsSets = _errors.values;
+    int numEntries = errorsSets.length;
     if (numEntries == 0) {
       return AnalysisError.NO_ERRORS;
     }
     List<AnalysisError> resultList = new List<AnalysisError>();
-    for (MapEntry<Source, Set<AnalysisError>> entry in entrySet) {
-      resultList.addAll(entry.getValue());
+    for (Set<AnalysisError> errorsSet in errorsSets) {
+      resultList.addAll(errorsSet);
     }
     return new List.from(resultList);
   }
@@ -11595,6 +12043,396 @@
 }
 
 /**
+ * Instances of the class [PolymerHtmlUnitBuilder] build Polymer specific elements.
+ */
+class PolymerHtmlUnitBuilder extends ht.RecursiveXmlVisitor<Object> {
+  /**
+   * These names are forbidden to use as a custom tag name.
+   *
+   * http://w3c.github.io/webcomponents/spec/custom/#concepts
+   */
+  static Set<String> _FORBIDDEN_TAG_NAMES = new Set();
+
+  static bool isValidAttributeName(String name) {
+    // cannot be empty
+    if (name.isEmpty) {
+      return false;
+    }
+    // check characters
+    int length = name.length;
+    for (int i = 0; i < length; i++) {
+      int c = name.codeUnitAt(i);
+      if (i == 0) {
+        if (!Character.isLetter(c)) {
+          return false;
+        }
+      } else {
+        if (!(Character.isLetterOrDigit(c) || c == 0x5F)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  static bool isValidTagName(String name) {
+    // cannot be empty
+    if (name.isEmpty) {
+      return false;
+    }
+    // check for forbidden name
+    if (_FORBIDDEN_TAG_NAMES.contains(name)) {
+      return false;
+    }
+    // check characters
+    int length = name.length;
+    bool hasDash = false;
+    for (int i = 0; i < length; i++) {
+      int c = name.codeUnitAt(i);
+      // check for '-'
+      if (c == 0x2D) {
+        hasDash = true;
+      }
+      // check character
+      if (i == 0) {
+        if (hasDash) {
+          return false;
+        }
+        if (!Character.isLetter(c)) {
+          return false;
+        }
+      } else {
+        if (!(Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F)) {
+          return false;
+        }
+      }
+    }
+    if (!hasDash) {
+      return false;
+    }
+    return true;
+  }
+
+  final InternalAnalysisContext _context;
+
+  TypeProvider _typeProvider;
+
+  final AnalysisErrorListener _errorListener;
+
+  final Source _source;
+
+  final LineInfo _lineInfo;
+
+  final ht.HtmlUnit _unit;
+
+  List<PolymerTagHtmlElement> _tagHtmlElements = [];
+
+  ht.XmlTagNode _elementNode;
+
+  String _elementName;
+
+  PolymerTagHtmlElementImpl _htmlElement;
+
+  PolymerTagDartElementImpl _dartElement;
+
+  PolymerHtmlUnitBuilder(this._context, this._errorListener, this._source, this._lineInfo, this._unit) {
+    this._typeProvider = _context.typeProvider;
+  }
+
+  /**
+   * Builds Polymer specific HTML elements.
+   */
+  void build() {
+    _unit.accept(this);
+    // set Polymer tags
+    HtmlElementImpl unitElement = _unit.element as HtmlElementImpl;
+    unitElement.polymerTags = new List.from(_tagHtmlElements);
+  }
+
+  @override
+  Object visitXmlTagNode(ht.XmlTagNode node) {
+    if (node.tag == "polymer-element") {
+      _createTagHtmlElement(node);
+    }
+    // visit children
+    return super.visitXmlTagNode(node);
+  }
+
+  void _createAttributeElements() {
+    // prepare "attributes" attribute
+    ht.XmlAttributeNode attributesAttribute = _elementNode.getAttribute("attributes");
+    if (attributesAttribute == null) {
+      return;
+    }
+    // check if there is a Dart part to resolve against it
+    if (_dartElement == null) {
+      // TODO(scheglov) maybe report error (if it is allowed at all to have element without Dart part)
+      return;
+    }
+    // prepare value of the "attributes" attribute
+    String attributesText = attributesAttribute.text;
+    if (attributesText.trim().isEmpty) {
+      _reportErrorForAttribute(attributesAttribute, PolymerCode.EMPTY_ATTRIBUTES, []);
+      return;
+    }
+    // prepare attribute name tokens
+    List<PolymerHtmlUnitBuilder_NameToken> nameTokens = [];
+    {
+      int index = 0;
+      int textOffset = attributesAttribute.textOffset;
+      int nameOffset = -1;
+      JavaStringBuilder nameBuilder = new JavaStringBuilder();
+      while (index < attributesText.length) {
+        int c = attributesText.codeUnitAt(index++);
+        if (Character.isWhitespace(c)) {
+          if (nameOffset != -1) {
+            nameTokens.add(new PolymerHtmlUnitBuilder_NameToken(nameOffset, nameBuilder.toString()));
+            nameBuilder = new JavaStringBuilder();
+            nameOffset = -1;
+          }
+          continue;
+        }
+        if (nameOffset == -1) {
+          nameOffset = textOffset + index - 1;
+        }
+        nameBuilder.appendChar(c);
+      }
+      if (nameOffset != -1) {
+        nameTokens.add(new PolymerHtmlUnitBuilder_NameToken(nameOffset, nameBuilder.toString()));
+        nameBuilder = new JavaStringBuilder();
+      }
+    }
+    // create attributes for name tokens
+    List<PolymerAttributeElement> attributes = [];
+    Set<String> definedNames = new Set();
+    ClassElement classElement = _dartElement.classElement;
+    for (PolymerHtmlUnitBuilder_NameToken nameToken in nameTokens) {
+      int offset = nameToken._offset;
+      // prepare name
+      String name = nameToken._value;
+      if (!isValidAttributeName(name)) {
+        _reportErrorForNameToken(nameToken, PolymerCode.INVALID_ATTRIBUTE_NAME, [name]);
+        continue;
+      }
+      if (!definedNames.add(name)) {
+        _reportErrorForNameToken(nameToken, PolymerCode.DUPLICATE_ATTRIBUTE_DEFINITION, [name]);
+        continue;
+      }
+      // create attribute
+      PolymerAttributeElementImpl attribute = new PolymerAttributeElementImpl(name, offset);
+      attributes.add(attribute);
+      // resolve field
+      FieldElement field = classElement.getField(name);
+      if (field == null) {
+        _reportErrorForNameToken(nameToken, PolymerCode.UNDEFINED_ATTRIBUTE_FIELD, [name, classElement.displayName]);
+        continue;
+      }
+      if (!_isPublishedField(field)) {
+        _reportErrorForNameToken(nameToken, PolymerCode.ATTRIBUTE_FIELD_NOT_PUBLISHED, [name, classElement.displayName]);
+      }
+      attribute.field = field;
+    }
+    _htmlElement.attributes = new List.from(attributes);
+  }
+
+  void _createTagHtmlElement(ht.XmlTagNode node) {
+    this._elementNode = node;
+    this._elementName = null;
+    this._htmlElement = null;
+    this._dartElement = null;
+    // prepare 'name' attribute
+    ht.XmlAttributeNode nameAttribute = node.getAttribute("name");
+    if (nameAttribute == null) {
+      _reportErrorForToken(node.tagToken, PolymerCode.MISSING_TAG_NAME, []);
+      return;
+    }
+    // prepare name
+    _elementName = nameAttribute.text;
+    if (!isValidTagName(_elementName)) {
+      _reportErrorForAttributeValue(nameAttribute, PolymerCode.INVALID_TAG_NAME, [_elementName]);
+      return;
+    }
+    // TODO(scheglov) Maybe check that at least one of "template" or "script" children.
+    // TODO(scheglov) Maybe check if more than one top-level "template".
+    // create HTML element
+    int nameOffset = nameAttribute.textOffset;
+    _htmlElement = new PolymerTagHtmlElementImpl(_elementName, nameOffset);
+    // bind to the corresponding Dart element
+    _dartElement = _findTagDartElement();
+    if (_dartElement != null) {
+      _htmlElement.dartElement = _dartElement;
+      _dartElement.htmlElement = _htmlElement;
+    }
+    // TODO(scheglov) create attributes
+    _createAttributeElements();
+    // done
+    _tagHtmlElements.add(_htmlElement);
+  }
+
+  /**
+   * Returns the [PolymerTagDartElement] that corresponds to the Polymer custom tag declared
+   * by the given [XmlTagNode].
+   */
+  PolymerTagDartElementImpl _findTagDartElement() {
+    LibraryElement dartLibraryElement = dartUnitElement;
+    if (dartLibraryElement == null) {
+      return null;
+    }
+    return _findTagDartElement_inLibrary(dartLibraryElement);
+  }
+
+  /**
+   * Returns the [PolymerTagDartElementImpl] declared in the given [LibraryElement] with
+   * the [elementName]. Maybe `null`.
+   */
+  PolymerTagDartElementImpl _findTagDartElement_inLibrary(LibraryElement library) {
+    try {
+      library.accept(new RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary(this));
+    } on PolymerHtmlUnitBuilder_FoundTagDartElementError catch (e) {
+      return e._result;
+    }
+    return null;
+  }
+
+  /**
+   * Returns the only [LibraryElement] referenced by a direct `script` child. Maybe
+   * `null` if none.
+   */
+  LibraryElement get dartUnitElement {
+    // TODO(scheglov) Maybe check if more than one "script".
+    for (ht.XmlTagNode child in _elementNode.tagNodes) {
+      if (child is ht.HtmlScriptTagNode) {
+        HtmlScriptElement scriptElement = child.scriptElement;
+        if (scriptElement is ExternalHtmlScriptElement) {
+          Source scriptSource = scriptElement.scriptSource;
+          if (scriptSource != null) {
+            return _context.getLibraryElement(scriptSource);
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  bool _isPublishedAnnotation(ElementAnnotation annotation) {
+    Element element = annotation.element;
+    if (element != null && element.name == "published") {
+      return true;
+    }
+    return false;
+  }
+
+  bool _isPublishedField(FieldElement field) {
+    List<ElementAnnotation> annotations = field.metadata;
+    for (ElementAnnotation annotation in annotations) {
+      if (_isPublishedAnnotation(annotation)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Reports an error on the attribute's value, or (if absent) on the attribute's name.
+   */
+  void _reportErrorForAttribute(ht.XmlAttributeNode node, ErrorCode errorCode, List<Object> arguments) {
+    _reportErrorForOffset(node.offset, node.length, errorCode, arguments);
+  }
+
+  /**
+   * Reports an error on the attribute's value, or (if absent) on the attribute's name.
+   */
+  void _reportErrorForAttributeValue(ht.XmlAttributeNode node, ErrorCode errorCode, List<Object> arguments) {
+    ht.Token valueToken = node.valueToken;
+    if (valueToken == null || valueToken.isSynthetic) {
+      _reportErrorForAttribute(node, errorCode, arguments);
+    } else {
+      _reportErrorForToken(valueToken, errorCode, arguments);
+    }
+  }
+
+  void _reportErrorForNameToken(PolymerHtmlUnitBuilder_NameToken token, ErrorCode errorCode, List<Object> arguments) {
+    int offset = token._offset;
+    int length = token._value.length;
+    _reportErrorForOffset(offset, length, errorCode, arguments);
+  }
+
+  void _reportErrorForOffset(int offset, int length, ErrorCode errorCode, List<Object> arguments) {
+    _errorListener.onError(new AnalysisError.con2(_source, offset, length, errorCode, arguments));
+  }
+
+  void _reportErrorForToken(ht.Token token, ErrorCode errorCode, List<Object> arguments) {
+    int offset = token.offset;
+    int length = token.length;
+    _reportErrorForOffset(offset, length, errorCode, arguments);
+  }
+}
+
+class PolymerHtmlUnitBuilder_FoundTagDartElementError extends Error {
+  final PolymerTagDartElementImpl _result;
+
+  PolymerHtmlUnitBuilder_FoundTagDartElementError(this._result);
+}
+
+class PolymerHtmlUnitBuilder_NameToken {
+  final int _offset;
+
+  final String _value;
+
+  PolymerHtmlUnitBuilder_NameToken(this._offset, this._value);
+}
+
+class RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary extends RecursiveElementVisitor<Object> {
+  final PolymerHtmlUnitBuilder PolymerHtmlUnitBuilder_this;
+
+  RecursiveElementVisitor_PolymerHtmlUnitBuilder_findTagDartElement_inLibrary(this.PolymerHtmlUnitBuilder_this) : super();
+
+  @override
+  Object visitPolymerTagDartElement(PolymerTagDartElement element) {
+    if (element.name == PolymerHtmlUnitBuilder_this._elementName) {
+      throw new PolymerHtmlUnitBuilder_FoundTagDartElementError(element as PolymerTagDartElementImpl);
+    }
+    return null;
+  }
+}
+
+/**
+ * Instances of the class [PolymerHtmlUnitResolver] resolve Polymer specific
+ * [XmlTagNode]s and expressions.
+ *
+ * TODO(scheglov) implement it
+ */
+class PolymerHtmlUnitResolver extends ht.RecursiveXmlVisitor<Object> {
+  final InternalAnalysisContext _context;
+
+  TypeProvider _typeProvider;
+
+  final AnalysisErrorListener _errorListener;
+
+  final Source _source;
+
+  final LineInfo _lineInfo;
+
+  final ht.HtmlUnit _unit;
+
+  PolymerHtmlUnitResolver(this._context, this._errorListener, this._source, this._lineInfo, this._unit) {
+    this._typeProvider = _context.typeProvider;
+  }
+
+  /**
+   * Resolves Polymer specific features.
+   */
+  void resolveUnit() {
+  }
+
+  @override
+  Object visitXmlAttributeNode(ht.XmlAttributeNode node) => super.visitXmlAttributeNode(node);
+
+  @override
+  Object visitXmlTagNode(ht.XmlTagNode node) => super.visitXmlTagNode(node);
+}
+
+/**
  * The abstract class `AnalysisTask` defines the behavior of objects used to perform an
  * analysis task.
  */
@@ -11692,6 +12530,15 @@
  */
 abstract class AnalysisTaskVisitor<E> {
   /**
+   * Visit a [BuildDartElementModelTask].
+   *
+   * @param task the task to be visited
+   * @return the result of visiting the task
+   * @throws AnalysisException if the visitor throws an exception for some reason
+   */
+  E visitBuildDartElementModelTask(BuildDartElementModelTask task);
+
+  /**
    * Visit a [GenerateDartErrorsTask].
    *
    * @param task the task to be visited
@@ -11746,6 +12593,24 @@
   E visitParseHtmlTask(ParseHtmlTask task);
 
   /**
+   * Visit a [PolymerBuildHtmlTask].
+   *
+   * @param task the task to be visited
+   * @return the result of visiting the task
+   * @throws AnalysisException if the visitor throws an exception for some reason
+   */
+  E visitPolymerBuildHtmlTask(PolymerBuildHtmlTask task);
+
+  /**
+   * Visit a [PolymerResolveHtmlTask].
+   *
+   * @param task the task to be visited
+   * @return the result of visiting the task
+   * @throws AnalysisException if the visitor throws an exception for some reason
+   */
+  E visitPolymerResolveHtmlTask(PolymerResolveHtmlTask task);
+
+  /**
    * Visit a [ResolveAngularComponentTemplateTask].
    *
    * @param task the task to be visited
@@ -11810,6 +12675,324 @@
 }
 
 /**
+ * Instances of the class `BuildDartElementModelTask` build the element models for all of the
+ * libraries in a cycle.
+ */
+class BuildDartElementModelTask extends AnalysisTask {
+  /**
+   * The library for which an element model was originally requested.
+   */
+  Source _targetLibrary;
+
+  /**
+   * The libraries that are part of the cycle to be resolved.
+   */
+  final List<ResolvableLibrary> librariesInCycle;
+
+  /**
+   * The listener to which analysis errors will be reported.
+   */
+  RecordingErrorListener _errorListener;
+
+  /**
+   * A source object representing the core library (dart:core).
+   */
+  Source _coreLibrarySource;
+
+  /**
+   * The object representing the core library.
+   */
+  ResolvableLibrary _coreLibrary;
+
+  /**
+   * A table mapping library sources to the information being maintained for those libraries.
+   */
+  Map<Source, ResolvableLibrary> _libraryMap = new Map<Source, ResolvableLibrary>();
+
+  /**
+   * Initialize a newly created task to perform analysis within the given context.
+   *
+   * @param context the context in which the task is to be performed
+   * @param targetLibrary the library for which an element model was originally requested
+   * @param librariesInCycle the libraries that are part of the cycle to be resolved
+   */
+  BuildDartElementModelTask(InternalAnalysisContext context, Source targetLibrary, this.librariesInCycle) : super(context) {
+    this._errorListener = new RecordingErrorListener();
+    _coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+  }
+
+  @override
+  accept(AnalysisTaskVisitor visitor) => visitor.visitBuildDartElementModelTask(this);
+
+  /**
+   * Return the listener to which analysis errors were (or will be) reported.
+   *
+   * @return the listener to which analysis errors were reported
+   */
+  RecordingErrorListener get errorListener => _errorListener;
+
+  /**
+   * Return the library for which an element model was originally requested.
+   *
+   * @return the library for which an element model was originally requested
+   */
+  Source get targetLibrary => _targetLibrary;
+
+  @override
+  String get taskDescription {
+    Source librarySource = librariesInCycle[0].librarySource;
+    if (librarySource == null) {
+      return "build an element model for unknown library";
+    }
+    return "build an element model for ${librarySource.fullName}";
+  }
+
+  @override
+  void internalPerform() {
+    InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engine.LibraryResolver.resolveLibrary");
+    try {
+      //
+      // Build the map of libraries that are known.
+      //
+      _libraryMap = _buildLibraryMap();
+      _coreLibrary = _libraryMap[_coreLibrarySource];
+      LibraryElement coreElement = _coreLibrary.libraryElement;
+      if (coreElement == null) {
+        throw new AnalysisException.con1("Could not resolve dart:core");
+      }
+      instrumentation.metric3("buildLibraryMap", "complete");
+      //
+      // Build the element models representing the libraries being resolved. This is done in three
+      // steps.
+      //
+      // 1. Build the basic element models without making any connections between elements other than
+      //    the basic parent/child relationships. This includes building the elements representing the
+      //    libraries.
+      //
+      _buildElementModels();
+      instrumentation.metric3("buildElementModels", "complete");
+      //
+      // 2. Build the elements for the import and export directives. This requires that we have the
+      //    elements built for the referenced libraries, but because of the possibility of circular
+      //    references needs to happen after all of the library elements have been created.
+      //
+      _buildDirectiveModels();
+      instrumentation.metric3("buildDirectiveModels", "complete");
+      //
+      // 3. Build the rest of the type model by connecting superclasses, mixins, and interfaces. This
+      //    requires that we be able to compute the names visible in the libraries being resolved,
+      //    which in turn requires that we have resolved the import directives.
+      //
+      _buildTypeHierarchies(new TypeProviderImpl(coreElement));
+      instrumentation.metric3("buildTypeHierarchies", "complete");
+    } finally {
+      instrumentation.log();
+    }
+  }
+
+  /**
+   * Build the element model representing the combinators declared by the given directive.
+   *
+   * @param directive the directive that declares the combinators
+   * @return an array containing the import combinators that were built
+   */
+  List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
+    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
+    for (Combinator combinator in directive.combinators) {
+      if (combinator is HideCombinator) {
+        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
+        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
+        combinators.add(hide);
+      } else {
+        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
+        show.offset = combinator.offset;
+        show.end = combinator.end;
+        show.shownNames = _getIdentifiers((combinator as ShowCombinator).shownNames);
+        combinators.add(show);
+      }
+    }
+    return new List.from(combinators);
+  }
+
+  /**
+   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
+   * the import and export directives.
+   *
+   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
+   *           be accessed
+   */
+  void _buildDirectiveModels() {
+    AnalysisContext analysisContext = context;
+    for (ResolvableLibrary library in librariesInCycle) {
+      Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixElementImpl>();
+      List<ImportElement> imports = new List<ImportElement>();
+      List<ExportElement> exports = new List<ExportElement>();
+      for (Directive directive in library.definingCompilationUnit.directives) {
+        if (directive is ImportDirective) {
+          ImportDirective importDirective = directive;
+          String uriContent = importDirective.uriContent;
+          if (DartUriResolver.isDartExtUri(uriContent)) {
+            library.libraryElement.hasExtUri = true;
+          }
+          Source importedSource = importDirective.source;
+          if (importedSource != null && analysisContext.exists(importedSource)) {
+            // The imported source will be null if the URI in the import directive was invalid.
+            ResolvableLibrary importedLibrary = _libraryMap[importedSource];
+            if (importedLibrary != null) {
+              ImportElementImpl importElement = new ImportElementImpl(directive.offset);
+              StringLiteral uriLiteral = importDirective.uri;
+              if (uriLiteral != null) {
+                importElement.uriOffset = uriLiteral.offset;
+                importElement.uriEnd = uriLiteral.end;
+              }
+              importElement.uri = uriContent;
+              importElement.combinators = _buildCombinators(importDirective);
+              LibraryElement importedLibraryElement = importedLibrary.libraryElement;
+              if (importedLibraryElement != null) {
+                importElement.importedLibrary = importedLibraryElement;
+              }
+              SimpleIdentifier prefixNode = directive.prefix;
+              if (prefixNode != null) {
+                importElement.prefixOffset = prefixNode.offset;
+                String prefixName = prefixNode.name;
+                PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+                if (prefix == null) {
+                  prefix = new PrefixElementImpl(prefixNode);
+                  nameToPrefixMap[prefixName] = prefix;
+                }
+                importElement.prefix = prefix;
+                prefixNode.staticElement = prefix;
+              }
+              directive.element = importElement;
+              imports.add(importElement);
+              if (analysisContext.computeKindOf(importedSource) != SourceKind.LIBRARY) {
+                _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
+              }
+            }
+          }
+        } else if (directive is ExportDirective) {
+          ExportDirective exportDirective = directive;
+          Source exportedSource = exportDirective.source;
+          if (exportedSource != null && analysisContext.exists(exportedSource)) {
+            // The exported source will be null if the URI in the export directive was invalid.
+            ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
+            if (exportedLibrary != null) {
+              ExportElementImpl exportElement = new ExportElementImpl();
+              StringLiteral uriLiteral = exportDirective.uri;
+              if (uriLiteral != null) {
+                exportElement.uriOffset = uriLiteral.offset;
+                exportElement.uriEnd = uriLiteral.end;
+              }
+              exportElement.uri = exportDirective.uriContent;
+              exportElement.combinators = _buildCombinators(exportDirective);
+              LibraryElement exportedLibraryElement = exportedLibrary.libraryElement;
+              if (exportedLibraryElement != null) {
+                exportElement.exportedLibrary = exportedLibraryElement;
+              }
+              directive.element = exportElement;
+              exports.add(exportElement);
+              if (analysisContext.computeKindOf(exportedSource) != SourceKind.LIBRARY) {
+                _errorListener.onError(new AnalysisError.con2(library.librarySource, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [uriLiteral.toSource()]));
+              }
+            }
+          }
+        }
+      }
+      Source librarySource = library.librarySource;
+      if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource) {
+        ImportElementImpl importElement = new ImportElementImpl(-1);
+        importElement.importedLibrary = _coreLibrary.libraryElement;
+        importElement.synthetic = true;
+        imports.add(importElement);
+      }
+      LibraryElementImpl libraryElement = library.libraryElement;
+      libraryElement.imports = new List.from(imports);
+      libraryElement.exports = new List.from(exports);
+      if (libraryElement.entryPoint == null) {
+        Namespace namespace = new NamespaceBuilder().createExportNamespaceForLibrary(libraryElement);
+        Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME);
+        if (element is FunctionElement) {
+          libraryElement.entryPoint = element;
+        }
+      }
+    }
+  }
+
+  /**
+   * Build element models for all of the libraries in the current cycle.
+   *
+   * @throws AnalysisException if any of the element models cannot be built
+   */
+  void _buildElementModels() {
+    for (ResolvableLibrary library in librariesInCycle) {
+      LibraryElementBuilder builder = new LibraryElementBuilder(context, _errorListener);
+      LibraryElementImpl libraryElement = builder.buildLibrary2(library);
+      library.libraryElement = libraryElement;
+    }
+  }
+
+  /**
+   * Build a table mapping library sources to the resolvable libraries representing those libraries.
+   *
+   * @return the map that was built
+   */
+  Map<Source, ResolvableLibrary> _buildLibraryMap() {
+    Map<Source, ResolvableLibrary> libraryMap = new Map<Source, ResolvableLibrary>();
+    int libraryCount = librariesInCycle.length;
+    for (int i = 0; i < libraryCount; i++) {
+      ResolvableLibrary library = librariesInCycle[i];
+      library.errorListener = _errorListener;
+      libraryMap[library.librarySource] = library;
+      List<ResolvableLibrary> dependencies = library.importsAndExports;
+      int dependencyCount = dependencies.length;
+      for (int j = 0; j < dependencyCount; j++) {
+        ResolvableLibrary dependency = dependencies[j];
+        //dependency.setErrorListener(errorListener);
+        libraryMap[dependency.librarySource] = dependency;
+      }
+    }
+    return libraryMap;
+  }
+
+  /**
+   * Resolve the type hierarchy across all of the types declared in the libraries in the current
+   * cycle.
+   *
+   * @throws AnalysisException if any of the type hierarchies could not be resolved
+   */
+  void _buildTypeHierarchies(TypeProvider typeProvider) {
+    TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
+    try {
+      for (ResolvableLibrary library in librariesInCycle) {
+        for (ResolvableCompilationUnit unit in library.resolvableCompilationUnits) {
+          Source source = unit.source;
+          CompilationUnit ast = unit.compilationUnit;
+          TypeResolverVisitor visitor = new TypeResolverVisitor.con4(library, source, typeProvider);
+          ast.accept(visitor);
+        }
+      }
+    } finally {
+      timeCounter.stop();
+    }
+  }
+
+  /**
+   * Return an array containing the lexical identifiers associated with the nodes in the given list.
+   *
+   * @param names the AST nodes representing the identifiers
+   * @return the lexical identifiers associated with the nodes in the list
+   */
+  List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
+    int count = names.length;
+    List<String> identifiers = new List<String>(count);
+    for (int i = 0; i < count; i++) {
+      identifiers[i] = names[i].name;
+    }
+    return identifiers;
+  }
+}
+
+/**
  * Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
  * Dart source.
  */
@@ -12576,6 +13759,122 @@
 }
 
 /**
+ * Instances of the class `PolymerBuildHtmlTask` build Polymer specific elements.
+ */
+class PolymerBuildHtmlTask extends AnalysisTask {
+  /**
+   * The source to build which Polymer HTML elements for.
+   */
+  final Source source;
+
+  /**
+   * The time at which the contents of the source were last modified.
+   */
+  final int modificationTime;
+
+  /**
+   * The line information associated with the source.
+   */
+  final LineInfo _lineInfo;
+
+  /**
+   * The HTML unit to be resolved.
+   */
+  final ht.HtmlUnit _unit;
+
+  /**
+   * The resolution errors that were discovered while building elements.
+   */
+  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
+
+  /**
+   * Initialize a newly created task to perform analysis within the given context.
+   *
+   * @param context the context in which the task is to be performed
+   * @param source the source to be resolved
+   * @param modificationTime the time at which the contents of the source were last modified
+   * @param lineInfo the line information associated with the source
+   * @param unit the HTML unit to build Polymer elements for
+   */
+  PolymerBuildHtmlTask(InternalAnalysisContext context, this.source, this.modificationTime, this._lineInfo, this._unit) : super(context);
+
+  @override
+  accept(AnalysisTaskVisitor visitor) => visitor.visitPolymerBuildHtmlTask(this);
+
+  List<AnalysisError> get errors => _errors;
+
+  @override
+  String get taskDescription => "build Polymer elements ${source.fullName}";
+
+  @override
+  void internalPerform() {
+    RecordingErrorListener errorListener = new RecordingErrorListener();
+    PolymerHtmlUnitBuilder resolver = new PolymerHtmlUnitBuilder(context, errorListener, source, _lineInfo, _unit);
+    resolver.build();
+    _errors = errorListener.getErrorsForSource(source);
+  }
+}
+
+/**
+ * Instances of the class `PolymerResolveHtmlTask` performs Polymer specific HTML file
+ * resolution.
+ *
+ * TODO(scheglov) implement it
+ */
+class PolymerResolveHtmlTask extends AnalysisTask {
+  /**
+   * The source to be resolved.
+   */
+  final Source source;
+
+  /**
+   * The time at which the contents of the source were last modified.
+   */
+  final int modificationTime;
+
+  /**
+   * The line information associated with the source.
+   */
+  final LineInfo _lineInfo;
+
+  /**
+   * The HTML unit to be resolved.
+   */
+  final ht.HtmlUnit _unit;
+
+  /**
+   * The resolution errors that were discovered while resolving the source.
+   */
+  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
+
+  /**
+   * Initialize a newly created task to perform analysis within the given context.
+   *
+   * @param context the context in which the task is to be performed
+   * @param source the source to be resolved
+   * @param modificationTime the time at which the contents of the source were last modified
+   * @param unit the HTML unit to be resolved
+   */
+  PolymerResolveHtmlTask(InternalAnalysisContext context, this.source, this.modificationTime, this._lineInfo, this._unit) : super(context);
+
+  @override
+  accept(AnalysisTaskVisitor visitor) => visitor.visitPolymerResolveHtmlTask(this);
+
+  List<AnalysisError> get errors => _errors;
+
+  @override
+  String get taskDescription => "resolve as Polymer ${source.fullName}";
+
+  @override
+  void internalPerform() {
+    RecordingErrorListener errorListener = new RecordingErrorListener();
+    PolymerHtmlUnitResolver resolver = new PolymerHtmlUnitResolver(context, errorListener, source, _lineInfo, _unit);
+    resolver.resolveUnit();
+    _errors = errorListener.getErrorsForSource(source);
+  }
+}
+
+/**
  * Instances of the class `ResolveAngularComponentTemplateTask` resolve HTML template
  * referenced by [AngularComponentElement].
  */
@@ -12640,7 +13939,7 @@
   ht.HtmlUnit get resolvedUnit => _resolvedUnit;
 
   @override
-  String get taskDescription => "resolving Angular template ${source}";
+  String get taskDescription => "resolve as Angular template ${source}";
 
   @override
   void internalPerform() {
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index ace8cf6..e944834 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -138,6 +138,55 @@
 }
 
 /**
+ * The enumeration `PolymerCode` defines Polymer specific problems.
+ */
+class PolymerCode extends Enum<PolymerCode> implements ErrorCode {
+  static const PolymerCode ATTRIBUTE_FIELD_NOT_PUBLISHED = const PolymerCode('ATTRIBUTE_FIELD_NOT_PUBLISHED', 0, "Field '%s' in '%s' must be @published");
+
+  static const PolymerCode DUPLICATE_ATTRIBUTE_DEFINITION = const PolymerCode('DUPLICATE_ATTRIBUTE_DEFINITION', 1, "The attribute '%s' is already defined");
+
+  static const PolymerCode EMPTY_ATTRIBUTES = const PolymerCode('EMPTY_ATTRIBUTES', 2, "Empty 'attributes' attribute is useless");
+
+  static const PolymerCode INVALID_ATTRIBUTE_NAME = const PolymerCode('INVALID_ATTRIBUTE_NAME', 3, "'%s' is not a valid name for a custom element attribute");
+
+  static const PolymerCode INVALID_TAG_NAME = const PolymerCode('INVALID_TAG_NAME', 4, "'%s' is not a valid name for a custom element");
+
+  static const PolymerCode MISSING_TAG_NAME = const PolymerCode('MISSING_TAG_NAME', 5, "Missing tag name of the custom element. Please include an attribute like name='your-tag-name'");
+
+  static const PolymerCode UNDEFINED_ATTRIBUTE_FIELD = const PolymerCode('UNDEFINED_ATTRIBUTE_FIELD', 6, "There is no such field '%s' in '%s'");
+
+  static const List<PolymerCode> values = const [
+      ATTRIBUTE_FIELD_NOT_PUBLISHED,
+      DUPLICATE_ATTRIBUTE_DEFINITION,
+      EMPTY_ATTRIBUTES,
+      INVALID_ATTRIBUTE_NAME,
+      INVALID_TAG_NAME,
+      MISSING_TAG_NAME,
+      UNDEFINED_ATTRIBUTE_FIELD];
+
+  /**
+   * The template used to create the message to be displayed for this error.
+   */
+  final String message;
+
+  /**
+   * Initialize a newly created error code to have the given message.
+   *
+   * @param message the message template used to create the message to be displayed for the error
+   */
+  const PolymerCode(String name, int ordinal, this.message) : super(name, ordinal);
+
+  @override
+  String get correction => null;
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
+
+  @override
+  ErrorType get type => ErrorType.POLYMER;
+}
+
+/**
  * The enumeration `AngularCode` defines Angular specific problems.
  */
 class AngularCode extends Enum<AngularCode> implements ErrorCode {
@@ -648,39 +697,38 @@
   static const HintCode IS_NOT_INT = const HintCode.con1('IS_NOT_INT', 10, "When compiled to JS, this test might return false when the left hand side is a double");
 
   /**
+   * This hint is generated anywhere where the [StaticTypeWarningCode#INVALID_ASSIGNMENT]
+   * would have been generated, if we used propagated information for the warnings.
+   *
+   * @param rhsTypeName the name of the right hand side type
+   * @param lhsTypeName the name of the left hand side type
+   * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
+   */
+  static const HintCode INVALID_ASSIGNMENT = const HintCode.con1('INVALID_ASSIGNMENT', 11, "A value of type '%s' cannot be assigned to a variable of type '%s'");
+
+  /**
    * Generate a hint for methods or functions that have a return type, but do not have a non-void
    * return statement on all branches. At the end of methods or functions with no return, Dart
    * implicitly returns `null`, avoiding these implicit returns is considered a best practice.
    *
    * @param returnType the name of the declared return type
    */
-  static const HintCode MISSING_RETURN = const HintCode.con2('MISSING_RETURN', 11, "This function declares a return type of '%s', but does not end with a return statement", "Either add a return statement or change the return type to 'void'");
+  static const HintCode MISSING_RETURN = const HintCode.con2('MISSING_RETURN', 12, "This function declares a return type of '%s', but does not end with a return statement", "Either add a return statement or change the return type to 'void'");
 
   /**
    * A getter with the override annotation does not override an existing getter.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_GETTER', 12, "Getter does not override an inherited getter");
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_GETTER', 13, "Getter does not override an inherited getter");
 
   /**
    * A method with the override annotation does not override an existing method.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_METHOD', 13, "Method does not override an inherited method");
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_METHOD', 14, "Method does not override an inherited method");
 
   /**
    * A setter with the override annotation does not override an existing setter.
    */
-  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_SETTER', 14, "Setter does not override an inherited setter");
-
-  /**
-   * It is not in best practice to declare a private method that happens to override the method in a
-   * superclass- depending on where the superclass is (either in the same library, or out of the
-   * same library), behavior can be different.
-   *
-   * @param memberType this is either "method", "getter" or "setter"
-   * @param memberName some private member name
-   * @param className the class name where the member is overriding the functionality
-   */
-  static const HintCode OVERRIDDING_PRIVATE_MEMBER = const HintCode.con1('OVERRIDDING_PRIVATE_MEMBER', 15, "The %s '%s' does not override the definition from '%s' because it is private and in a different library");
+  static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = const HintCode.con1('OVERRIDE_ON_NON_OVERRIDING_SETTER', 15, "Setter does not override an inherited setter");
 
   /**
    * Hint for classes that override equals, but not hashCode.
@@ -783,11 +831,11 @@
       IS_INT,
       IS_NOT_DOUBLE,
       IS_NOT_INT,
+      INVALID_ASSIGNMENT,
       MISSING_RETURN,
       OVERRIDE_ON_NON_OVERRIDING_GETTER,
       OVERRIDE_ON_NON_OVERRIDING_METHOD,
       OVERRIDE_ON_NON_OVERRIDING_SETTER,
-      OVERRIDDING_PRIVATE_MEMBER,
       OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
       TYPE_CHECK_IS_NOT_NULL,
       TYPE_CHECK_IS_NULL,
@@ -924,6 +972,11 @@
    */
   static const ErrorType ANGULAR = const ErrorType('ANGULAR', 7, ErrorSeverity.INFO);
 
+  /**
+   * Polymer specific semantic problems.
+   */
+  static const ErrorType POLYMER = const ErrorType('POLYMER', 8, ErrorSeverity.INFO);
+
   static const List<ErrorType> values = const [
       TODO,
       HINT,
@@ -932,7 +985,8 @@
       STATIC_WARNING,
       STATIC_TYPE_WARNING,
       SYNTACTIC_ERROR,
-      ANGULAR];
+      ANGULAR,
+      POLYMER];
 
   /**
    * The severity of this type of error.
@@ -1454,11 +1508,16 @@
   static const CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER = const CompileTimeErrorCode.con1('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER', 61, "Only static members can be accessed in initializers");
 
   /**
+   * Speculative.
+   */
+  static const CompileTimeErrorCode IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION = const CompileTimeErrorCode.con1('IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION', 62, "The library '%s' defines a top-level function named 'loadLibrary' and therefore cannot be deferred");
+
+  /**
    * SDK implementation libraries can be imported only by other SDK libraries.
    *
    * @param uri the uri pointing to a library
    */
-  static const CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 62, "The library '%s' is internal and cannot be imported");
+  static const CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_INTERNAL_LIBRARY', 63, "The library '%s' is internal and cannot be imported");
 
   /**
    * 14.1 Imports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1466,7 +1525,7 @@
    *
    * @param uri the uri pointing to a non-library declaration
    */
-  static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 63, "The imported library '%s' must not have a part-of directive");
+  static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY = const CompileTimeErrorCode.con1('IMPORT_OF_NON_LIBRARY', 64, "The imported library '%s' must not have a part-of directive");
 
   /**
    * 13.9 Switch: It is a compile-time error if values of the expressions <i>e<sub>k</sub></i> are
@@ -1475,7 +1534,7 @@
    * @param expressionSource the expression source code that is the unexpected type
    * @param expectedType the name of the expected type
    */
-  static const CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = const CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 64, "Case expressions must have the same types, '%s' is not a %s'");
+  static const CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES = const CompileTimeErrorCode.con1('INCONSISTENT_CASE_EXPRESSION_TYPES', 65, "Case expressions must have the same types, '%s' is not a %s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1486,7 +1545,7 @@
    *          immediately enclosing class
    * @see #INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD
    */
-  static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 65, "'%s' is not a variable in the enclosing class");
+  static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_NON_EXISTANT_FIELD', 66, "'%s' is not a variable in the enclosing class");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
@@ -1497,7 +1556,7 @@
    *          enclosing class
    * @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
    */
-  static const CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 66, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+  static const CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZER_FOR_STATIC_FIELD', 67, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1509,7 +1568,7 @@
    * @see #INITIALIZING_FORMAL_FOR_STATIC_FIELD
    * @see #INITIALIZER_FOR_NON_EXISTANT_FIELD
    */
-  static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 67, "'%s' is not a variable in the enclosing class");
+  static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_NON_EXISTANT_FIELD', 68, "'%s' is not a variable in the enclosing class");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form <i>this.id</i>. It is a
@@ -1520,20 +1579,20 @@
    *          enclosing class
    * @see #INITIALIZER_FOR_STATIC_FIELD
    */
-  static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 68, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
+  static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD = const CompileTimeErrorCode.con1('INITIALIZING_FORMAL_FOR_STATIC_FIELD', 69, "'%s' is a static variable in the enclosing class, variables initialized in a constructor cannot be static");
 
   /**
    * 12.30 Identifier Reference: Otherwise, e is equivalent to the property extraction
    * <b>this</b>.<i>id</i>.
    */
-  static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = const CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 69, "Instance member cannot be accessed from static method");
+  static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC = const CompileTimeErrorCode.con1('INSTANCE_MEMBER_ACCESS_FROM_STATIC', 70, "Instance member cannot be accessed from static method");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static const CompileTimeErrorCode INVALID_ANNOTATION = const CompileTimeErrorCode.con1('INVALID_ANNOTATION', 70, "Annotation can be only constant variable or constant constructor invocation");
+  static const CompileTimeErrorCode INVALID_ANNOTATION = const CompileTimeErrorCode.con1('INVALID_ANNOTATION', 71, "Annotation can be only constant variable or constant constructor invocation");
 
   /**
    * TODO(brianwilkerson) Remove this when we have decided on how to report errors in compile-time
@@ -1541,26 +1600,26 @@
    *
    * See TODOs in ConstantVisitor
    */
-  static const CompileTimeErrorCode INVALID_CONSTANT = const CompileTimeErrorCode.con1('INVALID_CONSTANT', 71, "Invalid constant value");
+  static const CompileTimeErrorCode INVALID_CONSTANT = const CompileTimeErrorCode.con1('INVALID_CONSTANT', 72, "Invalid constant value");
 
   /**
    * 7.6 Constructors: It is a compile-time error if the name of a constructor is not a constructor
    * name.
    */
-  static const CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = const CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 72, "Invalid constructor name");
+  static const CompileTimeErrorCode INVALID_CONSTRUCTOR_NAME = const CompileTimeErrorCode.con1('INVALID_CONSTRUCTOR_NAME', 73, "Invalid constructor name");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>M</i> is not the name of the immediately
    * enclosing class.
    */
-  static const CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = const CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 73, "The name of the immediately enclosing class expected");
+  static const CompileTimeErrorCode INVALID_FACTORY_NAME_NOT_A_CLASS = const CompileTimeErrorCode.con1('INVALID_FACTORY_NAME_NOT_A_CLASS', 74, "The name of the immediately enclosing class expected");
 
   /**
    * 12.10 This: It is a compile-time error if this appears in a top-level function or variable
    * initializer, in a factory constructor, or in a static method or variable initializer, or in the
    * initializer of an instance variable.
    */
-  static const CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = const CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 74, "Invalid reference to 'this' expression");
+  static const CompileTimeErrorCode INVALID_REFERENCE_TO_THIS = const CompileTimeErrorCode.con1('INVALID_REFERENCE_TO_THIS', 75, "Invalid reference to 'this' expression");
 
   /**
    * 12.6 Lists: It is a compile time error if the type argument of a constant list literal includes
@@ -1568,7 +1627,7 @@
    *
    * @name the name of the type parameter
    */
-  static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 75, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
+  static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_LIST', 76, "Constant list literals cannot include a type parameter as a type argument, such as '%s'");
 
   /**
    * 12.7 Maps: It is a compile time error if the type arguments of a constant map literal include a
@@ -1576,7 +1635,7 @@
    *
    * @name the name of the type parameter
    */
-  static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 76, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
+  static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP = const CompileTimeErrorCode.con1('INVALID_TYPE_ARGUMENT_IN_CONST_MAP', 77, "Constant map literals cannot include a type parameter as a type argument, such as '%s'");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -1591,7 +1650,7 @@
    * @param uri the URI that is invalid
    * @see #URI_DOES_NOT_EXIST
    */
-  static const CompileTimeErrorCode INVALID_URI = const CompileTimeErrorCode.con1('INVALID_URI', 77, "Invalid URI syntax: '%s'");
+  static const CompileTimeErrorCode INVALID_URI = const CompileTimeErrorCode.con1('INVALID_URI', 78, "Invalid URI syntax: '%s'");
 
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1602,7 +1661,7 @@
    *
    * @param labelName the name of the unresolvable label
    */
-  static const CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = const CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 78, "Cannot reference label '%s' declared in an outer method");
+  static const CompileTimeErrorCode LABEL_IN_OUTER_SCOPE = const CompileTimeErrorCode.con1('LABEL_IN_OUTER_SCOPE', 79, "Cannot reference label '%s' declared in an outer method");
 
   /**
    * 13.13 Break: It is a compile-time error if no such statement <i>s<sub>E</sub></i> exists within
@@ -1613,7 +1672,7 @@
    *
    * @param labelName the name of the unresolvable label
    */
-  static const CompileTimeErrorCode LABEL_UNDEFINED = const CompileTimeErrorCode.con1('LABEL_UNDEFINED', 79, "Cannot reference undefined label '%s'");
+  static const CompileTimeErrorCode LABEL_UNDEFINED = const CompileTimeErrorCode.con1('LABEL_UNDEFINED', 80, "Cannot reference undefined label '%s'");
 
   /**
    * 12.6 Lists: A run-time list literal &lt;<i>E</i>&gt; [<i>e<sub>1</sub></i> ...
@@ -1627,7 +1686,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static const CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 80, "The element type '%s' cannot be assigned to the list type '%s'");
+  static const CompileTimeErrorCode LIST_ELEMENT_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('LIST_ELEMENT_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the list type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -1641,7 +1700,7 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static const CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 81, "The element type '%s' cannot be assigned to the map key type '%s'");
+  static const CompileTimeErrorCode MAP_KEY_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_KEY_TYPE_NOT_ASSIGNABLE', 82, "The element type '%s' cannot be assigned to the map key type '%s'");
 
   /**
    * 12.7 Map: A run-time map literal &lt;<i>K</i>, <i>V</i>&gt; [<i>k<sub>1</sub></i> :
@@ -1655,13 +1714,13 @@
    * It is a static warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1 &lt;=
    * j &lt;= m</i>.
    */
-  static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 82, "The element type '%s' cannot be assigned to the map value type '%s'");
+  static const CompileTimeErrorCode MAP_VALUE_TYPE_NOT_ASSIGNABLE = const CompileTimeErrorCode.con1('MAP_VALUE_TYPE_NOT_ASSIGNABLE', 83, "The element type '%s' cannot be assigned to the map value type '%s'");
 
   /**
    * 7 Classes: It is a compile time error if a class <i>C</i> declares a member with the same name
    * as <i>C</i>.
    */
-  static const CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = const CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 83, "Class members cannot have the same name as the enclosing class");
+  static const CompileTimeErrorCode MEMBER_WITH_CLASS_NAME = const CompileTimeErrorCode.con1('MEMBER_WITH_CLASS_NAME', 84, "Class members cannot have the same name as the enclosing class");
 
   /**
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a method with the same
@@ -1669,17 +1728,17 @@
    *
    * @param name the conflicting name of the getter and method
    */
-  static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = const CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 84, "'%s' cannot be used to name a method, there is already a getter with the same name");
+  static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME = const CompileTimeErrorCode.con1('METHOD_AND_GETTER_WITH_SAME_NAME', 85, "'%s' cannot be used to name a method, there is already a getter with the same name");
 
   /**
    * 12.1 Constants: A constant expression is ... a constant list literal.
    */
-  static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 85, "List literals must be prefixed with 'const' when used as a constant expression");
+  static const CompileTimeErrorCode MISSING_CONST_IN_LIST_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_LIST_LITERAL', 86, "List literals must be prefixed with 'const' when used as a constant expression");
 
   /**
    * 12.1 Constants: A constant expression is ... a constant map literal.
    */
-  static const CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 86, "Map literals must be prefixed with 'const' when used as a constant expression");
+  static const CompileTimeErrorCode MISSING_CONST_IN_MAP_LITERAL = const CompileTimeErrorCode.con1('MISSING_CONST_IN_MAP_LITERAL', 87, "Map literals must be prefixed with 'const' when used as a constant expression");
 
   /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin explicitly declares a
@@ -1687,7 +1746,7 @@
    *
    * @param typeName the name of the mixin that is invalid
    */
-  static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = const CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 87, "The class '%s' cannot be used as a mixin because it declares a constructor");
+  static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR = const CompileTimeErrorCode.con1('MIXIN_DECLARES_CONSTRUCTOR', 88, "The class '%s' cannot be used as a mixin because it declares a constructor");
 
   /**
    * 9 Mixins: It is a compile-time error if a mixin is derived from a class whose superclass is not
@@ -1695,7 +1754,7 @@
    *
    * @param typeName the name of the mixin that is invalid
    */
-  static const CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = const CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 88, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
+  static const CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT = const CompileTimeErrorCode.con1('MIXIN_INHERITS_FROM_NOT_OBJECT', 89, "The class '%s' cannot be used as a mixin because it extends a class other than Object");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or implement Null.
@@ -1714,43 +1773,43 @@
    * @param typeName the name of the type that cannot be extended
    * @see #IMPLEMENTS_DISALLOWED_CLASS
    */
-  static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 89, "Classes cannot mixin '%s'");
+  static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_DISALLOWED_CLASS', 90, "Classes cannot mixin '%s'");
 
   /**
    * 9.1 Mixin Application: It is a compile-time error if <i>M</i> does not denote a class or mixin
    * available in the immediately enclosing scope.
    */
-  static const CompileTimeErrorCode MIXIN_OF_NON_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 90, "Classes can only mixin other classes");
+  static const CompileTimeErrorCode MIXIN_OF_NON_CLASS = const CompileTimeErrorCode.con1('MIXIN_OF_NON_CLASS', 91, "Classes can only mixin other classes");
 
   /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin refers to super.
    */
-  static const CompileTimeErrorCode MIXIN_REFERENCES_SUPER = const CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 91, "The class '%s' cannot be used as a mixin because it references 'super'");
+  static const CompileTimeErrorCode MIXIN_REFERENCES_SUPER = const CompileTimeErrorCode.con1('MIXIN_REFERENCES_SUPER', 92, "The class '%s' cannot be used as a mixin because it references 'super'");
 
   /**
    * 9.1 Mixin Application: It is a compile-time error if <i>S</i> does not denote a class available
    * in the immediately enclosing scope.
    */
-  static const CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = const CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 92, "Mixin can only be applied to class");
+  static const CompileTimeErrorCode MIXIN_WITH_NON_CLASS_SUPERCLASS = const CompileTimeErrorCode.con1('MIXIN_WITH_NON_CLASS_SUPERCLASS', 93, "Mixin can only be applied to class");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
    */
-  static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 93, "Constructor may have at most one 'this' redirection");
+  static const CompileTimeErrorCode MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode.con1('MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS', 94, "Constructor may have at most one 'this' redirection");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. Then <i>k</i> may
    * include at most one superinitializer in its initializer list or a compile time error occurs.
    */
-  static const CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = const CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 94, "Constructor may have at most one 'super' initializer");
+  static const CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS = const CompileTimeErrorCode.con1('MULTIPLE_SUPER_INITIALIZERS', 95, "Constructor may have at most one 'super' initializer");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = const CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 95, "Annotation creation must have arguments");
+  static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS = const CompileTimeErrorCode.con1('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS', 96, "Annotation creation must have arguments");
 
   /**
    * 7.6.1 Generative Constructors: If no superinitializer is provided, an implicit superinitializer
@@ -1760,7 +1819,7 @@
    * 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
    * generative constructor named <i>S</i> (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 96, "The class '%s' does not have a default constructor");
+  static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT', 97, "The class '%s' does not have a default constructor");
 
   /**
    * 7.6 Constructors: Iff no constructor is specified for a class <i>C</i>, it implicitly has a
@@ -1769,13 +1828,13 @@
    * 7.6.1 Generative constructors. It is a compile-time error if class <i>S</i> does not declare a
    * generative constructor named <i>S</i> (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 97, "The class '%s' does not have a default constructor");
+  static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT = const CompileTimeErrorCode.con1('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT', 98, "The class '%s' does not have a default constructor");
 
   /**
    * 13.2 Expression Statements: It is a compile-time error if a non-constant map literal that has
    * no explicit type arguments appears in a place where a statement is expected.
    */
-  static const CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = const CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 98, "A non-constant map literal without type arguments cannot be used as an expression statement");
+  static const CompileTimeErrorCode NON_CONST_MAP_AS_EXPRESSION_STATEMENT = const CompileTimeErrorCode.con1('NON_CONST_MAP_AS_EXPRESSION_STATEMENT', 99, "A non-constant map literal without type arguments cannot be used as an expression statement");
 
   /**
    * 13.9 Switch: Given a switch statement of the form <i>switch (e) { label<sub>11</sub> &hellip;
@@ -1786,44 +1845,44 @@
    * s<sub>n</sub>}</i>, it is a compile-time error if the expressions <i>e<sub>k</sub></i> are not
    * compile-time constants, for all <i>1 &lt;= k &lt;= n</i>.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = const CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 99, "Case expressions must be constant");
+  static const CompileTimeErrorCode NON_CONSTANT_CASE_EXPRESSION = const CompileTimeErrorCode.con1('NON_CONSTANT_CASE_EXPRESSION', 100, "Case expressions must be constant");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the default value of an optional
    * parameter is not a compile-time constant.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 100, "Default values of an optional parameter must be constant");
+  static const CompileTimeErrorCode NON_CONSTANT_DEFAULT_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_DEFAULT_VALUE', 101, "Default values of an optional parameter must be constant");
 
   /**
    * 12.6 Lists: It is a compile time error if an element of a constant list literal is not a
    * compile-time constant.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = const CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 101, "'const' lists must have all constant values");
+  static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT = const CompileTimeErrorCode.con1('NON_CONSTANT_LIST_ELEMENT', 102, "'const' lists must have all constant values");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
    * literal is not a compile-time constant.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 102, "The keys in a map must be constant");
+  static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_KEY', 103, "The keys in a map must be constant");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an entry in a constant map
    * literal is not a compile-time constant.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 103, "The values in a 'const' map must be constant");
+  static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE = const CompileTimeErrorCode.con1('NON_CONSTANT_MAP_VALUE', 104, "The values in a 'const' map must be constant");
 
   /**
    * 11 Metadata: Metadata consists of a series of annotations, each of which begin with the
    * character @, followed by a constant expression that must be either a reference to a
    * compile-time constant variable, or a call to a constant constructor.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 104, "Annotation creation can use only 'const' constructor");
+  static const CompileTimeErrorCode NON_CONSTANT_ANNOTATION_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_CONSTANT_ANNOTATION_CONSTRUCTOR', 105, "Annotation creation can use only 'const' constructor");
 
   /**
    * 7.6.3 Constant Constructors: Any expression that appears within the initializer list of a
    * constant constructor must be a potentially constant expression, or a compile-time error occurs.
    */
-  static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = const CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 105, "Initializer expressions in constant constructors must be constants");
+  static const CompileTimeErrorCode NON_CONSTANT_VALUE_IN_INITIALIZER = const CompileTimeErrorCode.con1('NON_CONSTANT_VALUE_IN_INITIALIZER', 106, "Initializer expressions in constant constructors must be constants");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i> or if <i>m > n</i>.
@@ -1834,7 +1893,7 @@
    * @param requiredCount the expected number of required arguments
    * @param argumentCount the actual number of positional arguments given
    */
-  static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = const CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 106, "%d required argument(s) expected, but %d found");
+  static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS = const CompileTimeErrorCode.con1('NOT_ENOUGH_REQUIRED_ARGUMENTS', 107, "%d required argument(s) expected, but %d found");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -1842,17 +1901,17 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 107, "The generative constructor '%s' expected, but factory found");
+  static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('NON_GENERATIVE_CONSTRUCTOR', 108, "The generative constructor '%s' expected, but factory found");
 
   /**
    * 7.9 Superclasses: It is a compile-time error to specify an extends clause for class Object.
    */
-  static const CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = const CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 108, "");
+  static const CompileTimeErrorCode OBJECT_CANNOT_EXTEND_ANOTHER_CLASS = const CompileTimeErrorCode.con1('OBJECT_CANNOT_EXTEND_ANOTHER_CLASS', 109, "");
 
   /**
    * 7.1.1 Operators: It is a compile-time error to declare an optional parameter in an operator.
    */
-  static const CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = const CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 109, "Optional parameters are not allowed when defining an operator");
+  static const CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR = const CompileTimeErrorCode.con1('OPTIONAL_PARAMETER_IN_OPERATOR', 110, "Optional parameters are not allowed when defining an operator");
 
   /**
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a valid part
@@ -1860,25 +1919,25 @@
    *
    * @param uri the uri pointing to a non-library declaration
    */
-  static const CompileTimeErrorCode PART_OF_NON_PART = const CompileTimeErrorCode.con1('PART_OF_NON_PART', 110, "The included part '%s' must have a part-of directive");
+  static const CompileTimeErrorCode PART_OF_NON_PART = const CompileTimeErrorCode.con1('PART_OF_NON_PART', 111, "The included part '%s' must have a part-of directive");
 
   /**
    * 14.1 Imports: It is a compile-time error if the current library declares a top-level member
    * named <i>p</i>.
    */
-  static const CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = const CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 111, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
+  static const CompileTimeErrorCode PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER = const CompileTimeErrorCode.con1('PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER', 112, "The name '%s' is already used as an import prefix and cannot be used to name a top-level element");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the name of a named optional parameter
    * begins with an '_' character.
    */
-  static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = const CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 112, "Named optional parameters cannot start with an underscore");
+  static const CompileTimeErrorCode PRIVATE_OPTIONAL_PARAMETER = const CompileTimeErrorCode.con1('PRIVATE_OPTIONAL_PARAMETER', 113, "Named optional parameters cannot start with an underscore");
 
   /**
    * 12.1 Constants: It is a compile-time error if the value of a compile-time constant expression
    * depends on itself.
    */
-  static const CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = const CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 113, "");
+  static const CompileTimeErrorCode RECURSIVE_COMPILE_TIME_CONSTANT = const CompileTimeErrorCode.con1('RECURSIVE_COMPILE_TIME_CONSTANT', 114, "");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
@@ -1889,13 +1948,13 @@
    *
    * https://code.google.com/p/dart/issues/detail?id=954
    */
-  static const CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 114, "Cycle in redirecting generative constructors");
+  static const CompileTimeErrorCode RECURSIVE_CONSTRUCTOR_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_CONSTRUCTOR_REDIRECT', 115, "Cycle in redirecting generative constructors");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if a redirecting factory constructor redirects to
    * itself, either directly or indirectly via a sequence of redirections.
    */
-  static const CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 115, "Cycle in redirecting factory constructors");
+  static const CompileTimeErrorCode RECURSIVE_FACTORY_REDIRECT = const CompileTimeErrorCode.con1('RECURSIVE_FACTORY_REDIRECT', 116, "Cycle in redirecting factory constructors");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1908,7 +1967,7 @@
    * @param className the name of the class that implements itself recursively
    * @param strImplementsPath a string representation of the implements loop
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 116, "'%s' cannot be a superinterface of itself: %s");
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE', 117, "'%s' cannot be a superinterface of itself: %s");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1920,7 +1979,7 @@
    *
    * @param className the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 117, "'%s' cannot extend itself");
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS', 118, "'%s' cannot extend itself");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the interface of a class <i>C</i> is a
@@ -1932,43 +1991,48 @@
    *
    * @param className the name of the class that implements itself recursively
    */
-  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 118, "'%s' cannot implement itself");
+  static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS = const CompileTimeErrorCode.con1('RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS', 119, "'%s' cannot implement itself");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
    * <i>k'</i> is not a constant constructor.
    */
-  static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 119, "The constructor '%s' could not be found in '%s'");
+  static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_MISSING_CONSTRUCTOR', 120, "The constructor '%s' could not be found in '%s'");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
    * <i>k'</i> is not a constant constructor.
    */
-  static const CompileTimeErrorCode REDIRECT_TO_NON_CLASS = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CLASS', 120, "The name '%s' is not a type and cannot be used in a redirected constructor");
+  static const CompileTimeErrorCode REDIRECT_TO_NON_CLASS = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CLASS', 121, "The name '%s' is not a type and cannot be used in a redirected constructor");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with the const modifier but
    * <i>k'</i> is not a constant constructor.
    */
-  static const CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 121, "Constant factory constructor cannot delegate to a non-constant constructor");
+  static const CompileTimeErrorCode REDIRECT_TO_NON_CONST_CONSTRUCTOR = const CompileTimeErrorCode.con1('REDIRECT_TO_NON_CONST_CONSTRUCTOR', 122, "Constant factory constructor cannot delegate to a non-constant constructor");
 
   /**
    * 5 Variables: A local variable may only be referenced at a source code location that is after
    * its initializer, if any, is complete, or a compile-time error occurs.
    */
-  static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION = const CompileTimeErrorCode.con1('REFERENCED_BEFORE_DECLARATION', 122, "Local variables cannot be referenced before they are declared");
+  static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION = const CompileTimeErrorCode.con1('REFERENCED_BEFORE_DECLARATION', 123, "Local variables cannot be referenced before they are declared");
 
   /**
    * 12.8.1 Rethrow: It is a compile-time error if an expression of the form <i>rethrow;</i> is not
    * enclosed within a on-catch clause.
    */
-  static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = const CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 123, "rethrow must be inside of a catch clause");
+  static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = const CompileTimeErrorCode.con1('RETHROW_OUTSIDE_CATCH', 124, "rethrow must be inside of a catch clause");
 
   /**
    * 13.12 Return: It is a compile-time error if a return statement of the form <i>return e;</i>
    * appears in a generative constructor.
    */
-  static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 124, "Constructors cannot return a value");
+  static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode.con1('RETURN_IN_GENERATIVE_CONSTRUCTOR', 125, "Constructors cannot return a value");
+
+  /**
+   * Speculative.
+   */
+  static const CompileTimeErrorCode SHARED_DEFERRED_PREFIX = const CompileTimeErrorCode.con1('SHARED_DEFERRED_PREFIX', 126, "The prefix of a deferred import cannot be used in other import directives");
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -1978,19 +2042,19 @@
    * initializer list, in class Object, in a factory constructor, or in a static method or variable
    * initializer.
    */
-  static const CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = const CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 125, "Invalid context for 'super' invocation");
+  static const CompileTimeErrorCode SUPER_IN_INVALID_CONTEXT = const CompileTimeErrorCode.con1('SUPER_IN_INVALID_CONTEXT', 127, "Invalid context for 'super' invocation");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting, in which case its
    * only action is to invoke another generative constructor.
    */
-  static const CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = const CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 126, "The redirecting constructor cannot have a 'super' initializer");
+  static const CompileTimeErrorCode SUPER_IN_REDIRECTING_CONSTRUCTOR = const CompileTimeErrorCode.con1('SUPER_IN_REDIRECTING_CONSTRUCTOR', 128, "The redirecting constructor cannot have a 'super' initializer");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It is a compile-time
    * error if a generative constructor of class Object includes a superinitializer.
    */
-  static const CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = const CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 127, "");
+  static const CompileTimeErrorCode SUPER_INITIALIZER_IN_OBJECT = const CompileTimeErrorCode.con1('SUPER_INITIALIZER_IN_OBJECT', 129, "");
 
   /**
    * 12.11 Instance Creation: It is a static type warning if any of the type arguments to a
@@ -2009,19 +2073,19 @@
    * @param boundingTypeName the name of the bounding type
    * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
    */
-  static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = const CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 128, "'%s' does not extend '%s'");
+  static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS = const CompileTimeErrorCode.con1('TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', 130, "'%s' does not extend '%s'");
 
   /**
    * 15.3.1 Typedef: Any self reference, either directly, or recursively via another typedef, is a
    * compile time error.
    */
-  static const CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = const CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 129, "Type alias cannot reference itself directly or recursively via another typedef");
+  static const CompileTimeErrorCode TYPE_ALIAS_CANNOT_REFERENCE_ITSELF = const CompileTimeErrorCode.con1('TYPE_ALIAS_CANNOT_REFERENCE_ITSELF', 131, "Type alias cannot reference itself directly or recursively via another typedef");
 
   /**
    * 12.11.2 Const: It is a compile-time error if <i>T</i> is not a class accessible in the current
    * scope, optionally followed by type arguments.
    */
-  static const CompileTimeErrorCode UNDEFINED_CLASS = const CompileTimeErrorCode.con1('UNDEFINED_CLASS', 130, "Undefined class '%s'");
+  static const CompileTimeErrorCode UNDEFINED_CLASS = const CompileTimeErrorCode.con1('UNDEFINED_CLASS', 132, "Undefined class '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -2029,7 +2093,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 131, "The class '%s' does not have a generative constructor '%s'");
+  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER', 133, "The class '%s' does not have a generative constructor '%s'");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the superinitializer appears
@@ -2037,7 +2101,7 @@
    * a compile-time error if class <i>S</i> does not declare a generative constructor named <i>S</i>
    * (respectively <i>S.id</i>)
    */
-  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 132, "The class '%s' does not have a default generative constructor");
+  static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode.con1('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT', 134, "The class '%s' does not have a default generative constructor");
 
   /**
    * 12.14.3 Unqualified Invocation: If there exists a lexically visible declaration named
@@ -2047,7 +2111,7 @@
    *
    * @param methodName the name of the method that is undefined
    */
-  static const CompileTimeErrorCode UNDEFINED_FUNCTION = const CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 133, "The function '%s' is not defined");
+  static const CompileTimeErrorCode UNDEFINED_FUNCTION = const CompileTimeErrorCode.con1('UNDEFINED_FUNCTION', 135, "The function '%s' is not defined");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>, <i>1<=i<=l</i>,
@@ -2059,7 +2123,7 @@
    *
    * @param name the name of the requested named parameter
    */
-  static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = const CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 134, "The named parameter '%s' is not defined");
+  static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER = const CompileTimeErrorCode.con1('UNDEFINED_NAMED_PARAMETER', 136, "The named parameter '%s' is not defined");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at the specified URI is
@@ -2074,7 +2138,7 @@
    * @param uri the URI pointing to a non-existent file
    * @see #INVALID_URI
    */
-  static const CompileTimeErrorCode URI_DOES_NOT_EXIST = const CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 135, "Target of URI does not exist: '%s'");
+  static const CompileTimeErrorCode URI_DOES_NOT_EXIST = const CompileTimeErrorCode.con1('URI_DOES_NOT_EXIST', 137, "Target of URI does not exist: '%s'");
 
   /**
    * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time constant, or if
@@ -2086,7 +2150,7 @@
    * 14.5 URIs: It is a compile-time error if the string literal <i>x</i> that describes a URI is
    * not a compile-time constant, or if <i>x</i> involves string interpolation.
    */
-  static const CompileTimeErrorCode URI_WITH_INTERPOLATION = const CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 136, "URIs cannot use string interpolation");
+  static const CompileTimeErrorCode URI_WITH_INTERPOLATION = const CompileTimeErrorCode.con1('URI_WITH_INTERPOLATION', 138, "URIs cannot use string interpolation");
 
   /**
    * 7.1.1 Operators: It is a compile-time error if the arity of the user-declared operator []= is
@@ -2099,7 +2163,7 @@
    * @param expectedNumberOfParameters the number of parameters expected
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 137, "Operator '%s' should declare exactly %d parameter(s), but %d found");
+  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR', 139, "Operator '%s' should declare exactly %d parameter(s), but %d found");
 
   /**
    * 7.1.1 Operators: It is a compile time error if the arity of the user-declared operator - is not
@@ -2107,13 +2171,13 @@
    *
    * @param actualNumberOfParameters the number of parameters found in the operator declaration
    */
-  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 138, "Operator '-' should declare 0 or 1 parameter, but %d found");
+  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS', 140, "Operator '-' should declare 0 or 1 parameter, but %d found");
 
   /**
    * 7.3 Setters: It is a compile-time error if a setter's formal parameter list does not include
    * exactly one required formal parameter <i>p</i>.
    */
-  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 139, "Setters should declare exactly one required parameter");
+  static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER = const CompileTimeErrorCode.con1('WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER', 141, "Setters should declare exactly one required parameter");
 
   static const List<CompileTimeErrorCode> values = const [
       AMBIGUOUS_EXPORT,
@@ -2178,6 +2242,7 @@
       IMPLEMENTS_REPEATED,
       IMPLEMENTS_SUPER_CLASS,
       IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+      IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
       IMPORT_INTERNAL_LIBRARY,
       IMPORT_OF_NON_LIBRARY,
       INCONSISTENT_CASE_EXPRESSION_TYPES,
@@ -2241,6 +2306,7 @@
       REFERENCED_BEFORE_DECLARATION,
       RETHROW_OUTSIDE_CATCH,
       RETURN_IN_GENERATIVE_CONSTRUCTOR,
+      SHARED_DEFERRED_PREFIX,
       SUPER_IN_INVALID_CONTEXT,
       SUPER_IN_REDIRECTING_CONSTRUCTOR,
       SUPER_INITIALIZER_IN_OBJECT,
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
index 7777598..2b26d5b 100644
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ b/pkg/analyzer/lib/src/generated/html.dart
@@ -1253,6 +1253,22 @@
   }
 
   /**
+   * Answer the offset of the value after the leading quote.
+   *
+   * @return the offset of the value, or `-1` if the value is not specified
+   */
+  int get textOffset {
+    if (_value == null) {
+      return -1;
+    }
+    String text = _value.lexeme;
+    if (StringUtilities.startsWithChar(text, 0x22) || StringUtilities.startsWithChar(text, 0x27)) {
+      return _value.offset + 1;
+    }
+    return _value.offset;
+  }
+
+  /**
    * Answer the attribute value token. A properly formed value will start and end with matching
    * quote characters, but the value returned may not be properly formed.
    *
diff --git a/pkg/analyzer/lib/src/generated/index.dart b/pkg/analyzer/lib/src/generated/index.dart
index 544f582..4eda02c 100644
--- a/pkg/analyzer/lib/src/generated/index.dart
+++ b/pkg/analyzer/lib/src/generated/index.dart
@@ -17,6 +17,7 @@
 import 'resolver.dart' show Namespace, NamespaceBuilder;
 import 'engine.dart';
 import 'html.dart' as ht;
+import 'utilities_collection.dart';
 
 /**
  * Instances of the [RemoveSourceOperation] implement an operation that removes from the index
@@ -1504,9 +1505,9 @@
       importElementsMap[importElement] = elements;
     }
     // use import namespace to choose correct one
-    for (MapEntry<ImportElement, Set<Element>> entry in getMapEntrySet(importElementsMap)) {
-      if (entry.getValue().contains(usedElement)) {
-        return entry.getKey();
+    for (MapIterator<ImportElement, Set<Element>> iter = SingleMapIterator.forMap(importElementsMap); iter.moveNext();) {
+      if (iter.value.contains(usedElement)) {
+        return iter.key;
       }
     }
     // not found
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index f523e8f..3ce0ec1 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -174,6 +174,11 @@
 }
 
 class ArrayUtils {
+  static List add(List target, Object value) {
+    target = new List.from(target);
+    target.add(value);
+    return target;
+  }
   static List addAll(List target, List source) {
     List result = new List.from(target);
     result.addAll(source);
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 0957f27..1e1e445 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -103,6 +103,9 @@
     }
     return false;
   }
+  bool isExecutable() {
+    return _newFile().statSync().mode & 0x111 != 0;
+  }
   bool isFile() {
     return _newFile().existsSync();
   }
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 9b9dc17..2721627 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -4915,15 +4915,21 @@
   ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
     Token importKeyword = _expectKeyword(Keyword.IMPORT);
     StringLiteral libraryUri = parseStringLiteral();
+    Token deferredToken = null;
     Token asToken = null;
     SimpleIdentifier prefix = null;
+    if (_matchesKeyword(Keyword.DEFERRED)) {
+      deferredToken = andAdvance;
+    }
     if (_matchesKeyword(Keyword.AS)) {
       asToken = andAdvance;
       prefix = parseSimpleIdentifier();
+    } else if (deferredToken != null) {
+      _reportErrorForCurrentToken(ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT, []);
     }
     List<Combinator> combinators = _parseCombinators();
     Token semicolon = _expectSemicolon();
-    return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon);
+    return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.metadata, importKeyword, libraryUri, deferredToken, asToken, prefix, combinators, semicolon);
   }
 
   /**
@@ -6441,7 +6447,7 @@
    * @param arguments the arguments to the error, used to compose the error message
    */
   void _reportErrorForToken(ParserErrorCode errorCode, Token token, List<Object> arguments) {
-    _reportError(new AnalysisError.con2(_source, token.offset, token.length, errorCode, arguments));
+    _reportError(new AnalysisError.con2(_source, token.offset, Math.max(token.length, 1), errorCode, arguments));
   }
 
   /**
@@ -7497,107 +7503,109 @@
 
   static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 80, "Library directives must include a library name");
 
-  static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 81, "Expected a statement");
+  static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT = const ParserErrorCode.con3('MISSING_PREFIX_IN_DEFERRED_IMPORT', 81, "Deferred imports must have a prefix");
 
-  static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 82, "There is no '%s' to close the parameter group");
+  static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 82, "Expected a statement");
 
-  static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 83, "Type aliases for functions must have an explicit list of parameters");
+  static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 83, "There is no '%s' to close the parameter group");
 
-  static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 84, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+  static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 84, "Type aliases for functions must have an explicit list of parameters");
 
-  static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 85, "Cannot have both positional and named parameters in a single parameter list");
+  static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 85, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
 
-  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 86, "Each class definition can have at most one extends clause");
+  static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 86, "Cannot have both positional and named parameters in a single parameter list");
 
-  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 87, "Each class definition can have at most one implements clause");
+  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 87, "Each class definition can have at most one extends clause");
 
-  static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 88, "Only one library directive may be declared in a file");
+  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 88, "Each class definition can have at most one implements clause");
 
-  static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 89, "Cannot have multiple groups of named parameters in a single parameter list");
+  static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 89, "Only one library directive may be declared in a file");
 
-  static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 90, "Only one part-of directive may be declared in a file");
+  static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 90, "Cannot have multiple groups of named parameters in a single parameter list");
 
-  static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 91, "Cannot have multiple groups of positional parameters in a single parameter list");
+  static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 91, "Only one part-of directive may be declared in a file");
 
-  static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 92, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+  static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 92, "Cannot have multiple groups of positional parameters in a single parameter list");
 
-  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 93, "Each class definition can have at most one with clause");
+  static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 93, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
 
-  static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 94, "Function expressions cannot be named");
+  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 94, "Each class definition can have at most one with clause");
 
-  static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 95, "Named parameters must be enclosed in curly braces ('{' and '}')");
+  static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 95, "Function expressions cannot be named");
 
-  static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 96, "Native clause can only be used in the SDK and code that is loaded through native extensions");
+  static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 96, "Named parameters must be enclosed in curly braces ('{' and '}')");
 
-  static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 97, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
+  static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 97, "Native clause can only be used in the SDK and code that is loaded through native extensions");
 
-  static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 98, "Only constructors can be declared to be a 'factory'");
+  static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 98, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
 
-  static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 99, "The name of a library must be an identifier");
+  static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 99, "Only constructors can be declared to be a 'factory'");
 
-  static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 100, "The part-of directive must be the only directive in a part");
+  static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 100, "The name of a library must be an identifier");
 
-  static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 101, "The operator '%s' is not user definable");
+  static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 101, "The part-of directive must be the only directive in a part");
 
-  static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 102, "Normal parameters must occur before optional parameters");
+  static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 102, "The operator '%s' is not user definable");
 
-  static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 103, "Positional arguments must occur before named arguments");
+  static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 103, "Normal parameters must occur before optional parameters");
 
-  static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 104, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+  static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 104, "Positional arguments must occur before named arguments");
 
-  static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 105, "Only factory constructor can specify '=' redirection.");
+  static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 105, "Positional parameters must be enclosed in square brackets ('[' and ']')");
 
-  static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 106, "Setters cannot be defined within methods or functions");
+  static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 106, "Only factory constructor can specify '=' redirection.");
 
-  static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 107, "The modifier 'static' should be before the modifier 'const'");
+  static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 107, "Setters cannot be defined within methods or functions");
 
-  static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 108, "The modifier 'static' should be before the modifier 'final'");
+  static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 108, "The modifier 'static' should be before the modifier 'const'");
 
-  static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 109, "The modifier 'static' should be before the modifier 'var'");
+  static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 109, "The modifier 'static' should be before the modifier 'final'");
 
-  static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 110, "Constructors cannot be static");
+  static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 110, "The modifier 'static' should be before the modifier 'var'");
 
-  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 111, "A 'static' getter must have a body");
+  static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 111, "Constructors cannot be static");
 
-  static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 112, "Operators cannot be static");
+  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 112, "A 'static' getter must have a body");
 
-  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 113, "A 'static' setter must have a body");
+  static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 113, "Operators cannot be static");
 
-  static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 114, "Top-level declarations cannot be declared to be 'static'");
+  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 114, "A 'static' setter must have a body");
 
-  static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 115, "The 'default' case should be the last case in a switch statement");
+  static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 115, "Top-level declarations cannot be declared to be 'static'");
 
-  static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 116, "The 'default' case can only be declared once");
+  static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 116, "The 'default' case should be the last case in a switch statement");
 
-  static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 117, "Operators must be declared within a class");
+  static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 117, "The 'default' case can only be declared once");
 
-  static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 118, "There is no '%s' to open a parameter group");
+  static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 118, "Operators must be declared within a class");
 
-  static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 119, "Unexpected token '%s'");
+  static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 119, "There is no '%s' to open a parameter group");
 
-  static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 120, "The extends clause must be before the with clause");
+  static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 120, "Unexpected token '%s'");
 
-  static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 121, "The with clause cannot be used without an extends clause");
+  static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 121, "The extends clause must be before the with clause");
 
-  static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 122, "The default value of a named parameter should be preceeded by ':'");
+  static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 122, "The with clause cannot be used without an extends clause");
 
-  static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 123, "The default value of a positional parameter should be preceeded by '='");
+  static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 123, "The default value of a named parameter should be preceeded by ':'");
 
-  static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 124, "Expected '%s' to close parameter group");
+  static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 124, "The default value of a positional parameter should be preceeded by '='");
 
-  static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 125, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
+  static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 125, "Expected '%s' to close parameter group");
 
-  static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 126, "The keyword 'var' cannot be used as a type name");
+  static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 126, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
 
-  static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 127, "Classes cannot be declared to be 'var'");
+  static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 127, "The keyword 'var' cannot be used as a type name");
 
-  static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 128, "The return type cannot be 'var'");
+  static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 128, "Classes cannot be declared to be 'var'");
 
-  static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 129, "Type aliases cannot be declared to be 'var'");
+  static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 129, "The return type cannot be 'var'");
 
-  static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 130, "Parameters cannot have a type of 'void'");
+  static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 130, "Type aliases cannot be declared to be 'var'");
 
-  static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 131, "Variables cannot have a type of 'void'");
+  static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 131, "Parameters cannot have a type of 'void'");
+
+  static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 132, "Variables cannot have a type of 'void'");
 
   static const List<ParserErrorCode> values = const [
       ABSTRACT_CLASS_MEMBER,
@@ -7681,6 +7689,7 @@
       MISSING_KEYWORD_OPERATOR,
       MISSING_NAME_IN_LIBRARY_DIRECTIVE,
       MISSING_NAME_IN_PART_OF_DIRECTIVE,
+      MISSING_PREFIX_IN_DEFERRED_IMPORT,
       MISSING_STATEMENT,
       MISSING_TERMINATOR_FOR_PARAMETER_GROUP,
       MISSING_TYPEDEF_PARAMETERS,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 44dcd88..3572534 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -16,6 +16,7 @@
 import 'scanner.dart' as sc;
 import 'utilities_dart.dart';
 import 'utilities_general.dart';
+import 'utilities_collection.dart';
 import 'ast.dart';
 import 'parser.dart' show Parser, ParserErrorCode;
 import 'sdk.dart' show DartSdk, SdkLibrary;
@@ -242,11 +243,6 @@
   ClassElementImpl _classElement;
 
   /**
-   * The [ToolkitObjectElement]s to set for [classElement].
-   */
-  List<ToolkitObjectElement> _classToolkitObjects = [];
-
-  /**
    * The [Annotation] that is currently being analyzed.
    */
   Annotation _annotation;
@@ -270,7 +266,6 @@
       if (unitMember is ClassDeclaration) {
         this._classDeclaration = unitMember;
         this._classElement = _classDeclaration.element as ClassElementImpl;
-        this._classToolkitObjects.clear();
         // process annotations
         NodeList<Annotation> annotations = _classDeclaration.metadata;
         for (Annotation annotation in annotations) {
@@ -300,11 +295,6 @@
             continue;
           }
         }
-        // set toolkit objects
-        if (!_classToolkitObjects.isEmpty) {
-          List<ToolkitObjectElement> objects = _classToolkitObjects;
-          _classElement.toolkitObjects = new List.from(objects);
-        }
       }
     }
   }
@@ -414,7 +404,7 @@
       element.styleUriOffset = styleUriOffset;
       element.properties = _parseNgComponentProperties();
       element.scopeProperties = _parseScopeProperties();
-      _classToolkitObjects.add(element);
+      _classElement.addToolkitObjects(element);
     }
   }
 
@@ -566,7 +556,7 @@
       int nameOffset = _getStringArgumentOffset(_PUBLISH_AS);
       AngularControllerElementImpl element = new AngularControllerElementImpl(name, nameOffset);
       element.selector = selector;
-      _classToolkitObjects.add(element);
+      _classElement.addToolkitObjects(element);
     }
   }
 
@@ -591,7 +581,7 @@
       AngularDirectiveElementImpl element = new AngularDirectiveElementImpl(offset);
       element.selector = selector;
       element.properties = _parseNgComponentProperties();
-      _classToolkitObjects.add(element);
+      _classElement.addToolkitObjects(element);
     }
   }
 
@@ -606,7 +596,7 @@
     if (isValid) {
       String name = _getStringArgument(_NAME);
       int nameOffset = _getStringArgumentOffset(_NAME);
-      _classToolkitObjects.add(new AngularFilterElementImpl(name, nameOffset));
+      _classElement.addToolkitObjects(new AngularFilterElementImpl(name, nameOffset));
     }
   }
 
@@ -2206,20 +2196,120 @@
 }
 
 /**
+ * Instances of the class `PolymerCompilationUnitBuilder` build a Polymer specific element
+ * model for a single compilation unit.
+ */
+class PolymerCompilationUnitBuilder {
+  static String _CUSTOM_TAG = "CustomTag";
+
+  static Element getElement(AstNode node, int offset) {
+    // maybe node is not SimpleStringLiteral
+    if (node is! SimpleStringLiteral) {
+      return null;
+    }
+    SimpleStringLiteral literal = node as SimpleStringLiteral;
+    // maybe has PolymerElement
+    {
+      Element element = literal.toolkitElement;
+      if (element is PolymerElement) {
+        return element;
+      }
+    }
+    // no Element
+    return null;
+  }
+
+  /**
+   * The compilation unit with built Dart element models.
+   */
+  final CompilationUnit _unit;
+
+  /**
+   * The [ClassDeclaration] that is currently being analyzed.
+   */
+  ClassDeclaration _classDeclaration;
+
+  /**
+   * The [ClassElementImpl] that is currently being analyzed.
+   */
+  ClassElementImpl _classElement;
+
+  /**
+   * The [Annotation] that is currently being analyzed.
+   */
+  Annotation _annotation;
+
+  /**
+   * Initialize a newly created compilation unit element builder.
+   *
+   * @param unit the compilation unit with built Dart element models
+   */
+  PolymerCompilationUnitBuilder(this._unit);
+
+  /**
+   * Builds Polymer specific element models and adds them to the existing Dart elements.
+   */
+  void build() {
+    // process classes
+    for (CompilationUnitMember unitMember in _unit.declarations) {
+      if (unitMember is ClassDeclaration) {
+        this._classDeclaration = unitMember;
+        this._classElement = _classDeclaration.element as ClassElementImpl;
+        // process annotations
+        NodeList<Annotation> annotations = _classDeclaration.metadata;
+        for (Annotation annotation in annotations) {
+          // verify annotation
+          if (annotation.arguments == null) {
+            continue;
+          }
+          this._annotation = annotation;
+          // @CustomTag
+          if (_isAnnotation(annotation, _CUSTOM_TAG)) {
+            _parseCustomTag();
+            continue;
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Checks if given [Annotation] is an annotation with required name.
+   */
+  bool _isAnnotation(Annotation annotation, String name) {
+    Element element = annotation.element;
+    if (element is ConstructorElement) {
+      ConstructorElement constructorElement = element;
+      return constructorElement.returnType.displayName == name;
+    }
+    return false;
+  }
+
+  void _parseCustomTag() {
+    List<Expression> arguments = _annotation.arguments.arguments;
+    if (arguments.length == 1) {
+      Expression nameExpression = arguments[0];
+      if (nameExpression is SimpleStringLiteral) {
+        SimpleStringLiteral nameLiteral = nameExpression;
+        String name = nameLiteral.value;
+        int nameOffset = nameLiteral.valueOffset;
+        PolymerTagDartElementImpl element = new PolymerTagDartElementImpl(name, nameOffset, _classElement);
+        _classElement.addToolkitObjects(element);
+        nameLiteral.toolkitElement = element;
+      }
+    }
+  }
+}
+
+/**
  * Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
  * violations of Dart best practices.
  */
 class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
-  static String _GETTER = "getter";
-
   static String _HASHCODE_GETTER_NAME = "hashCode";
 
-  static String _METHOD = "method";
-
   static String _NULL_TYPE_NAME = "Null";
 
-  static String _SETTER = "setter";
-
   static String _TO_INT_METHOD_NAME = "toInt";
 
   /**
@@ -2273,10 +2363,11 @@
   @override
   Object visitAssignmentExpression(AssignmentExpression node) {
     sc.TokenType operatorType = node.operator.type;
-    if (operatorType != sc.TokenType.EQ) {
-      _checkForDeprecatedMemberUse(node.bestElement, node);
-    } else {
+    if (operatorType == sc.TokenType.EQ) {
       _checkForUseOfVoidResult(node.rightHandSide);
+      _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
+    } else {
+      _checkForDeprecatedMemberUse(node.bestElement, node);
     }
     return super.visitAssignmentExpression(node);
   }
@@ -2378,6 +2469,7 @@
   @override
   Object visitVariableDeclaration(VariableDeclaration node) {
     _checkForUseOfVoidResult(node.initializer);
+    _checkForInvalidAssignment(node.name, node.initializer);
     return super.visitVariableDeclaration(node);
   }
 
@@ -2623,6 +2715,44 @@
   }
 
   /**
+   * This verifies that the passed left hand side and right hand side represent a valid assignment.
+   *
+   * This method corresponds to ErrorVerifier.checkForInvalidAssignment.
+   *
+   * @param lhs the left hand side expression
+   * @param rhs the right hand side expression
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see HintCode#INVALID_ASSIGNMENT
+   */
+  bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
+    if (lhs == null || rhs == null) {
+      return false;
+    }
+    VariableElement leftElement = ErrorVerifier.getVariableElement(lhs);
+    DartType leftType = (leftElement == null) ? ErrorVerifier.getStaticType(lhs) : leftElement.type;
+    DartType staticRightType = ErrorVerifier.getStaticType(rhs);
+    if (!staticRightType.isAssignableTo(leftType)) {
+      // The warning was generated on this rhs
+      return false;
+    }
+    // Test for, and then generate the hint
+    DartType bestRightType = rhs.bestType;
+    if (leftType != null && bestRightType != null) {
+      if (!bestRightType.isAssignableTo(leftType)) {
+        String leftName = leftType.displayName;
+        String rightName = bestRightType.displayName;
+        if (leftName == rightName) {
+          leftName = ErrorVerifier.getExtendedDisplayName(leftType);
+          rightName = ErrorVerifier.getExtendedDisplayName(bestRightType);
+        }
+        _errorReporter.reportErrorForNode(HintCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
    * Generate a hint for functions or methods that have a return type, but do not have a return
    * statement on all branches. At the end of blocks with no return, Dart implicitly returns
    * `null`, avoiding these implicit returns is considered a best practice.
@@ -2680,75 +2810,6 @@
   }
 
   /**
-   * Checks that if the passed method declaration is private, it does not override a private member
-   * in a superclass.
-   *
-   * @param node the method declaration to check
-   * @return `true` if and only if a hint code is generated on the passed node
-   * @see HintCode#OVERRIDDING_PRIVATE_MEMBER
-   */
-  bool _checkForOverridingPrivateMember(MethodDeclaration node) {
-    // If not in an enclosing class, return false
-    if (_enclosingClass == null) {
-      return false;
-    }
-    // If the member is not private, return false
-    if (!Identifier.isPrivateName(node.name.name)) {
-      return false;
-    }
-    // Get the element of the member, if null, return false
-    ExecutableElement executableElement = node.element;
-    if (executableElement == null) {
-      return false;
-    }
-    // Loop through all of the superclasses looking for a matching method or accessor
-    // TODO(jwren) If the HintGenerator needs or has easy access to the InheritanceManager in the
-    // future then this could be refactored down to be more readable, however, since we are only
-    // looking through super classes (and not the entire interface graph) there is no pressing need
-    String elementName = executableElement.name;
-    bool isGetterOrSetter = executableElement is PropertyAccessorElement;
-    InterfaceType superType = _enclosingClass.supertype;
-    if (superType == null) {
-      return false;
-    }
-    ClassElement classElement = superType.element;
-    while (classElement != null) {
-      if (_enclosingClass.library != classElement.library) {
-        if (isGetterOrSetter) {
-          PropertyAccessorElement overriddenAccessor = null;
-          List<PropertyAccessorElement> accessors = classElement.accessors;
-          for (PropertyAccessorElement propertyAccessorElement in accessors) {
-            if (elementName == propertyAccessorElement.name) {
-              overriddenAccessor = propertyAccessorElement;
-              break;
-            }
-          }
-          if (overriddenAccessor != null) {
-            String memberType = (executableElement as PropertyAccessorElement).isGetter ? _GETTER : _SETTER;
-            _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
-                memberType,
-                executableElement.displayName,
-                classElement.displayName]);
-            return true;
-          }
-        } else {
-          MethodElement overriddenMethod = classElement.getMethod(elementName);
-          if (overriddenMethod != null) {
-            _errorReporter.reportErrorForNode(HintCode.OVERRIDDING_PRIVATE_MEMBER, node.name, [
-                _METHOD,
-                executableElement.displayName,
-                classElement.displayName]);
-            return true;
-          }
-        }
-      }
-      superType = classElement.supertype;
-      classElement = superType != null ? superType.element : null;
-    }
-    return false;
-  }
-
-  /**
    * Check for the passed as expression for the [HintCode#UNNECESSARY_CAST] hint code.
    *
    * @param node the as expression to check
@@ -3000,10 +3061,10 @@
           if (currentType.isObject) {
             // Found catch clause clause that has Object as an exception type, this is equivalent to
             // having a catch clause that doesn't have an exception type, visit the block, but
-             // generate an error on any following catch clauses (and don't visit them).
+            // generate an error on any following catch clauses (and don't visit them).
             _safelyVisit(catchClause);
             if (i + 1 != numOfCatchClauses) {
-               // this catch clause is not the last in the try statement
+              // this catch clause is not the last in the try statement
               CatchClause nextCatchClause = catchClauses[i + 1];
               CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
               int offset = nextCatchClause.offset;
@@ -3025,7 +3086,7 @@
         }
         _safelyVisit(catchClause);
       } else {
-         // Found catch clause clause that doesn't have an exception type, visit the block, but
+        // Found catch clause clause that doesn't have an exception type, visit the block, but
         // generate an error on any following catch clauses (and don't visit them).
         _safelyVisit(catchClause);
         if (i + 1 != numOfCatchClauses) {
@@ -3080,24 +3141,15 @@
     }
     // Don't consider situations where we could evaluate to a constant boolean expression with the
     // ConstantVisitor
-//
-       // else {
-//
-         // EvaluationResultImpl result = expression.accept(new ConstantVisitor());
-//
-         // if (result == ValidResult.RESULT_TRUE) {
-//
-           // return ValidResult.RESULT_TRUE;
-//
-         // } else if (result == ValidResult.RESULT_FALSE) {
-//
-           // return ValidResult.RESULT_FALSE;
-//
-         // }
-//
-         // return null;
-//
-       // }
+    //    else {
+    //      EvaluationResultImpl result = expression.accept(new ConstantVisitor());
+    //      if (result == ValidResult.RESULT_TRUE) {
+    //        return ValidResult.RESULT_TRUE;
+    //      } else if (result == ValidResult.RESULT_FALSE) {
+    //        return ValidResult.RESULT_FALSE;
+    //      }
+    //      return null;
+    //    }
     return null;
   }
 
@@ -8581,9 +8633,9 @@
     //
     // Loop through the entries in the unionMap, adding them to the resultMap appropriately.
     //
-    for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(unionMap)) {
-      String key = entry.getKey();
-      List<ExecutableElement> list = entry.getValue();
+    for (MapIterator<String, List<ExecutableElement>> iter = SingleMapIterator.forMap(unionMap); iter.moveNext();) {
+      String key = iter.key;
+      List<ExecutableElement> list = iter.value;
       int numOfEltsWithMatchingNames = list.length;
       if (numOfEltsWithMatchingNames == 1) {
         //
@@ -8659,12 +8711,30 @@
           } else {
             if (subtypesOfAllOtherTypesIndexes.isEmpty) {
               //
+              // Determine if the current class has a method or accessor with the member name, if it
+              // does then then this class does not "inherit" from any of the supertypes.
+              // See issue 16134.
+              //
+              bool classHasMember = false;
+              if (allMethods) {
+                classHasMember = classElt.getMethod(key) != null;
+              } else {
+                List<PropertyAccessorElement> accessors = classElt.accessors;
+                for (int i = 0; i < accessors.length; i++) {
+                  if (accessors[i].name == key) {
+                    classHasMember = true;
+                  }
+                }
+              }
+              //
               // Example: class A inherited only 2 method named 'm'. One has the function type
               // '() -> int' and one has the function type '() -> String'. Since neither is a subtype
               // of the other, we create a warning, and have this class inherit nothing.
               //
-              String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
-              _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+              if (!classHasMember) {
+                String firstTwoFuntionTypesStr = "${executableElementTypes[0].toString()}, ${executableElementTypes[1].toString()}";
+                _reportError(classElt, classElt.nameOffset, classElt.displayName.length, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key, firstTwoFuntionTypesStr]);
+              }
             } else {
               //
               // Example: class A inherits 2 methods named 'm'. One has the function type
@@ -9725,6 +9795,7 @@
               importElement.uriOffset = uriLiteral.offset;
               importElement.uriEnd = uriLiteral.end;
               importElement.uri = uriContent;
+              importElement.deferred = importDirective.deferredToken != null;
               importElement.combinators = _buildCombinators(importDirective);
               LibraryElement importedLibraryElement = importedLibrary.libraryElement;
               if (importedLibraryElement != null) {
@@ -10074,6 +10145,16 @@
     } finally {
       timeCounter.stop();
     }
+    // Polymer
+    timeCounter = PerformanceStatistics.polymer.start();
+    try {
+      for (Source source in library.compilationUnitSources) {
+        CompilationUnit ast = library.getAST(source);
+        new PolymerCompilationUnitBuilder(ast).build();
+      }
+    } finally {
+      timeCounter.stop();
+    }
   }
 
   /**
@@ -10296,6 +10377,7 @@
                 importElement.uriEnd = uriLiteral.end;
               }
               importElement.uri = uriContent;
+              importElement.deferred = importDirective.deferredToken != null;
               importElement.combinators = _buildCombinators(importDirective);
               LibraryElement importedLibraryElement = importedLibrary.libraryElement;
               if (importedLibraryElement != null) {
@@ -10505,6 +10587,16 @@
     } finally {
       timeCounter.stop();
     }
+    // Polymer
+    timeCounter = PerformanceStatistics.polymer.start();
+    try {
+      for (Source source in library.compilationUnitSources) {
+        CompilationUnit ast = library.getAST(source);
+        new PolymerCompilationUnitBuilder(ast).build();
+      }
+    } finally {
+      timeCounter.stop();
+    }
   }
 }
 
@@ -14902,8 +14994,8 @@
    * @param overrides the overrides to be applied
    */
   void applyOverrides(Map<Element, DartType> overrides) {
-    for (MapEntry<Element, DartType> entry in getMapEntrySet(overrides)) {
-      _overridenTypes[entry.getKey()] = entry.getValue();
+    for (MapIterator<Element, DartType> iter = SingleMapIterator.forMap(overrides); iter.moveNext();) {
+      _overridenTypes[iter.key] = iter.value;
     }
   }
 
@@ -17253,8 +17345,8 @@
    * @param namespace the namespace containing the names to be added to this namespace
    */
   void _addAllFromMap(Map<String, Element> definedNames, Map<String, Element> newNames) {
-    for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
-      definedNames[entry.getKey()] = entry.getValue();
+    for (MapIterator<String, Element> iter = SingleMapIterator.forMap(newNames); iter.moveNext();) {
+      definedNames[iter.key] = iter.value;
     }
   }
 
@@ -17336,8 +17428,8 @@
     if (prefixElement != null) {
       String prefix = prefixElement.name;
       Map<String, Element> newNames = new Map<String, Element>();
-      for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
-        newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
+      for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+        newNames["${prefix}.${iter.key}"] = iter.value;
       }
       return newNames;
     } else {
@@ -18086,6 +18178,56 @@
  */
 class ErrorVerifier extends RecursiveAstVisitor<Object> {
   /**
+   * Return a display name for the given type that includes the path to the compilation unit in
+   * which the type is defined.
+   *
+   * @param type the type for which an extended display name is to be returned
+   * @return a display name that can help distiguish between two types with the same name
+   */
+  static String getExtendedDisplayName(DartType type) {
+    Element element = type.element;
+    if (element != null) {
+      Source source = element.source;
+      if (source != null) {
+        return "${type.displayName} (${source.fullName})";
+      }
+    }
+    return type.displayName;
+  }
+
+  /**
+   * Return the static type of the given expression that is to be used for type analysis.
+   *
+   * @param expression the expression whose type is to be returned
+   * @return the static type of the given expression
+   */
+  static DartType getStaticType(Expression expression) {
+    DartType type = expression.staticType;
+    if (type == null) {
+      // TODO(brianwilkerson) This should never happen.
+      return DynamicTypeImpl.instance;
+    }
+    return type;
+  }
+
+  /**
+   * Return the variable element represented by the given expression, or `null` if there is no
+   * such element.
+   *
+   * @param expression the expression whose element is to be returned
+   * @return the variable element represented by the expression
+   */
+  static VariableElement getVariableElement(Expression expression) {
+    if (expression is Identifier) {
+      Element element = expression.staticElement;
+      if (element is VariableElement) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  /**
    * The error reporter by which errors will be reported.
    */
   final ErrorReporter _errorReporter;
@@ -18096,11 +18238,6 @@
   final LibraryElement _currentLibrary;
 
   /**
-   * The type representing the type 'dynamic'.
-   */
-  DartType _dynamicType;
-
-  /**
    * The type representing the type 'bool'.
    */
   InterfaceType _boolType;
@@ -18308,7 +18445,6 @@
     _isInInstanceVariableInitializer = false;
     _isInConstructorInitializer = false;
     _isInStaticMethod = false;
-    _dynamicType = _typeProvider.dynamicType;
     _boolType = _typeProvider.boolType;
     _intType = _typeProvider.intType;
     _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [
@@ -18334,8 +18470,7 @@
 
   @override
   Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.Token operator = node.operator;
-    sc.TokenType operatorType = operator.type;
+    sc.TokenType operatorType = node.operator.type;
     if (operatorType == sc.TokenType.EQ) {
       _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
     } else {
@@ -18400,9 +18535,9 @@
     try {
       _isInNativeClass = node.nativeClause != null;
       _enclosingClass = node.element;
-      WithClause withClause = node.withClause;
-      ImplementsClause implementsClause = node.implementsClause;
       ExtendsClause extendsClause = node.extendsClause;
+      ImplementsClause implementsClause = node.implementsClause;
+      WithClause withClause = node.withClause;
       _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME);
       _checkForMemberWithClassName();
       _checkForNoDefaultSuperConstructorImplicit(node);
@@ -18412,7 +18547,7 @@
         // Only check for all of the inheritance logic around clauses if there isn't an error code
         // such as "Cannot extend double" already on the class.
         if (!_checkForImplementsDisallowedClass(implementsClause) && !_checkForExtendsDisallowedClass(extendsClause) && !_checkForAllMixinErrorCodes(withClause)) {
-          _checkForNonAbstractClassInheritsAbstractMember(node);
+          _checkForNonAbstractClassInheritsAbstractMember(node.name);
           _checkForInconsistentMethodInheritance();
           _checkForRecursiveInterfaceInheritance(_enclosingClass);
           _checkForConflictingGetterAndMethod();
@@ -18446,14 +18581,16 @@
   @override
   Object visitClassTypeAlias(ClassTypeAlias node) {
     _checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
-    _checkForExtendsDisallowedClassInTypeAlias(node);
-    _checkForImplementsDisallowedClass(node.implementsClause);
-    _checkForAllMixinErrorCodes(node.withClause);
     ClassElement outerClassElement = _enclosingClass;
     try {
       _enclosingClass = node.element;
-      _checkForRecursiveInterfaceInheritance(node.element);
-      _checkForTypeAliasCannotReferenceItself_mixin(node);
+      // Only check for all of the inheritance logic around clauses if there isn't an error code
+      // such as "Cannot extend double" already on the class.
+      if (!_checkForExtendsDisallowedClassInTypeAlias(node) && !_checkForImplementsDisallowedClass(node.implementsClause) && !_checkForAllMixinErrorCodes(node.withClause)) {
+        _checkForRecursiveInterfaceInheritance(node.element);
+        _checkForTypeAliasCannotReferenceItself_mixin(node);
+        _checkForNonAbstractClassInheritsAbstractMember(node.name);
+      }
     } finally {
       _enclosingClass = outerClassElement;
     }
@@ -18471,6 +18608,12 @@
   }
 
   @override
+  Object visitCompilationUnit(CompilationUnit node) {
+    _checkForDeferredPrefixCollisions(node);
+    return super.visitCompilationUnit(node);
+  }
+
+  @override
   Object visitConditionalExpression(ConditionalExpression node) {
     _checkForNonBoolCondition(node.condition);
     return super.visitConditionalExpression(node);
@@ -18671,6 +18814,9 @@
     if (importElement != null) {
       _checkForImportDuplicateLibraryName(node, importElement);
       _checkForImportInternalLibrary(node, importElement);
+      if (importElement.isDeferred) {
+        _checkForLoadLibraryFunction(node, importElement);
+      }
     }
     return super.visitImportDirective(node);
   }
@@ -19073,9 +19219,9 @@
       }
     }
     // Visit all of the states in the map to ensure that none were never initialized.
-    for (MapEntry<FieldElement, INIT_STATE> entry in getMapEntrySet(fieldElementsMap)) {
-      if (entry.getValue() == INIT_STATE.NOT_INIT) {
-        FieldElement fieldElement = entry.getKey();
+    for (MapIterator<FieldElement, INIT_STATE> iter = SingleMapIterator.forMap(fieldElementsMap); iter.moveNext();) {
+      if (iter.value == INIT_STATE.NOT_INIT) {
+        FieldElement fieldElement = iter.key;
         if (fieldElement.isConst) {
           _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [fieldElement.name]);
           foundError = true;
@@ -19249,22 +19395,21 @@
       parameterIndex++;
     }
     // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
-    JavaIterator<MapEntry<String, DartType>> overriddenNamedPTIterator = new JavaIterator(getMapEntrySet(overriddenNamedPT));
-    while (overriddenNamedPTIterator.hasNext) {
-      MapEntry<String, DartType> overriddenNamedPTEntry = overriddenNamedPTIterator.next();
-      DartType overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()];
+    MapIterator<String, DartType> overriddenNamedPTIterator = SingleMapIterator.forMap(overriddenNamedPT);
+    while (overriddenNamedPTIterator.moveNext()) {
+      DartType overridingType = overridingNamedPT[overriddenNamedPTIterator.key];
       if (overridingType == null) {
         // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been created above if
         // this could be reached.
         continue;
       }
-      if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
+      if (!overriddenNamedPTIterator.value.isAssignableTo(overridingType)) {
         // lookup the parameter for the error to select
         ParameterElement parameterToSelect = null;
         AstNode parameterLocationToSelect = null;
         for (int i = 0; i < parameters.length; i++) {
           ParameterElement parameter = parameters[i];
-          if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTEntry.getKey() == parameter.name) {
+          if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedPTIterator.key == parameter.name) {
             parameterToSelect = parameter;
             parameterLocationToSelect = parameterLocations[i];
             break;
@@ -19273,7 +19418,7 @@
         if (parameterToSelect != null) {
           _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [
               overridingType.displayName,
-              overriddenNamedPTEntry.getValue().displayName,
+              overriddenNamedPTIterator.value.displayName,
               overriddenExecutable.enclosingElement.displayName]);
           return true;
         }
@@ -19611,9 +19756,9 @@
     // check exported names
     Namespace namespace = new NamespaceBuilder().createExportNamespaceForDirective(exportElement);
     Map<String, Element> definedNames = namespace.definedNames;
-    for (MapEntry<String, Element> definedEntry in getMapEntrySet(definedNames)) {
-      String name = definedEntry.getKey();
-      Element element = definedEntry.getValue();
+    for (MapIterator<String, Element> iter = SingleMapIterator.forMap(definedNames); iter.moveNext();) {
+      String name = iter.key;
+      Element element = iter.value;
       Element prevElement = _exportedElements[name];
       if (element != null && prevElement != null && prevElement != element) {
         _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [
@@ -19699,7 +19844,7 @@
    * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE
    * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE
    */
-  bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, _getStaticType(expression), errorCode);
+  bool _checkForArgumentTypeNotAssignableWithExpectedTypes(Expression expression, DartType expectedStaticType, ErrorCode errorCode) => _checkForArgumentTypeNotAssignable(expression, expectedStaticType, getStaticType(expression), errorCode);
 
   /**
    * This verifies that the passed arguments can be assigned to their corresponding parameters.
@@ -20552,6 +20697,47 @@
   }
 
   /**
+   * This verifies that any deferred imports in the given compilation unit have a unique prefix.
+   *
+   * @param node the compilation unit containing the imports to be checked
+   * @return `true` if an error was generated
+   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
+   */
+  bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
+    bool foundError = false;
+    NodeList<Directive> directives = node.directives;
+    int count = directives.length;
+    if (count > 0) {
+      Map<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new Map<PrefixElement, List<ImportDirective>>();
+      for (int i = 0; i < count; i++) {
+        Directive directive = directives[i];
+        if (directive is ImportDirective) {
+          ImportDirective importDirective = directive;
+          SimpleIdentifier prefix = importDirective.prefix;
+          if (prefix != null) {
+            Element element = prefix.staticElement;
+            if (element is PrefixElement) {
+              PrefixElement prefixElement = element;
+              List<ImportDirective> elements = prefixToDirectivesMap[prefixElement];
+              if (elements == null) {
+                elements = new List<ImportDirective>();
+                prefixToDirectivesMap[prefixElement] = elements;
+              }
+              elements.add(importDirective);
+            }
+          }
+        }
+      }
+      for (List<ImportDirective> imports in prefixToDirectivesMap.values) {
+        if (_hasDeferredPrefixCollision(imports)) {
+          foundError = true;
+        }
+      }
+    }
+    return foundError;
+  }
+
+  /**
    * This verifies that the enclosing class does not have an instance member with the given name of
    * the static member.
    *
@@ -20785,7 +20971,7 @@
       return false;
     }
     // test the static type of the expression
-    DartType staticType = _getStaticType(expression);
+    DartType staticType = getStaticType(expression);
     if (staticType == null) {
       return false;
     }
@@ -21159,31 +21345,19 @@
     if (lhs == null || rhs == null) {
       return false;
     }
-    VariableElement leftElement = _getVariableElement(lhs);
-    DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
-    DartType staticRightType = _getStaticType(rhs);
-    bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
-    if (!isStaticAssignable) {
+    VariableElement leftElement = getVariableElement(lhs);
+    DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
+    DartType staticRightType = getStaticType(rhs);
+    if (!staticRightType.isAssignableTo(leftType)) {
       String leftName = leftType.displayName;
       String rightName = staticRightType.displayName;
       if (leftName == rightName) {
-        leftName = _getExtendedDisplayName(leftType);
-        rightName = _getExtendedDisplayName(staticRightType);
+        leftName = getExtendedDisplayName(leftType);
+        rightName = getExtendedDisplayName(staticRightType);
       }
       _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightName, leftName]);
       return true;
     }
-    // TODO(brianwilkerson) Define a hint corresponding to the warning and report it if appropriate.
-    //    Type propagatedRightType = rhs.getPropagatedType();
-    //    boolean isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType);
-    //    if (!isStaticAssignable && !isPropagatedAssignable) {
-    //      errorReporter.reportError(
-    //          StaticTypeWarningCode.INVALID_ASSIGNMENT,
-    //          rhs,
-    //          staticRightType.getDisplayName(),
-    //          leftType.getDisplayName());
-    //      return true;
-    //    }
     return false;
   }
 
@@ -21200,8 +21374,8 @@
     if (lhs == null) {
       return false;
     }
-    VariableElement leftElement = _getVariableElement(lhs);
-    DartType leftType = (leftElement == null) ? _getStaticType(lhs) : leftElement.type;
+    VariableElement leftElement = getVariableElement(lhs);
+    DartType leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.type;
     MethodElement invokedMethod = node.staticElement;
     if (invokedMethod == null) {
       return false;
@@ -21214,8 +21388,8 @@
       String leftName = leftType.displayName;
       String rightName = rightType.displayName;
       if (leftName == rightName) {
-        leftName = _getExtendedDisplayName(leftType);
-        rightName = _getExtendedDisplayName(rightType);
+        leftName = getExtendedDisplayName(leftType);
+        rightName = getExtendedDisplayName(rightType);
       }
       _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT, node.rightHandSide, [rightName, leftName]);
       return true;
@@ -21316,6 +21490,26 @@
   }
 
   /**
+   * Check that the imported library does not define a loadLibrary function.
+   *
+   * @param node the import directive to evaluate
+   * @param importElement the [ImportElement] retrieved from the node
+   * @return `true` if and only if an error code is generated on the passed node
+   * @see CompileTimeErrorCode#IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION
+   */
+  bool _checkForLoadLibraryFunction(ImportDirective node, ImportElement importElement) {
+    LibraryElement importedLibrary = importElement.importedLibrary;
+    if (importedLibrary == null) {
+      return false;
+    }
+    if (importedLibrary.hasLoadLibraryFunction) {
+      _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node, [importedLibrary.name]);
+      return true;
+    }
+    return false;
+  }
+
+  /**
    * This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
    * key/value types specified in the type arguments.
    *
@@ -21657,7 +21851,8 @@
    * This checks that passed class declaration overrides all members required by its superclasses
    * and interfaces.
    *
-   * @param node the [ClassDeclaration] to evaluate
+   * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
+   *          either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
    * @return `true` if and only if an error code is generated on the passed node
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
@@ -21665,7 +21860,7 @@
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
    * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS
    */
-  bool _checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) {
+  bool _checkForNonAbstractClassInheritsAbstractMember(SimpleIdentifier classNameNode) {
     if (_enclosingClass.isAbstract) {
       return false;
     }
@@ -21673,8 +21868,6 @@
     // Store in local sets the set of all method and accessor names
     //
     List<MethodElement> methods = _enclosingClass.methods;
-    List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
-    Set<String> methodsInEnclosingClass = new Set<String>();
     for (MethodElement method in methods) {
       String methodName = method.name;
       // If the enclosing class declares the method noSuchMethod(), then return.
@@ -21684,11 +21877,6 @@
       if (methodName == ElementResolver.NO_SUCH_METHOD_METHOD_NAME) {
         return false;
       }
-      methodsInEnclosingClass.add(methodName);
-    }
-    Set<String> accessorsInEnclosingClass = new Set<String>();
-    for (PropertyAccessorElement accessor in accessors) {
-      accessorsInEnclosingClass.add(accessor.name);
     }
     Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
     //
@@ -21773,22 +21961,22 @@
     List<String> stringMembersArray = new List.from(stringMembersArrayListSet);
     AnalysisErrorWithProperties analysisError;
     if (stringMembersArray.length == 1) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, node.name, [stringMembersArray[0]]);
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE, classNameNode, [stringMembersArray[0]]);
     } else if (stringMembersArray.length == 2) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, node.name, [stringMembersArray[0], stringMembersArray[1]]);
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO, classNameNode, [stringMembersArray[0], stringMembersArray[1]]);
     } else if (stringMembersArray.length == 3) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, node.name, [
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE, classNameNode, [
           stringMembersArray[0],
           stringMembersArray[1],
           stringMembersArray[2]]);
     } else if (stringMembersArray.length == 4) {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, node.name, [
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR, classNameNode, [
           stringMembersArray[0],
           stringMembersArray[1],
           stringMembersArray[2],
           stringMembersArray[3]]);
     } else {
-      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, node.name, [
+      analysisError = _errorReporter.newErrorWithProperties(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS, classNameNode, [
           stringMembersArray[0],
           stringMembersArray[1],
           stringMembersArray[2],
@@ -21809,7 +21997,7 @@
    * @see StaticTypeWarningCode#NON_BOOL_CONDITION
    */
   bool _checkForNonBoolCondition(Expression condition) {
-    DartType conditionType = _getStaticType(condition);
+    DartType conditionType = getStaticType(condition);
     if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
       _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_CONDITION, condition, []);
       return true;
@@ -21826,7 +22014,7 @@
    */
   bool _checkForNonBoolExpression(AssertStatement node) {
     Expression expression = node.condition;
-    DartType type = _getStaticType(expression);
+    DartType type = getStaticType(expression);
     if (type is InterfaceType) {
       if (!type.isAssignableTo(_boolType)) {
         _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression, []);
@@ -21850,7 +22038,7 @@
    * @see StaticTypeWarningCode#NON_BOOL_NEGATION_EXPRESSION
    */
   bool _checkForNonBoolNegationExpression(Expression expression) {
-    DartType conditionType = _getStaticType(expression);
+    DartType conditionType = getStaticType(expression);
     if (conditionType != null && !conditionType.isAssignableTo(_boolType)) {
       _errorReporter.reportErrorForNode(StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION, expression, []);
       return true;
@@ -22193,7 +22381,7 @@
    * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
    */
   bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expectedReturnType) {
-    DartType staticReturnType = _getStaticType(returnExpression);
+    DartType staticReturnType = getStaticType(returnExpression);
     if (expectedReturnType.isVoid) {
       if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnType.isBottom) {
         return false;
@@ -22257,7 +22445,7 @@
   bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
     // prepare 'switch' expression type
     Expression expression = node.expression;
-    DartType expressionType = _getStaticType(expression);
+    DartType expressionType = getStaticType(expression);
     if (expressionType == null) {
       return false;
     }
@@ -22270,7 +22458,7 @@
       SwitchCase switchCase = switchMember as SwitchCase;
       // prepare 'case' type
       Expression caseExpression = switchCase.expression;
-      DartType caseType = _getStaticType(caseExpression);
+      DartType caseType = getStaticType(caseExpression);
       // check types
       if (expressionType.isAssignableTo(caseType)) {
         return false;
@@ -22667,24 +22855,6 @@
   }
 
   /**
-   * Return a display name for the given type that includes the path to the compilation unit in
-   * which the type is defined.
-   *
-   * @param type the type for which an extended display name is to be returned
-   * @return a display name that can help distiguish between two types with the same name
-   */
-  String _getExtendedDisplayName(DartType type) {
-    Element element = type.element;
-    if (element != null) {
-      Source source = element.source;
-      if (source != null) {
-        return "${type.displayName} (${source.fullName})";
-      }
-    }
-    return type.displayName;
-  }
-
-  /**
    * Returns the Type (return type) for a given getter.
    *
    * @param propertyAccessorElement
@@ -22716,35 +22886,26 @@
   }
 
   /**
-   * Return the static type of the given expression that is to be used for type analysis.
+   * Given a list of directives that have the same prefix, generate an error if there is more than
+   * one import and any of those imports is deferred.
    *
-   * @param expression the expression whose type is to be returned
-   * @return the static type of the given expression
+   * @param directives the list of directives that have the same prefix
+   * @return `true` if an error was generated
+   * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX
    */
-  DartType _getStaticType(Expression expression) {
-    DartType type = expression.staticType;
-    if (type == null) {
-      // TODO(brianwilkerson) This should never happen.
-      return _dynamicType;
-    }
-    return type;
-  }
-
-  /**
-   * Return the variable element represented by the given expression, or `null` if there is no
-   * such element.
-   *
-   * @param expression the expression whose element is to be returned
-   * @return the variable element represented by the expression
-   */
-  VariableElement _getVariableElement(Expression expression) {
-    if (expression is Identifier) {
-      Element element = expression.staticElement;
-      if (element is VariableElement) {
-        return element;
+  bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
+    bool foundError = false;
+    int count = directives.length;
+    if (count > 1) {
+      for (int i = 0; i < count; i++) {
+        sc.Token deferredToken = directives[i].deferredToken;
+        if (deferredToken != null) {
+          _errorReporter.reportErrorForToken(CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken, []);
+          foundError = true;
+        }
       }
     }
-    return null;
+    return foundError;
   }
 
   /**
@@ -22842,7 +23003,7 @@
   /**
    * Return `true` iff the passed [ClassElement] has a method, getter or setter that
    * matches the name of the passed [ExecutableElement] in either the class itself, or one of
-   * its' mixins.
+   * its' mixins that is concrete.
    *
    * By "match", only the name of the member is tested to match, it does not have to equal or be a
    * subtype of the passed executable element, this is due to the specific use where this method is
@@ -22857,14 +23018,14 @@
     String executableName = executableElt.name;
     if (executableElt is MethodElement) {
       foundElt = classElt.getMethod(executableName);
-      if (foundElt != null) {
+      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
         return true;
       }
       List<InterfaceType> mixins = classElt.mixins;
       for (int i = 0; i < mixins.length && foundElt == null; i++) {
         foundElt = mixins[i].getMethod(executableName);
       }
-      if (foundElt != null) {
+      if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
         return true;
       }
     } else if (executableElt is PropertyAccessorElement) {
@@ -22875,7 +23036,7 @@
       if (foundElt == null && propertyAccessorElement.isSetter) {
         foundElt = classElt.getSetter(executableName);
       }
-      if (foundElt != null) {
+      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
         return true;
       }
       List<InterfaceType> mixins = classElt.mixins;
@@ -22885,7 +23046,7 @@
           foundElt = mixins[i].getSetter(executableName);
         }
       }
-      if (foundElt != null) {
+      if (foundElt != null && !(foundElt as PropertyAccessorElement).isAbstract) {
         return true;
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 6960402..fa20569 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -335,31 +335,33 @@
 
   static const Keyword AS = const Keyword.con2('AS', 34, "as", true);
 
-  static const Keyword DYNAMIC = const Keyword.con2('DYNAMIC', 35, "dynamic", true);
+  static const Keyword DEFERRED = const Keyword.con2('DEFERRED', 35, "deferred", true);
 
-  static const Keyword EXPORT = const Keyword.con2('EXPORT', 36, "export", true);
+  static const Keyword DYNAMIC = const Keyword.con2('DYNAMIC', 36, "dynamic", true);
 
-  static const Keyword EXTERNAL = const Keyword.con2('EXTERNAL', 37, "external", true);
+  static const Keyword EXPORT = const Keyword.con2('EXPORT', 37, "export", true);
 
-  static const Keyword FACTORY = const Keyword.con2('FACTORY', 38, "factory", true);
+  static const Keyword EXTERNAL = const Keyword.con2('EXTERNAL', 38, "external", true);
 
-  static const Keyword GET = const Keyword.con2('GET', 39, "get", true);
+  static const Keyword FACTORY = const Keyword.con2('FACTORY', 39, "factory", true);
 
-  static const Keyword IMPLEMENTS = const Keyword.con2('IMPLEMENTS', 40, "implements", true);
+  static const Keyword GET = const Keyword.con2('GET', 40, "get", true);
 
-  static const Keyword IMPORT = const Keyword.con2('IMPORT', 41, "import", true);
+  static const Keyword IMPLEMENTS = const Keyword.con2('IMPLEMENTS', 41, "implements", true);
 
-  static const Keyword LIBRARY = const Keyword.con2('LIBRARY', 42, "library", true);
+  static const Keyword IMPORT = const Keyword.con2('IMPORT', 42, "import", true);
 
-  static const Keyword OPERATOR = const Keyword.con2('OPERATOR', 43, "operator", true);
+  static const Keyword LIBRARY = const Keyword.con2('LIBRARY', 43, "library", true);
 
-  static const Keyword PART = const Keyword.con2('PART', 44, "part", true);
+  static const Keyword OPERATOR = const Keyword.con2('OPERATOR', 44, "operator", true);
 
-  static const Keyword SET = const Keyword.con2('SET', 45, "set", true);
+  static const Keyword PART = const Keyword.con2('PART', 45, "part", true);
 
-  static const Keyword STATIC = const Keyword.con2('STATIC', 46, "static", true);
+  static const Keyword SET = const Keyword.con2('SET', 46, "set", true);
 
-  static const Keyword TYPEDEF = const Keyword.con2('TYPEDEF', 47, "typedef", true);
+  static const Keyword STATIC = const Keyword.con2('STATIC', 47, "static", true);
+
+  static const Keyword TYPEDEF = const Keyword.con2('TYPEDEF', 48, "typedef", true);
 
   static const List<Keyword> values = const [
       ASSERT,
@@ -397,6 +399,7 @@
       WITH,
       ABSTRACT,
       AS,
+      DEFERRED,
       DYNAMIC,
       EXPORT,
       EXTERNAL,
@@ -1457,11 +1460,6 @@
         next = bigSwitch(next);
       }
     }
-    if (next == -1) {
-      return next;
-    }
-    next = _reader.advance();
-    _beginToken();
     return next;
   }
 
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index eedc729..d09350b 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -20,7 +20,21 @@
 
 /**
  * Instances of the class `DirectoryBasedDartSdk` represent a Dart SDK installed in a
- * specified directory.
+ * specified directory. Typical Dart SDK layout is something like...
+ *
+ * <pre>
+ *    dart-sdk/
+ *       bin/
+ *          dart[.exe]  <-- VM
+ *       lib/
+ *          core/
+ *             core.dart
+ *             ... other core library files ...
+ *          ... other libraries ...
+ *       util/
+ *          ... Dart utilities ...
+ *    Chromium/   <-- Dartium typically exists in a sibling directory
+ * </pre>
  */
 class DirectoryBasedDartSdk implements DartSdk {
   /**
@@ -39,11 +53,26 @@
   String _sdkVersion;
 
   /**
+   * The file containing the dart2js executable.
+   */
+  JavaFile _dart2jsExecutable;
+
+  /**
+   * The file containing the dart formatter executable.
+   */
+  JavaFile _dartFmtExecutable;
+
+  /**
    * The file containing the Dartium executable.
    */
   JavaFile _dartiumExecutable;
 
   /**
+   * The file containing the pub executable.
+   */
+  JavaFile _pubExecutable;
+
+  /**
    * The file containing the VM executable.
    */
   JavaFile _vmExecutable;
@@ -59,9 +88,34 @@
   static String _BIN_DIRECTORY_NAME = "bin";
 
   /**
-   * The name of the directory within the SDK directory that contains Chromium.
+   * The name of the directory on Mac that contains dartium.
    */
-  static String _CHROMIUM_DIRECTORY_NAME = "chromium";
+  static String _DARTIUM_DIRECTORY_NAME_MAC = "Chromium.app";
+
+  /**
+   * The name of the directory on non-Mac that contains dartium.
+   */
+  static String _DARTIUM_DIRECTORY_NAME = "chromium";
+
+  /**
+   * The name of the dart2js executable on non-windows operating systems.
+   */
+  static String _DART2JS_EXECUTABLE_NAME = "dart2js";
+
+  /**
+   * The name of the file containing the dart2js executable on Windows.
+   */
+  static String _DART2JS_EXECUTABLE_NAME_WIN = "dart2js.bat";
+
+  /**
+   * The name of the dart formatter executable on non-windows operating systems.
+   */
+  static String _DARTFMT_EXECUTABLE_NAME = "dartfmt";
+
+  /**
+   * The name of the dart formatter executable on windows operating systems.
+   */
+  static String _DARTFMT_EXECUTABLE_NAME_WIN = "dartfmt.bat";
 
   /**
    * The name of the file containing the Dartium executable on Linux.
@@ -122,9 +176,9 @@
   static String _PUB_EXECUTABLE_NAME = "pub";
 
   /**
-   * The name of the file within the SDK directory that contains the revision number of the SDK.
+   * The name of the file within the SDK directory that contains the version number of the SDK.
    */
-  static String _REVISION_FILE_NAME = "revision";
+  static String _VERSION_FILE_NAME = "version";
 
   /**
    * The name of the file containing the VM executable on the Windows operating system.
@@ -177,8 +231,7 @@
    */
   DirectoryBasedDartSdk(JavaFile sdkDirectory, [bool useDart2jsPaths = false]) {
     this._sdkDirectory = sdkDirectory.getAbsoluteFile();
-    _initializeSdk();
-    _initializeLibraryMap(useDart2jsPaths);
+    _libraryMap = initialLibraryMap(useDart2jsPaths);
     _analysisContext = new AnalysisContextImpl();
     _analysisContext.sourceFactory = new SourceFactory([new DartUriResolver(this)]);
     List<String> uris = this.uris;
@@ -196,27 +249,57 @@
   AnalysisContext get context => _analysisContext;
 
   /**
+   * Return the file containing the dart2js executable, or `null` if it does not exist.
+   *
+   * @return the file containing the dart2js executable
+   */
+  JavaFile get dart2JsExecutable {
+    if (_dart2jsExecutable == null) {
+      _dart2jsExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _DART2JS_EXECUTABLE_NAME_WIN : _DART2JS_EXECUTABLE_NAME));
+    }
+    return _dart2jsExecutable;
+  }
+
+  /**
+   * Return the file containing the dart formatter executable, or `null` if it does not exist.
+   *
+   * @return the file containing the dart formatter executable
+   */
+  JavaFile get dartFmtExecutable {
+    if (_dartFmtExecutable == null) {
+      _dartFmtExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _DARTFMT_EXECUTABLE_NAME_WIN : _DARTFMT_EXECUTABLE_NAME));
+    }
+    return _dartFmtExecutable;
+  }
+
+  /**
    * Return the file containing the Dartium executable, or `null` if it does not exist.
    *
    * @return the file containing the Dartium executable
    */
   JavaFile get dartiumExecutable {
     if (_dartiumExecutable == null) {
-      JavaFile file = new JavaFile.relative(dartiumWorkingDirectory, dartiumBinaryName);
-      if (file.exists()) {
-        _dartiumExecutable = file;
-      }
+      _dartiumExecutable = _verifyExecutable(new JavaFile.relative(dartiumWorkingDirectory, dartiumBinaryName));
     }
     return _dartiumExecutable;
   }
 
   /**
-   * Return the directory where dartium can be found in the Dart SDK (the directory that will be the
-   * working directory is Dartium is invoked without changing the default).
+   * Return the directory where dartium can be found (the directory that will be the working
+   * directory is Dartium is invoked without changing the default).
    *
    * @return the directory where dartium can be found
    */
-  JavaFile get dartiumWorkingDirectory => new JavaFile.relative(_sdkDirectory.getParentFile(), _CHROMIUM_DIRECTORY_NAME);
+  JavaFile get dartiumWorkingDirectory => getDartiumWorkingDirectory(_sdkDirectory.getParentFile());
+
+  /**
+   * Return the directory where dartium can be found (the directory that will be the working
+   * directory is Dartium is invoked without changing the default).
+   *
+   * @param installDir the installation directory
+   * @return the directory where dartium can be found
+   */
+  JavaFile getDartiumWorkingDirectory(JavaFile installDir) => new JavaFile.relative(installDir, _DARTIUM_DIRECTORY_NAME);
 
   /**
    * Return the directory containing the SDK.
@@ -266,9 +349,10 @@
    * @return the file containing the Pub executable
    */
   JavaFile get pubExecutable {
-    String pubBinaryName = OSUtilities.isWindows() ? _PUB_EXECUTABLE_NAME_WIN : _PUB_EXECUTABLE_NAME;
-    JavaFile file = new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), pubBinaryName);
-    return file.exists() ? file : null;
+    if (_pubExecutable == null) {
+      _pubExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), OSUtilities.isWindows() ? _PUB_EXECUTABLE_NAME_WIN : _PUB_EXECUTABLE_NAME));
+    }
+    return _pubExecutable;
   }
 
   @override
@@ -287,11 +371,11 @@
   String get sdkVersion {
     if (_sdkVersion == null) {
       _sdkVersion = DartSdk.DEFAULT_VERSION;
-      JavaFile revisionFile = new JavaFile.relative(_sdkDirectory, _REVISION_FILE_NAME);
+      JavaFile revisionFile = new JavaFile.relative(_sdkDirectory, _VERSION_FILE_NAME);
       try {
         String revision = revisionFile.readAsStringSync();
         if (revision != null) {
-          _sdkVersion = revision;
+          _sdkVersion = revision.trim();
         }
       } on JavaIOException catch (exception) {
       }
@@ -314,10 +398,7 @@
    */
   JavaFile get vmExecutable {
     if (_vmExecutable == null) {
-      JavaFile file = new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), vmBinaryName);
-      if (file.exists()) {
-        _vmExecutable = file;
-      }
+      _vmExecutable = _verifyExecutable(new JavaFile.relative(new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME), vmBinaryName));
     }
     return _vmExecutable;
   }
@@ -346,6 +427,23 @@
   }
 
   /**
+   * Read all of the configuration files to initialize the library maps.
+   *
+   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+   * @return the initialized library map
+   */
+  LibraryMap initialLibraryMap(bool useDart2jsPaths) {
+    JavaFile librariesFile = new JavaFile.relative(new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
+    try {
+      String contents = librariesFile.readAsStringSync();
+      return new SdkLibrariesReader(useDart2jsPaths).readFromFile(librariesFile, contents);
+    } on JavaException catch (exception) {
+      AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception);
+      return new LibraryMap();
+    }
+  }
+
+  /**
    * Ensure that the dart VM is executable. If it is not, make it executable and log that it was
    * necessary for us to do so.
    */
@@ -381,29 +479,12 @@
   }
 
   /**
-   * Read all of the configuration files to initialize the library maps.
+   * Verify that the given executable file exists and is executable.
    *
-   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+   * @param file the binary file
+   * @return the file if it exists and is executable, else `null`
    */
-  void _initializeLibraryMap(bool useDart2jsPaths) {
-    JavaFile librariesFile = new JavaFile.relative(new JavaFile.relative(libraryDirectory, _INTERNAL_DIR), _LIBRARIES_FILE);
-    try {
-      String contents = librariesFile.readAsStringSync();
-      _libraryMap = new SdkLibrariesReader(useDart2jsPaths).readFromFile(librariesFile, contents);
-    } on JavaException catch (exception) {
-      AnalysisEngine.instance.logger.logError2("Could not initialize the library map from ${librariesFile.getAbsolutePath()}", exception);
-      _libraryMap = new LibraryMap();
-    }
-  }
-
-  /**
-   * Initialize the state of the SDK.
-   */
-  void _initializeSdk() {
-    if (!OSUtilities.isWindows()) {
-      _ensureVmIsExecutable();
-    }
-  }
+  JavaFile _verifyExecutable(JavaFile file) => file.isExecutable() ? file : null;
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 7dbcacd..c38eb08 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -611,6 +611,15 @@
    */
   SourceRange getTranslated(int delta) => new SourceRange(offset + delta, length);
 
+  /**
+   * @return the minimal [SourceRange] that cover this and the given [SourceRange]s.
+   */
+  SourceRange getUnion(SourceRange other) {
+    int newOffset = Math.min(offset, other.offset);
+    int newEnd = Math.max(offset + length, other.offset + other.length);
+    return new SourceRange(newOffset, newEnd - newOffset);
+  }
+
   @override
   int get hashCode => 31 * offset + length;
 
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index f28e1f1..f70bc19 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -437,6 +437,52 @@
 }
 
 /**
+ * The interface `MapIterator` defines the behavior of objects that iterate over the entries
+ * in a map.
+ *
+ * This interface defines the concept of a current entry and provides methods to access the key and
+ * value in the current entry. When an iterator is first created it will be positioned before the
+ * first entry and there is no current entry until [moveNext] is invoked. When all of the
+ * entries have been accessed there will also be no current entry.
+ *
+ * There is no guarantee made about the order in which the entries are accessible.
+ */
+abstract class MapIterator<K, V> {
+  /**
+   * Return the key associated with the current element.
+   *
+   * @return the key associated with the current element
+   * @throws NoSuchElementException if there is no current element
+   */
+  K get key;
+
+  /**
+   * Return the value associated with the current element.
+   *
+   * @return the value associated with the current element
+   * @throws NoSuchElementException if there is no current element
+   */
+  V get value;
+
+  /**
+   * Advance to the next entry in the map. Return `true` if there is a current element that
+   * can be accessed after this method returns. It is safe to invoke this method even if the
+   * previous invocation returned `false`.
+   *
+   * @return `true` if there is a current element that can be accessed
+   */
+  bool moveNext();
+
+  /**
+   * Set the value associated with the current element to the given value.
+   *
+   * @param newValue the new value to be associated with the current element
+   * @throws NoSuchElementException if there is no current element
+   */
+  void set value(V newValue);
+}
+
+/**
  * The class `ListUtilities` defines utility methods useful for working with [List
  ].
  */
@@ -453,4 +499,182 @@
       list.add(elements[i]);
     }
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Instances of the class `MultipleMapIterator` implement an iterator that can be used to
+ * sequentially access the entries in multiple maps.
+ */
+class MultipleMapIterator<K, V> implements MapIterator<K, V> {
+  /**
+   * The iterators used to access the entries.
+   */
+  List<MapIterator<K, V>> _iterators;
+
+  /**
+   * The index of the iterator currently being used to access the entries.
+   */
+  int _iteratorIndex = -1;
+
+  /**
+   * The current iterator, or `null` if there is no current iterator.
+   */
+  MapIterator<K, V> _currentIterator;
+
+  /**
+   * Initialize a newly created iterator to return the entries from the given maps.
+   *
+   * @param maps the maps containing the entries to be iterated
+   */
+  MultipleMapIterator(List<Map<K, V>> maps) {
+    int count = maps.length;
+    _iterators = new List<MapIterator>(count);
+    for (int i = 0; i < count; i++) {
+      _iterators[i] = new SingleMapIterator<K, V>(maps[i]);
+    }
+  }
+
+  @override
+  K get key {
+    if (_currentIterator == null) {
+      throw new NoSuchElementException();
+    }
+    return _currentIterator.key;
+  }
+
+  @override
+  V get value {
+    if (_currentIterator == null) {
+      throw new NoSuchElementException();
+    }
+    return _currentIterator.value;
+  }
+
+  @override
+  bool moveNext() {
+    if (_iteratorIndex < 0) {
+      if (_iterators.length == 0) {
+        _currentIterator = null;
+        return false;
+      }
+      if (_advanceToNextIterator()) {
+        return true;
+      } else {
+        _currentIterator = null;
+        return false;
+      }
+    }
+    if (_currentIterator.moveNext()) {
+      return true;
+    } else if (_advanceToNextIterator()) {
+      return true;
+    } else {
+      _currentIterator = null;
+      return false;
+    }
+  }
+
+  @override
+  void set value(V newValue) {
+    if (_currentIterator == null) {
+      throw new NoSuchElementException();
+    }
+    _currentIterator.value = newValue;
+  }
+
+  /**
+   * Under the assumption that there are no more entries that can be returned using the current
+   * iterator, advance to the next iterator that has entries.
+   *
+   * @return `true` if there is a current iterator that has entries
+   */
+  bool _advanceToNextIterator() {
+    _iteratorIndex++;
+    while (_iteratorIndex < _iterators.length) {
+      MapIterator<K, V> iterator = _iterators[_iteratorIndex];
+      if (iterator.moveNext()) {
+        _currentIterator = iterator;
+        return true;
+      }
+      _iteratorIndex++;
+    }
+    return false;
+  }
+}
+
+/**
+ * Instances of the class `SingleMapIterator` implement an iterator that can be used to access
+ * the entries in a single map.
+ */
+class SingleMapIterator<K, V> implements MapIterator<K, V> {
+  /**
+   * Returns a new [SingleMapIterator] instance for the given [Map].
+   */
+  static SingleMapIterator forMap(Map map) => new SingleMapIterator(map);
+
+  /**
+   * The [Map] containing the entries to be iterated over.
+   */
+  final Map<K, V> _map;
+
+  /**
+   * The iterator used to access the entries.
+   */
+  Iterator<K> _keyIterator;
+
+  /**
+   * The current key, or `null` if there is no current key.
+   */
+  K _currentKey;
+
+  /**
+   * The current value.
+   */
+  V _currentValue;
+
+  /**
+   * Initialize a newly created iterator to return the entries from the given map.
+   *
+   * @param map the map containing the entries to be iterated over
+   */
+  SingleMapIterator(this._map) {
+    this._keyIterator = _map.keys.iterator;
+  }
+
+  @override
+  K get key {
+    if (_currentKey == null) {
+      throw new NoSuchElementException();
+    }
+    return _currentKey;
+  }
+
+  @override
+  V get value {
+    if (_currentKey == null) {
+      throw new NoSuchElementException();
+    }
+    return _currentValue;
+  }
+
+  @override
+  bool moveNext() {
+    if (_keyIterator.moveNext()) {
+      _currentKey = _keyIterator.current;
+      _currentValue = _map[_currentKey];
+      return true;
+    } else {
+      _currentKey = null;
+      return false;
+    }
+  }
+
+  @override
+  void set value(V newValue) {
+    if (_currentKey == null) {
+      throw new NoSuchElementException();
+    }
+    _currentValue = newValue;
+    _map[_currentKey] = newValue;
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index d889e35..78089ec 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -58,4 +58,4 @@
       _prev._sw.start();
     }
   }
-}
+}
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index 900b1d27..5c0c314 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -530,7 +530,7 @@
 
   visitClassDeclaration(ClassDeclaration node) {
     preserveLeadingNewlines();
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.abstractKeyword);
     token(node.classKeyword);
     space();
@@ -556,7 +556,7 @@
 
   visitClassTypeAlias(ClassTypeAlias node) {
     preserveLeadingNewlines();
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.abstractKeyword);
     token(node.keyword);
     space();
@@ -615,7 +615,7 @@
   }
 
   visitConstructorDeclaration(ConstructorDeclaration node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.externalKeyword);
     modifier(node.constKeyword);
     modifier(node.factoryKeyword);
@@ -650,6 +650,7 @@
       newlines();
     } else {
       preserveLeadingNewlines();
+      space();
     }
     indent(2);
     token(node.separator /* : */);
@@ -742,7 +743,7 @@
   }
 
   visitExportDirective(ExportDirective node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitDirectiveMetadata(node.metadata);
     token(node.keyword);
     space();
     visit(node.uri);
@@ -771,7 +772,7 @@
   }
 
   visitFieldDeclaration(FieldDeclaration node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.staticKeyword);
     visit(node.fields);
     token(node.semicolon);
@@ -861,7 +862,7 @@
 
   visitFunctionDeclaration(FunctionDeclaration node) {
     preserveLeadingNewlines();
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.externalKeyword);
     visitNode(node.returnType, followedBy: space);
     modifier(node.propertyKeyword);
@@ -887,7 +888,7 @@
   }
 
   visitFunctionTypeAlias(FunctionTypeAlias node) {
-    visitNodes(node.metadata, separatedBy: newlines, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     token(node.keyword);
     space();
     visitNode(node.returnType, followedBy: space);
@@ -941,7 +942,7 @@
   }
 
   visitImportDirective(ImportDirective node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitDirectiveMetadata(node.metadata);
     token(node.keyword);
     nonBreakingSpace();
     visit(node.uri);
@@ -1010,7 +1011,7 @@
   }
 
   visitLibraryDirective(LibraryDirective node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitDirectiveMetadata(node.metadata);
     token(node.keyword);
     space();
     visit(node.name);
@@ -1054,7 +1055,7 @@
   }
 
   visitMethodDeclaration(MethodDeclaration node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.externalKeyword);
     modifier(node.modifierKeyword);
     visitNode(node.returnType, followedBy: space);
@@ -1181,7 +1182,7 @@
   }
 
   visitSimpleFormalParameter(SimpleFormalParameter node) {
-    visitNodes(node.metadata, followedBy: space);
+    visitMemberMetadata(node.metadata);
     modifier(node.keyword);
     visitNode(node.type, followedBy: space);
     visit(node.identifier);
@@ -1304,7 +1305,7 @@
   }
 
   visitTypeParameter(TypeParameter node) {
-    visitNodes(node.metadata, followedBy: space);
+    visitMemberMetadata(node.metadata);
     visit(node.name);
     token(node.keyword /* extends */, precededBy: space, followedBy: space);
     visit(node.bound);
@@ -1335,7 +1336,7 @@
   }
 
   visitVariableDeclarationList(VariableDeclarationList node) {
-    visitNodes(node.metadata, followedBy: newlines);
+    visitMemberMetadata(node.metadata);
     modifier(node.keyword);
     visitNode(node.type, followedBy: space);
 
@@ -1398,6 +1399,24 @@
     }
   }
 
+  /// Visit member metadata
+  visitMemberMetadata(NodeList<Annotation> metadata) {
+    visitNodes(metadata,
+      separatedBy: () {
+        space();
+        preserveLeadingNewlines();
+      },
+      followedBy: space);
+    if (metadata != null && metadata.length > 0) {
+      preserveLeadingNewlines();
+    }
+  }
+
+  /// Visit member metadata
+  visitDirectiveMetadata(NodeList<Annotation> metadata) {
+    visitNodes(metadata, separatedBy: newlines, followedBy: newlines);
+  }
+
   /// Visit the given function [body], printing the [prefix] before if given
   /// body is not empty.
   visitPrefixedBody(prefix(), FunctionBody body) {
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index bf3f884..b11960a 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.13.4
+version: 0.13.5
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index b582327..5a478f4 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -484,7 +484,7 @@
 
   static ImplementsClause implementsClause(List<TypeName> types) => new ImplementsClause(TokenFactory.tokenFromKeyword(Keyword.IMPLEMENTS), list(types));
 
-  static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective(null, metadata, TokenFactory.tokenFromKeyword(Keyword.IMPORT), string2(uri), prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS), prefix == null ? null : identifier3(prefix), list(combinators), TokenFactory.tokenFromType(TokenType.SEMICOLON));
+  static ImportDirective importDirective(List<Annotation> metadata, String uri, String prefix, List<Combinator> combinators) => new ImportDirective(null, metadata, TokenFactory.tokenFromKeyword(Keyword.IMPORT), string2(uri), null, prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS), prefix == null ? null : identifier3(prefix), list(combinators), TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
   static ImportDirective importDirective2(String uri, String prefix, List<Combinator> combinators) => importDirective(new List<Annotation>(), uri, prefix, combinators);
 
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index a20ce5f..3672606 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2745,10 +2745,22 @@
     JUnitTestCase.assertNotNull(clause.keyword);
   }
 
+  void test_parseImportDirective_deferred() {
+    ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' deferred as a;");
+    JUnitTestCase.assertNotNull(directive.keyword);
+    JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNotNull(directive.deferredToken);
+    JUnitTestCase.assertNotNull(directive.asToken);
+    JUnitTestCase.assertNotNull(directive.prefix);
+    EngineTestCase.assertSizeOfList(0, directive.combinators);
+    JUnitTestCase.assertNotNull(directive.semicolon);
+  }
+
   void test_parseImportDirective_hide() {
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' hide A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSizeOfList(1, directive.combinators);
@@ -2759,6 +2771,7 @@
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart';");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSizeOfList(0, directive.combinators);
@@ -2769,6 +2782,7 @@
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a;");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSizeOfList(0, directive.combinators);
@@ -2779,6 +2793,7 @@
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a hide A show B;");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSizeOfList(2, directive.combinators);
@@ -2789,6 +2804,7 @@
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' as a show B hide A;");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNotNull(directive.asToken);
     JUnitTestCase.assertNotNull(directive.prefix);
     EngineTestCase.assertSizeOfList(2, directive.combinators);
@@ -2799,6 +2815,7 @@
     ImportDirective directive = ParserTestCase.parse("parseImportDirective", <Object> [emptyCommentAndMetadata()], "import 'lib/lib.dart' show A, B;");
     JUnitTestCase.assertNotNull(directive.keyword);
     JUnitTestCase.assertNotNull(directive.uri);
+    JUnitTestCase.assertNull(directive.deferredToken);
     JUnitTestCase.assertNull(directive.asToken);
     JUnitTestCase.assertNull(directive.prefix);
     EngineTestCase.assertSizeOfList(1, directive.combinators);
@@ -5887,6 +5904,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseImplementsClause_single);
       });
+      _ut.test('test_parseImportDirective_deferred', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseImportDirective_deferred);
+      });
       _ut.test('test_parseImportDirective_hide', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseImportDirective_hide);
@@ -7313,7 +7334,7 @@
    * @param methodName the name of the parse method that should be invoked to parse the source
    * @param objects the values of the arguments to the method
    * @param source the source to be parsed by the parse method
-   * @param errorCodes the error codes of the errors that should be generated
+   * @param errors the errors that should be generated
    * @return the result of invoking the method
    * @throws Exception if the method could not be invoked or throws an exception
    * @throws AssertionFailedError if the result is `null` or the errors produced while
@@ -9995,6 +10016,13 @@
     ParserTestCase.parse4("parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
+  void test_expectedInterpolationIdentifier_emptyString() {
+    // The scanner inserts an empty string token between the two $'s; we need to make sure that the
+    // MISSING_IDENTIFIER error that is generated has a nonzero width so that it will show up in
+    // the editor UI.
+    ParserTestCase.parse2("parseStringLiteral", <Object> [], "'\$\$foo'", [new AnalysisError.con2(null, 2, 1, ParserErrorCode.MISSING_IDENTIFIER, [])]);
+  }
+
   void test_expectedStringLiteral() {
     StringLiteral expression = ParserTestCase.parse4("parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
     JUnitTestCase.assertTrue(expression.isSynthetic);
@@ -10422,6 +10450,10 @@
     JUnitTestCase.assertNotNull(unit);
   }
 
+  void test_missingPrefixInDeferredImport() {
+    ParserTestCase.parseCompilationUnit("import 'foo.dart' deferred;", [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT]);
+  }
+
   void test_missingStatement() {
     ParserTestCase.parseStatement("is", [ParserErrorCode.MISSING_STATEMENT]);
   }
@@ -11003,6 +11035,10 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_expectedInterpolationIdentifier);
       });
+      _ut.test('test_expectedInterpolationIdentifier_emptyString', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedInterpolationIdentifier_emptyString);
+      });
       _ut.test('test_expectedStringLiteral', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_expectedStringLiteral);
@@ -11403,6 +11439,10 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingNameInPartOfDirective);
       });
+      _ut.test('test_missingPrefixInDeferredImport', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingPrefixInDeferredImport);
+      });
       _ut.test('test_missingStatement', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingStatement);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 4054c21..b719bc4 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/sdk_io.dart' show DirectoryBasedDartSdk;
 import 'package:unittest/unittest.dart' as _ut;
@@ -2077,6 +2078,17 @@
     verify([source]);
   }
 
+  void test_importDeferredLibraryWithLoadFunction() {
+    addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f() {}"]));
+    Source source = addSource(EngineTestCase.createSource([
+        "library root;",
+        "import 'lib1.dart' deferred as lib1;",
+        "main() { lib1.f(); }"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_importDuplicatedLibraryName() {
     Source source = addSource(EngineTestCase.createSource([
         "library test;",
@@ -2219,6 +2231,57 @@
     verify([source]);
   }
 
+  void test_inconsistentMethodInheritance_overrideTrumpsInherits_getter() {
+    // 16134
+    Source source = addSource(EngineTestCase.createSource([
+        "class B<S> {",
+        "  S get g => null;",
+        "}",
+        "abstract class I<U> {",
+        "  U get g => null;",
+        "}",
+        "class C extends B<double> implements I<int> {",
+        "  num get g => null;",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_inconsistentMethodInheritance_overrideTrumpsInherits_method() {
+    // 16134
+    Source source = addSource(EngineTestCase.createSource([
+        "class B<S> {",
+        "  m(S s) => null;",
+        "}",
+        "abstract class I<U> {",
+        "  m(U u) => null;",
+        "}",
+        "class C extends B<double> implements I<int> {",
+        "  m(num n) => null;",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_inconsistentMethodInheritance_overrideTrumpsInherits_setter() {
+    // 16134
+    Source source = addSource(EngineTestCase.createSource([
+        "class B<S> {",
+        "  set t(S s) {}",
+        "}",
+        "abstract class I<U> {",
+        "  set t(U u) {}",
+        "}",
+        "class C extends B<double> implements I<int> {",
+        "  set t(num n) {}",
+        "}"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_inconsistentMethodInheritance_simple() {
     Source source = addSource(EngineTestCase.createSource([
         "abstract class A {",
@@ -3024,6 +3087,46 @@
     verify([source]);
   }
 
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class M {}",
+        "abstract class A {}",
+        "abstract class I {",
+        "  m();",
+        "}",
+        "abstract class B = A with M implements I;"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class M {",
+        "  m();",
+        "}",
+        "abstract class A {}",
+        "abstract class B = A with M;"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "class M {}",
+        "abstract class A {",
+        "  m();",
+        "}",
+        "abstract class B = A with M;"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() {
     // 17034
     Source source = addSource(EngineTestCase.createSource([
@@ -3881,6 +3984,21 @@
     verify([source]);
   }
 
+  void test_sharedDeferredPrefix() {
+    addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f1() {}"]));
+    addNamedSource("/lib2.dart", EngineTestCase.createSource(["library lib2;", "f2() {}"]));
+    addNamedSource("/lib3.dart", EngineTestCase.createSource(["library lib3;", "f3() {}"]));
+    Source source = addSource(EngineTestCase.createSource([
+        "library root;",
+        "import 'lib1.dart' deferred as lib1;",
+        "import 'lib2.dart' as lib;",
+        "import 'lib3.dart' as lib;",
+        "main() { lib1.f1(); lib.f2(); lib.f3(); }"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_staticAccessToInstanceMember_annotation() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -5008,6 +5126,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_typeParameter);
       });
+      _ut.test('test_importDeferredLibraryWithLoadFunction', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_importDeferredLibraryWithLoadFunction);
+      });
       _ut.test('test_importDuplicatedLibraryName', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_importDuplicatedLibraryName);
@@ -5048,6 +5170,18 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_inconsistentMethodInheritance_methods_typeParameters1);
       });
+      _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_getter', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_getter);
+      });
+      _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_method', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_method);
+      });
+      _ut.test('test_inconsistentMethodInheritance_overrideTrumpsInherits_setter', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_inconsistentMethodInheritance_overrideTrumpsInherits_setter);
+      });
       _ut.test('test_inconsistentMethodInheritance_simple', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_inconsistentMethodInheritance_simple);
@@ -5344,6 +5478,18 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_abstractsDontOverrideConcretes_setter);
       });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass);
+      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter);
@@ -5624,6 +5770,10 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_reversedTypeArguments);
       });
+      _ut.test('test_sharedDeferredPrefix', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_sharedDeferredPrefix);
+      });
       _ut.test('test_staticAccessToInstanceMember_annotation', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_staticAccessToInstanceMember_annotation);
@@ -7774,55 +7924,6 @@
     verify([source]);
   }
 
-  void fail_overriddingPrivateMember_getter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  get _g => 0;",
-        "}"]));
-    Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  get _g => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void fail_overriddingPrivateMember_method() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  _m(int x) => 0;",
-        "}"]));
-    Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void fail_overriddingPrivateMember_method2() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {}",
-        "class C extends B {",
-        "  _m(int x) => 0;",
-        "}"]));
-    Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  _m(int x) => 0;", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  void fail_overriddingPrivateMember_setter() {
-    Source source = addSource(EngineTestCase.createSource([
-        "import 'lib1.dart';",
-        "class B extends A {",
-        "  set _s(int x) {}",
-        "}"]));
-    Source source2 = addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "class A {", "  set _s(int x) {}", "}"]));
-    resolve(source);
-    assertErrors(source, [HintCode.OVERRIDDING_PRIVATE_MEMBER]);
-    verify([source, source2]);
-  }
-
   void fail_overrideEqualsButNotHashCode() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  bool operator ==(x) {}", "}"]));
     resolve(source);
@@ -8346,6 +8447,75 @@
     verify([source]);
   }
 
+  void test_invalidAssignment_instanceVariable() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  int x;",
+        "}",
+        "f(var y) {",
+        "  A a;",
+        "  if(y is String) {",
+        "    a.x = y;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
+  void test_invalidAssignment_localVariable() {
+    Source source = addSource(EngineTestCase.createSource([
+        "f(var y) {",
+        "  if(y is String) {",
+        "    int x = y;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
+  void test_invalidAssignment_message() {
+    // The implementation of HintCode.INVALID_ASSIGNMENT assumes that
+    // StaticTypeWarningCode.INVALID_ASSIGNMENT has the same message.
+    JUnitTestCase.assertEquals(HintCode.INVALID_ASSIGNMENT.message, StaticTypeWarningCode.INVALID_ASSIGNMENT.message);
+  }
+
+  void test_invalidAssignment_staticVariable() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  static int x;",
+        "}",
+        "f(var y) {",
+        "  if(y is String) {",
+        "    A.x = y;",
+        "  }",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
+  void test_invalidAssignment_variableDeclaration() {
+    // 17971
+    Source source = addSource(EngineTestCase.createSource([
+        "class Point {",
+        "  final num x, y;",
+        "  Point(this.x, this.y);",
+        "  Point operator +(Point other) {",
+        "    return new Point(x+other.x, y+other.y);",
+        "  }",
+        "}",
+        "main() {",
+        "  var p1 = new Point(0, 0);",
+        "  var p2 = new Point(10, 10);",
+        "  int n = p1 + p2;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [HintCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
   void test_isDouble() {
     Source source = addSource(EngineTestCase.createSource(["var v = 1 is double;"]));
     resolve(source);
@@ -8943,6 +9113,26 @@
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_duplicateImport3);
       });
+      _ut.test('test_invalidAssignment_instanceVariable', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_instanceVariable);
+      });
+      _ut.test('test_invalidAssignment_localVariable', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_localVariable);
+      });
+      _ut.test('test_invalidAssignment_message', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_message);
+      });
+      _ut.test('test_invalidAssignment_staticVariable', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_staticVariable);
+      });
+      _ut.test('test_invalidAssignment_variableDeclaration', () {
+        final __test = new HintCodeTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_variableDeclaration);
+      });
       _ut.test('test_isDouble', () {
         final __test = new HintCodeTest();
         runJUnitTest(__test, __test.test_isDouble);
@@ -9634,6 +9824,12 @@
    */
   CompilationUnit resolveCompilationUnit(Source source, LibraryElement library) => _analysisContext.resolveCompilationUnit(source, library);
 
+  @override
+  void tearDown() {
+    _analysisContext = null;
+    super.tearDown();
+  }
+
   /**
    * Verify that all of the identifiers in the compilation units associated with the given sources
    * have been resolved.
@@ -12341,6 +12537,17 @@
     verify([source]);
   }
 
+  void test_importDeferredLibraryWithLoadFunction() {
+    addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "loadLibrary() {}", "f() {}"]));
+    Source source = addSource(EngineTestCase.createSource([
+        "library root;",
+        "import 'lib1.dart' deferred as lib1;",
+        "main() { lib1.f(); }"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]);
+    verify([source]);
+  }
+
   void test_importInternalLibrary() {
     Source source = addSource(EngineTestCase.createSource(["import 'dart:_interceptors';"]));
     resolve(source);
@@ -13732,6 +13939,19 @@
     verify([source]);
   }
 
+  void test_sharedDeferredPrefix() {
+    addNamedSource("/lib1.dart", EngineTestCase.createSource(["library lib1;", "f1() {}"]));
+    addNamedSource("/lib2.dart", EngineTestCase.createSource(["library lib2;", "f2() {}"]));
+    Source source = addSource(EngineTestCase.createSource([
+        "library root;",
+        "import 'lib1.dart' deferred as lib;",
+        "import 'lib2.dart' as lib;",
+        "main() { lib.f1(); lib.f2(); }"]));
+    resolve(source);
+    assertErrors(source, [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]);
+    verify([source]);
+  }
+
   void test_superInInvalidContext_binaryExpression() {
     Source source = addSource(EngineTestCase.createSource(["var v = super + 0;"]));
     resolve(source);
@@ -14792,6 +15012,10 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_implicitThisReferenceInInitializer_superConstructorInvocation);
       });
+      _ut.test('test_importDeferredLibraryWithLoadFunction', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_importDeferredLibraryWithLoadFunction);
+      });
       _ut.test('test_importInternalLibrary', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_importInternalLibrary);
@@ -15396,6 +15620,10 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_returnInGenerativeConstructor_expressionFunctionBody);
       });
+      _ut.test('test_sharedDeferredPrefix', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_sharedDeferredPrefix);
+      });
       _ut.test('test_superInInvalidContext_binaryExpression', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_superInInvalidContext_binaryExpression);
@@ -17098,6 +17326,58 @@
 }
 
 class StaticWarningCodeTest extends ResolverTestCase {
+  void fail_invalidGetterOverrideReturnType_twoInterfaces_conflicting() {
+    // 17983
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class I<U> {",
+        "  U get g => null;",
+        "}",
+        "abstract class J<V> {",
+        "  V get g => null;",
+        "}",
+        "class B implements I<int>, J<String> {",
+        "  double get g => null;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE]);
+    verify([source]);
+  }
+
+  void fail_invalidMethodOverrideNormalParamType_twoInterfaces_conflicting() {
+    // 17983
+    // language/override_inheritance_generic_test/08
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class I<U> {",
+        "  m(U u) => null;",
+        "}",
+        "abstract class J<V> {",
+        "  m(V v) => null;",
+        "}",
+        "class B implements I<int>, J<String> {",
+        "  m(double d) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+    verify([source]);
+  }
+
+  void fail_invalidSetterOverrideNormalParamType_twoInterfaces_conflicting() {
+    // 17983
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class I<U> {",
+        "  set s(U u) {}",
+        "}",
+        "abstract class J<V> {",
+        "  set s(V v) {}",
+        "}",
+        "class B implements I<int>, J<String> {",
+        "  set s(double d) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
+    verify([source]);
+  }
+
   void fail_undefinedGetter() {
     Source source = addSource(EngineTestCase.createSource([]));
     resolve(source);
@@ -18286,7 +18566,7 @@
     verify([source]);
   }
 
-  void test_invalidMethodOverrideNormalParamType() {
+  void test_invalidMethodOverrideNormalParamType_interface() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
         "  m(int a) {}",
@@ -18299,6 +18579,35 @@
     verify([source]);
   }
 
+  void test_invalidMethodOverrideNormalParamType_superclass() {
+    Source source = addSource(EngineTestCase.createSource([
+        "class A {",
+        "  m(int a) {}",
+        "}",
+        "class B extends A {",
+        "  m(String a) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+    verify([source]);
+  }
+
+  void test_invalidMethodOverrideNormalParamType_superclass_interface() {
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class I<U> {",
+        "  m(U u) => null;",
+        "}",
+        "abstract class J<V> {",
+        "  m(V v) => null;",
+        "}",
+        "class B extends I<int> implements J<String> {",
+        "  m(double d) {}",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE]);
+    verify([source]);
+  }
+
   void test_invalidMethodOverrideNormalParamType_twoInterfaces() {
     Source source = addSource(EngineTestCase.createSource([
         "abstract class I {",
@@ -18562,6 +18871,23 @@
     verify([source]);
   }
 
+  void test_invalidSetterOverrideNormalParamType_superclass_interface() {
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class I {",
+        "  set setter14(int _) => null;",
+        "}",
+        "abstract class J {",
+        "  set setter14(num _) => null;",
+        "}",
+        "abstract class A extends I implements J {}",
+        "class B extends A {",
+        "  set setter14(String _) => null;",
+        "}"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE]);
+    verify([source]);
+  }
+
   void test_invalidSetterOverrideNormalParamType_twoInterfaces() {
     // test from language/override_inheritance_field_test_34.dart
     Source source = addSource(EngineTestCase.createSource([
@@ -18815,6 +19141,46 @@
     verify([source]);
   }
 
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class M {}",
+        "abstract class A {}",
+        "abstract class I {",
+        "  m();",
+        "}",
+        "class B = A with M implements I;"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "abstract class M {",
+        "  m();",
+        "}",
+        "abstract class A {}",
+        "class B = A with M;"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
+  void test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass() {
+    // 15979
+    Source source = addSource(EngineTestCase.createSource([
+        "class M {}",
+        "abstract class A {",
+        "  m();",
+        "}",
+        "class B = A with M;"]));
+    resolve(source);
+    assertErrors(source, [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
+    verify([source]);
+  }
+
   void test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation() {
     // 15028
     Source source = addSource(EngineTestCase.createSource([
@@ -19935,9 +20301,17 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_invalidMethodOverrideNamedParamType);
       });
-      _ut.test('test_invalidMethodOverrideNormalParamType', () {
+      _ut.test('test_invalidMethodOverrideNormalParamType_interface', () {
         final __test = new StaticWarningCodeTest();
-        runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType);
+        runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_interface);
+      });
+      _ut.test('test_invalidMethodOverrideNormalParamType_superclass', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_superclass);
+      });
+      _ut.test('test_invalidMethodOverrideNormalParamType_superclass_interface', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidMethodOverrideNormalParamType_superclass_interface);
       });
       _ut.test('test_invalidMethodOverrideNormalParamType_twoInterfaces', () {
         final __test = new StaticWarningCodeTest();
@@ -20015,6 +20389,10 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType);
       });
+      _ut.test('test_invalidSetterOverrideNormalParamType_superclass_interface', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType_superclass_interface);
+      });
       _ut.test('test_invalidSetterOverrideNormalParamType_twoInterfaces', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_invalidSetterOverrideNormalParamType_twoInterfaces);
@@ -20099,6 +20477,18 @@
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberFour);
       });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_interface);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_mixin);
+      });
+      _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass', () {
+        final __test = new StaticWarningCodeTest();
+        runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_classTypeAlias_superclass);
+      });
       _ut.test('test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation', () {
         final __test = new StaticWarningCodeTest();
         runJUnitTest(__test, __test.test_nonAbstractClassInheritsAbstractMemberOne_ensureCorrectFunctionSubtypeIsUsedInImplementation);
@@ -20414,6 +20804,8 @@
     return source;
   }
 
+  CompilationUnitElement getDefiningUnitElement(Source source) => context.getCompilationUnitElement(source, source);
+
   CompilationUnit resolveDefiningUnit(Source source) {
     LibraryElement libraryElement = context.computeLibraryElement(source);
     return context.resolveCompilationUnit(source, libraryElement);
@@ -20775,6 +21167,7 @@
     //
     // Force the referenced types to be cached.
     //
+    objectType;
     boolType;
     stringType;
     //
@@ -22393,8 +22786,8 @@
       EngineTestCase.assertSizeOfMap(0, namedTypes);
     } else {
       EngineTestCase.assertSizeOfMap(expectedNamedTypes.length, namedTypes);
-      for (MapEntry<String, DartType> entry in getMapEntrySet(expectedNamedTypes)) {
-        JUnitTestCase.assertSame(entry.getValue(), namedTypes[entry.getKey()]);
+      for (MapIterator<String, DartType> iter = SingleMapIterator.forMap(expectedNamedTypes); iter.moveNext();) {
+        JUnitTestCase.assertSame(iter.value, namedTypes[iter.key]);
       }
     }
     JUnitTestCase.assertSame(expectedReturnType, functionType.returnType);
@@ -23056,19 +23449,6 @@
     verify([source]);
   }
 
-  void test_overriddingPrivateMember_sameLibrary() {
-    Source source = addSource(EngineTestCase.createSource([
-        "class A {",
-        "  _m(int x) => 0;",
-        "}",
-        "class B extends A {",
-        "  _m(int x) => 0;",
-        "}"]));
-    resolve(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_overrideEqualsButNotHashCode() {
     Source source = addSource(EngineTestCase.createSource([
         "class A {",
@@ -23596,10 +23976,6 @@
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_missingReturn_voidReturnType);
       });
-      _ut.test('test_overriddingPrivateMember_sameLibrary', () {
-        final __test = new NonHintCodeTest();
-        runJUnitTest(__test, __test.test_overriddingPrivateMember_sameLibrary);
-      });
       _ut.test('test_overrideEqualsButNotHashCode', () {
         final __test = new NonHintCodeTest();
         runJUnitTest(__test, __test.test_overrideEqualsButNotHashCode);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 0d52188..9bbf199 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -302,6 +302,14 @@
 }
 
 class ScannerTest extends JUnitTestCase {
+  void fail_incomplete_string_interpolation() {
+    // https://code.google.com/p/dart/issues/detail?id=18073
+    _assertErrorAndTokens(ScannerErrorCode.UNTERMINATED_STRING_LITERAL, 9, "\"foo \${bar", [
+        new StringToken(TokenType.STRING, "\"foo ", 0),
+        new StringToken(TokenType.STRING_INTERPOLATION_EXPRESSION, "\${", 5),
+        new StringToken(TokenType.IDENTIFIER, "bar", 7)]);
+  }
+
   void test_ampersand() {
     _assertToken(TokenType.AMPERSAND, "&");
   }
@@ -471,7 +479,7 @@
   }
 
   void test_illegalChar_cyrillicLetter_middle() {
-    _assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 0, "Shche\u0433lov");
+    _assertError(ScannerErrorCode.ILLEGAL_CHARACTER, 5, "Shche\u0433lov");
   }
 
   void test_illegalChar_cyrillicLetter_start() {
@@ -542,6 +550,10 @@
     _assertKeywordToken("default");
   }
 
+  void test_keyword_deferred() {
+    _assertKeywordToken("deferred");
+  }
+
   void test_keyword_do() {
     _assertKeywordToken("do");
   }
@@ -1092,6 +1104,22 @@
   }
 
   /**
+   * Assert that scanning the given source produces an error with the given code, and also produces
+   * the given tokens.
+   *
+   * @param expectedError the error that should be produced
+   * @param expectedOffset the string offset that should be associated with the error
+   * @param source the source to be scanned to produce the error
+   * @param expectedTokens the tokens that are expected to be in the source
+   */
+  void _assertErrorAndTokens(ScannerErrorCode expectedError, int expectedOffset, String source, List<Token> expectedTokens) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Token token = _scanWithListener(source, listener);
+    listener.assertErrors([new AnalysisError.con2(null, expectedOffset, 1, expectedError, [source.codeUnitAt(expectedOffset)])]);
+    _checkTokens(token, expectedTokens);
+  }
+
+  /**
    * Assert that when scanned the given source contains a single keyword token with the same lexeme
    * as the original source.
    *
@@ -1190,7 +1218,12 @@
    */
   void _assertTokens(String source, List<Token> expectedTokens) {
     Token token = _scan(source);
-    JUnitTestCase.assertNotNull(token);
+    _checkTokens(token, expectedTokens);
+  }
+
+  void _checkTokens(Token firstToken, List<Token> expectedTokens) {
+    JUnitTestCase.assertNotNull(firstToken);
+    Token token = firstToken;
     for (int i = 0; i < expectedTokens.length; i++) {
       Token expectedToken = expectedTokens[i];
       JUnitTestCase.assertEqualsMsg("Wrong type for token ${i}", expectedToken.type, token.type);
@@ -1455,6 +1488,10 @@
         final __test = new ScannerTest();
         runJUnitTest(__test, __test.test_keyword_default);
       });
+      _ut.test('test_keyword_deferred', () {
+        final __test = new ScannerTest();
+        runJUnitTest(__test, __test.test_keyword_deferred);
+      });
       _ut.test('test_keyword_do', () {
         final __test = new ScannerTest();
         runJUnitTest(__test, __test.test_keyword_do);
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 2490233..435d3ce 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_junit.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
@@ -142,9 +143,9 @@
     //
     // Compare the expected and actual number of each type of error.
     //
-    for (MapEntry<ErrorCode, int> entry in getMapEntrySet(expectedCounts)) {
-      ErrorCode code = entry.getKey();
-      int expectedCount = entry.getValue();
+    for (MapIterator<ErrorCode, int> iter = SingleMapIterator.forMap(expectedCounts); iter.moveNext();) {
+      ErrorCode code = iter.key;
+      int expectedCount = iter.value;
       int actualCount;
       List<AnalysisError> list = errorsByCode.remove(code);
       if (list == null) {
@@ -168,9 +169,9 @@
     //
     // Check that there are no more errors in the actual-errors map, otherwise, record message.
     //
-    for (MapEntry<ErrorCode, List<AnalysisError>> entry in getMapEntrySet(errorsByCode)) {
-      ErrorCode code = entry.getKey();
-      List<AnalysisError> actualErrors = entry.getValue();
+    for (MapIterator<ErrorCode, List<AnalysisError>> iter = SingleMapIterator.forMap(errorsByCode); iter.moveNext();) {
+      ErrorCode code = iter.key;
+      List<AnalysisError> actualErrors = iter.value;
       int actualCount = actualErrors.length;
       if (builder.length == 0) {
         builder.append("Expected ");
@@ -401,7 +402,7 @@
         return true;
       }
     }
-    return true;
+    return false;
   }
 }
 
diff --git a/pkg/analyzer/test/services/data/cu_tests.data b/pkg/analyzer/test/services/data/cu_tests.data
index 65b6c42..6ed971d 100644
--- a/pkg/analyzer/test/services/data/cu_tests.data
+++ b/pkg/analyzer/test/services/data/cu_tests.data
@@ -216,12 +216,12 @@
 >>> Single initializers can be on one line
 class Foo extends Bar {
   final int b;
-  Foo(int a, this.b): super(a);
+  Foo(int a, this.b) : super(a);
 }
 <<<
 class Foo extends Bar {
   final int b;
-  Foo(int a, this.b): super(a);
+  Foo(int a, this.b) : super(a);
 }
 >>> (or not)
 class Foo extends Bar {
@@ -246,4 +246,28 @@
   Foo(int a, int b)
       : super(a),
         this.b = b == null ? 0 : b;
+}
+>>> dartbug.com/17837
+@meta class Foo {
+  @meta String foo;
+  @meta int bar() => 42;
+}
+@meta
+class Bar {
+  @meta
+  String foo;
+  @meta
+  int bar() => 42;
+}
+<<<
+@meta class Foo {
+  @meta String foo;
+  @meta int bar() => 42;
+}
+@meta
+class Bar {
+  @meta
+  String foo;
+  @meta
+  int bar() => 42;
 }
\ No newline at end of file
diff --git a/pkg/barback/lib/src/transform.dart b/pkg/barback/lib/src/transform.dart
index 25c260a..268849d 100644
--- a/pkg/barback/lib/src/transform.dart
+++ b/pkg/barback/lib/src/transform.dart
@@ -57,7 +57,10 @@
   /// Gets the asset for an input [id].
   ///
   /// If an input with [id] cannot be found, throws an [AssetNotFoundException].
-  Future<Asset> getInput(AssetId id) => _node.getInput(id);
+  Future<Asset> getInput(AssetId id) {
+    if (id == _node.primary.id) return syncFuture(() => primaryInput);
+    return _node.getInput(id);
+  }
 
   /// A convenience method to the contents of the input with [id] as a string.
   ///
diff --git a/pkg/barback/lib/src/transform_node.dart b/pkg/barback/lib/src/transform_node.dart
index 5402849..ecd8d8f 100644
--- a/pkg/barback/lib/src/transform_node.dart
+++ b/pkg/barback/lib/src/transform_node.dart
@@ -10,6 +10,7 @@
 import 'asset_id.dart';
 import 'asset_node.dart';
 import 'declaring_transform.dart';
+import 'declaring_transformer.dart';
 import 'errors.dart';
 import 'lazy_transformer.dart';
 import 'log.dart';
@@ -55,6 +56,8 @@
   /// The controllers for the asset nodes emitted by this node.
   final _outputControllers = new Map<AssetId, AssetNodeController>();
 
+  /// The ids of inputs the transformer tried and failed to read last time it
+  /// ran.
   final _missingInputs = new Set<AssetId>();
 
   /// The controller that's used to pass [primary] through [this] if it's not
@@ -89,6 +92,9 @@
   Stream<LogEntry> get onLog => _onLogPool.stream;
   final _onLogPool = new StreamPool<LogEntry>.broadcast();
 
+  /// A controller for log entries emitted by this node.
+  final _onLogController = new StreamController<LogEntry>.broadcast(sync: true);
+
   /// The current state of [this].
   var _state = _State.COMPUTING_IS_PRIMARY;
 
@@ -102,10 +108,18 @@
   /// [_State.APPLIED].
   bool _consumePrimary = false;
 
+  /// The set of output ids that [transformer] declared it would emit.
+  ///
+  /// This is only non-null if [transformer] is a [DeclaringTransformer] and its
+  /// [declareOutputs] has been run successfully.
+  Set<AssetId> _declaredOutputs;
+
   TransformNode(this.phase, Transformer transformer, this.primary,
       this._location)
       : transformer = transformer,
         _isLazy = transformer is LazyTransformer {
+    _onLogPool.add(_onLogController.stream);
+
     _primarySubscription = primary.onStateChange.listen((state) {
       if (state.isRemoved) {
         remove();
@@ -118,26 +132,7 @@
       if (_missingInputs.contains(node.id)) _dirty();
     });
 
-    syncFuture(() => transformer.isPrimary(primary.id))
-        .catchError((error, stackTrace) {
-      if (_isRemoved) return false;
-
-      // Catch all transformer errors and pipe them to the results stream. This
-      // is so a broken transformer doesn't take down the whole graph.
-      phase.cascade.reportError(_wrapException(error, stackTrace));
-
-      return false;
-    }).then((isPrimary) {
-      if (_isRemoved) return;
-      if (isPrimary) {
-        _apply();
-        return;
-      }
-
-      _emitPassThrough();
-      _state = _State.NOT_PRIMARY;
-      _onDoneController.add(null);
-    });
+    _isPrimary();
   }
 
   /// The [TransformInfo] describing this node.
@@ -153,6 +148,7 @@
   /// from the primary input, but it's possible for a transform to no longer be
   /// valid even if its primary input still exists.
   void remove() {
+    _onLogController.close();
     _onAssetController.close();
     _onDoneController.close();
     _primarySubscription.cancel();
@@ -179,11 +175,11 @@
   ///
   /// This causes all of the transform's outputs to be marked as dirty as well.
   void _dirty() {
-    if (_state == _State.COMPUTING_IS_PRIMARY) return;
     if (_state == _State.NOT_PRIMARY) {
       _emitPassThrough();
       return;
     }
+    if (_state == _State.COMPUTING_IS_PRIMARY || _isLazy) return;
 
     if (_passThroughController != null) _passThroughController.setDirty();
     for (var controller in _outputControllers.values) {
@@ -197,32 +193,87 @@
     }
   }
 
+  /// Runs [transformer.isPrimary] and adjusts [this]'s state according to the
+  /// result.
+  ///
+  /// This will also run [_declareOutputs] and/or [_apply] as appropriate.
+  void _isPrimary() {
+    syncFuture(() => transformer.isPrimary(primary.id))
+        .catchError((error, stackTrace) {
+      if (_isRemoved) return false;
+
+      // Catch all transformer errors and pipe them to the results stream. This
+      // is so a broken transformer doesn't take down the whole graph.
+      phase.cascade.reportError(_wrapException(error, stackTrace));
+
+      return false;
+    }).then((isPrimary) {
+      if (_isRemoved) return null;
+      if (isPrimary) {
+        return _declareOutputs().then((_) {
+          if (_isRemoved) return;
+          if (_isLazy) {
+            _state = _State.APPLIED;
+            _onDoneController.add(null);
+          } else {
+            _apply();
+          }
+        });
+      }
+
+      _emitPassThrough();
+      _state = _State.NOT_PRIMARY;
+      _onDoneController.add(null);
+    });
+  }
+
+  /// Runs [transform.declareOutputs] and emits the resulting assets as dirty
+  /// assets.
+  Future _declareOutputs() {
+    if (transformer is! DeclaringTransformer) return new Future.value();
+
+    var controller = new DeclaringTransformController(this);
+    return syncFuture(() {
+      return (transformer as DeclaringTransformer)
+          .declareOutputs(controller.transform);
+    }).then((_) {
+      if (_isRemoved) return;
+      if (controller.loggedError) return;
+
+      _consumePrimary = controller.consumePrimary;
+      _declaredOutputs = controller.outputIds;
+      var invalidIds = _declaredOutputs
+          .where((id) => id.package != phase.cascade.package).toSet();
+      for (var id in invalidIds) {
+        _declaredOutputs.remove(id);
+        // TODO(nweiz): report this as a warning rather than a failing error.
+        phase.cascade.reportError(new InvalidOutputException(info, id));
+      }
+
+      if (!_declaredOutputs.contains(primary.id)) _emitPassThrough();
+
+      for (var id in _declaredOutputs) {
+        var controller = transformer is LazyTransformer
+            ? new AssetNodeController.lazy(id, force, this)
+            : new AssetNodeController(id, this);
+        _outputControllers[id] = controller;
+        _onAssetController.add(controller.node);
+      }
+    }).catchError((error, stackTrace) {
+      if (_isRemoved) return;
+      phase.cascade.reportError(_wrapException(error, stackTrace));
+    });
+  }
+
   /// Applies this transform.
   void _apply() {
-    assert(!_isRemoved);
+    assert(!_isRemoved && !_isLazy);
 
     // Clear input subscriptions here as well as in [_process] because [_apply]
     // may be restarted independently if only a secondary input changes.
     _clearInputSubscriptions();
     _state = _State.APPLYING;
-    primary.whenAvailable((_) {
-      if (_isRemoved) return null;
-      _state = _State.APPLYING;
-      // TODO(nweiz): If [transformer] is a [DeclaringTransformer] but not a
-      // [LazyTransformer], we can get some mileage out of doing a declaration
-      // first so we know how to hook up the assets.
-      if (_isLazy) return _declareLazy();
-      return _applyImmediate();
-    }).catchError((error, stackTrace) {
-      // If the transform became dirty while processing, ignore any errors from
-      // it.
-      if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
-
-      // Catch all transformer errors and pipe them to the results stream. This
-      // is so a broken transformer doesn't take down the whole graph.
-      phase.cascade.reportError(_wrapException(error, stackTrace));
-      return true;
-    }).then((hadError) {
+    _runApply().then((hadError) {
       if (_isRemoved) return;
 
       if (_state == _State.NEEDS_APPLY) {
@@ -233,7 +284,16 @@
       assert(_state == _State.APPLYING);
       if (hadError) {
         _clearOutputs();
-        _dontEmitPassThrough();
+        // If the transformer threw an error, we don't want to emit the
+        // pass-through asset in case it will be overwritten by the transformer.
+        // However, if the transformer declared that it wouldn't overwrite or
+        // consume the pass-through asset, we can safely emit it.
+        if (_declaredOutputs != null && !_consumePrimary &&
+            !_declaredOutputs.contains(primary.id)) {
+          _emitPassThrough();
+        } else {
+          _dontEmitPassThrough();
+        }
       }
 
       _state = _State.APPLIED;
@@ -262,116 +322,88 @@
     });
   }
 
-  /// Applies the transform so that it produces concrete (as opposed to lazy)
-  /// outputs.
+  /// Run [Transformer.apply] as soon as [primary] is available.
   ///
-  /// Returns whether or not the transformer logged an error.
-  Future<bool> _applyImmediate() {
+  /// Returns whether or not an error occurred while running the transformer.
+  Future<bool> _runApply() {
     var transformController = new TransformController(this);
     _onLogPool.add(transformController.onLog);
 
-    return syncFuture(() {
-      return transformer.apply(transformController.transform);
+    return primary.whenAvailable((_) {
+      if (_isRemoved) return null;
+      _state = _State.APPLYING;
+      return syncFuture(() => transformer.apply(transformController.transform));
     }).then((_) {
       if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
       if (transformController.loggedError) return true;
-
-      _consumePrimary = transformController.consumePrimary;
-
-      var newOutputs = transformController.outputs;
-      // Any ids that are for a different package are invalid.
-      var invalidIds = newOutputs
-          .map((asset) => asset.id)
-          .where((id) => id.package != phase.cascade.package)
-          .toSet();
-      for (var id in invalidIds) {
-        newOutputs.removeId(id);
-        // TODO(nweiz): report this as a warning rather than a failing error.
-        phase.cascade.reportError(new InvalidOutputException(info, id));
-      }
-
-      // Remove outputs that used to exist but don't anymore.
-      for (var id in _outputControllers.keys.toList()) {
-        if (newOutputs.containsId(id)) continue;
-        _outputControllers.remove(id).setRemoved();
-      }
-
-      // Emit or stop emitting the pass-through asset between removing and
-      // adding outputs to ensure there are no collisions.
-      if (!newOutputs.containsId(primary.id)) {
-        _emitPassThrough();
-      } else {
-        _dontEmitPassThrough();
-      }
-
-      // Store any new outputs or new contents for existing outputs.
-      for (var asset in newOutputs) {
-        var controller = _outputControllers[asset.id];
-        if (controller != null) {
-          controller.setAvailable(asset);
-        } else {
-          var controller = new AssetNodeController.available(asset, this);
-          _outputControllers[asset.id] = controller;
-          _onAssetController.add(controller.node);
-        }
-      }
-
+      _handleApplyResults(transformController);
       return false;
+    }).catchError((error, stackTrace) {
+      // If the transform became dirty while processing, ignore any errors from
+      // it.
+      if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
+
+      // Catch all transformer errors and pipe them to the results stream. This
+      // is so a broken transformer doesn't take down the whole graph.
+      phase.cascade.reportError(_wrapException(error, stackTrace));
+      return true;
     });
   }
 
-  /// Applies the transform in declarative mode so that it produces lazy
-  /// outputs.
+  /// Handle the results of running [Transformer.apply].
   ///
-  /// Returns whether or not the transformer logged an error.
-  Future<bool> _declareLazy() {
-    var transformController = new DeclaringTransformController(this);
+  /// [transformController] should be the controller for the [Transform] passed
+  /// to [Transformer.apply].
+  void _handleApplyResults(TransformController transformController) {
+    _consumePrimary = transformController.consumePrimary;
 
-    return syncFuture(() {
-      return (transformer as LazyTransformer)
-          .declareOutputs(transformController.transform);
-    }).then((_) {
-      if (_state == _State.NEEDS_APPLY || _isRemoved) return false;
-      if (transformController.loggedError) return true;
+    var newOutputs = transformController.outputs;
+    // Any ids that are for a different package are invalid.
+    var invalidIds = newOutputs
+        .map((asset) => asset.id)
+        .where((id) => id.package != phase.cascade.package)
+        .toSet();
+    for (var id in invalidIds) {
+      newOutputs.removeId(id);
+      // TODO(nweiz): report this as a warning rather than a failing error.
+      phase.cascade.reportError(new InvalidOutputException(info, id));
+    }
 
-      _consumePrimary = transformController.consumePrimary;
-
-      var newIds = transformController.outputIds;
-      var invalidIds =
-          newIds.where((id) => id.package != phase.cascade.package).toSet();
-      for (var id in invalidIds) {
-        newIds.remove(id);
-        // TODO(nweiz): report this as a warning rather than a failing error.
-        phase.cascade.reportError(new InvalidOutputException(info, id));
+    if (_declaredOutputs != null) {
+      var missingOutputs = _declaredOutputs.difference(
+          newOutputs.map((asset) => asset.id).toSet());
+      if (missingOutputs.isNotEmpty) {
+        _warn("This transformer didn't emit declared "
+            "${pluralize('output asset', missingOutputs.length)} "
+            "${toSentence(missingOutputs)}.");
       }
+    }
 
-      // Remove outputs that used to exist but don't anymore.
-      for (var id in _outputControllers.keys.toList()) {
-        if (newIds.contains(id)) continue;
-        _outputControllers.remove(id).setRemoved();
-      }
+    // Remove outputs that used to exist but don't anymore.
+    for (var id in _outputControllers.keys.toList()) {
+      if (newOutputs.containsId(id)) continue;
+      _outputControllers.remove(id).setRemoved();
+    }
 
-      // Emit or stop emitting the pass-through asset between removing and
-      // adding outputs to ensure there are no collisions.
-      if (!newIds.contains(primary.id)) {
-        _emitPassThrough();
+    // Emit or stop emitting the pass-through asset between removing and
+    // adding outputs to ensure there are no collisions.
+    if (!_consumePrimary && !newOutputs.containsId(primary.id)) {
+      _emitPassThrough();
+    } else {
+      _dontEmitPassThrough();
+    }
+
+    // Store any new outputs or new contents for existing outputs.
+    for (var asset in newOutputs) {
+      var controller = _outputControllers[asset.id];
+      if (controller != null) {
+        controller.setAvailable(asset);
       } else {
-        _dontEmitPassThrough();
+        var controller = new AssetNodeController.available(asset, this);
+        _outputControllers[asset.id] = controller;
+        _onAssetController.add(controller.node);
       }
-
-      for (var id in newIds) {
-        var controller = _outputControllers[id];
-        if (controller != null) {
-          controller.setLazy(force);
-        } else {
-          var controller = new AssetNodeController.lazy(id, force, this);
-          _outputControllers[id] = controller;
-          _onAssetController.add(controller.node);
-        }
-      }
-
-      return false;
-    });
+    }
   }
 
   /// Cancels all subscriptions to secondary input nodes.
@@ -422,6 +454,12 @@
     }
   }
 
+  /// Emit a warning about the transformer on [id].
+  void _warn(String message) {
+    _onLogController.add(
+        new LogEntry(info, primary.id, LogLevel.WARNING, message, null));
+  }
+
   String toString() =>
     "transform node in $_location for $transformer on $primary";
 }
@@ -452,6 +490,10 @@
   /// The transform has finished running [Transformer.apply], whether or not it
   /// emitted an error.
   ///
+  /// If the transformer is lazy, the [TransformNode] can also be in this state
+  /// when [Transformer.declareOutputs] has been run but [Transformer.apply] has
+  /// not.
+  ///
   /// If an input changes, this will transition to [APPLYING].
   static final APPLIED = const _State._("applied");
 
diff --git a/pkg/barback/test/package_graph/declaring_transformer_test.dart b/pkg/barback/test/package_graph/declaring_transformer_test.dart
new file mode 100644
index 0000000..94aef14
--- /dev/null
+++ b/pkg/barback/test/package_graph/declaring_transformer_test.dart
@@ -0,0 +1,170 @@
+// 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 barback.test.package_graph.declaring_transformer_test;
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../utils.dart';
+
+main() {
+  initConfig();
+
+  test("gets a declared output with a different path", () {
+    initGraph(["app|foo.blub"], {"app": [
+      [new DeclaringRewriteTransformer("blub", "blab")]
+    ]});
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blab", "foo.blab");
+    buildShouldSucceed();
+  });
+
+  test("gets a declared output with the same path", () {
+    initGraph(["app|foo.blub"], {"app": [
+      [new DeclaringRewriteTransformer("blub", "blub")]
+    ]});
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blub", "foo.blub");
+    buildShouldSucceed();
+  });
+
+  test("gets a passed-through asset", () {
+    initGraph(["app|foo.blub"], {"app": [
+      [new DeclaringRewriteTransformer("blub", "blab")]
+    ]});
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blub", "foo");
+    buildShouldSucceed();
+  });
+
+  test("doesn't get a consumed asset", () {
+    initGraph(["app|foo.blub"], {"app": [
+      [new DeclaringRewriteTransformer("blub", "blab")..consumePrimary = true]
+    ]});
+    updateSources(["app|foo.blub"]);
+    expectNoAsset("app|foo.blub");
+    buildShouldSucceed();
+  });
+
+  test("gets a passed-through asset before apply is finished", () {
+    var transformer = new DeclaringRewriteTransformer("blub", "blab");
+    initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+    transformer.pauseApply();
+    updateSources(["app|foo.blub"]);
+    expectAsset("app|foo.blub", "foo");
+
+    transformer.resumeApply();
+    buildShouldSucceed();
+  });
+
+  test("fails to get a consumed asset before apply is finished", () {
+    var transformer = new DeclaringRewriteTransformer("blub", "blab")
+        ..consumePrimary = true;
+    initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+    transformer.pauseApply();
+    updateSources(["app|foo.blub"]);
+    expectNoAsset("app|foo.blub");
+
+    transformer.resumeApply();
+    buildShouldSucceed();
+  });
+
+  test("waits until apply is finished to get an overwritten asset", () {
+    var transformer = new DeclaringRewriteTransformer("blub", "blub");
+    initGraph(["app|foo.blub"], {"app": [[transformer]]});
+
+    transformer.pauseApply();
+    updateSources(["app|foo.blub"]);
+    expectAssetDoesNotComplete("app|foo.blub");
+
+    transformer.resumeApply();
+    expectAsset("app|foo.blub", "foo.blub");
+    buildShouldSucceed();
+  });
+
+  group("with an error in declareOutputs", () {
+    test("still runs apply", () {
+      initGraph(["app|foo.txt"], {"app": [[
+        new DeclaringBadTransformer("app|out.txt",
+            declareError: true, applyError: false)
+      ]]});
+
+      updateSources(["app|foo.txt"]);
+      expectAsset("app|out.txt", "bad out");
+      expectAsset("app|foo.txt", "foo");
+      buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+    });
+
+    test("waits for apply to complete before passing through the input even if "
+        "consumePrimary was called", () {
+      var transformer = new DeclaringBadTransformer("app|out.txt",
+            declareError: true, applyError: false)..consumePrimary = true;
+      initGraph(["app|foo.txt"], {"app": [[transformer]]});
+
+      transformer.pauseApply();
+      updateSources(["app|foo.txt"]);
+      expectAssetDoesNotComplete("app|out.txt");
+      expectAssetDoesNotComplete("app|foo.txt");
+
+      transformer.resumeApply();
+      expectAsset("app|out.txt", "bad out");
+      expectNoAsset("app|foo.txt");
+      buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+    });
+  });
+
+  test("with an error in apply still passes through the input", () {
+   initGraph(["app|foo.txt"], {"app": [[
+     new DeclaringBadTransformer("app|out.txt",
+         declareError: false, applyError: true)
+   ]]});
+
+   updateSources(["app|foo.txt"]);
+   expectNoAsset("app|out.txt");
+   expectAsset("app|foo.txt", "foo");
+   buildShouldFail([isTransformerException(BadTransformer.ERROR)]);
+  });
+
+  test("can emit outputs it didn't declare", () {
+    initGraph(["app|foo.txt"], {"app": [
+      [new DeclareAssetsTransformer([], ["app|out.txt"])]
+    ]});
+
+    updateSources(["app|foo.txt"]);
+    // There's probably going to be some time when "out.txt" is unavailable,
+    // since it was undeclared.
+    schedule(pumpEventQueue);
+    expectAsset("app|out.txt", "app|out.txt");
+    buildShouldSucceed();
+  });
+
+  test("can overwrite the primary input even if it declared that it wouldn't",
+      () {
+    var transformer = new DeclareAssetsTransformer([], ["app|foo.txt"]);
+    initGraph(["app|foo.txt"], {"app": [[transformer]]});
+
+    transformer.pauseApply();
+    updateSources(["app|foo.txt"]);
+    expectAsset("app|foo.txt", "foo");
+
+    transformer.resumeApply();
+    schedule(pumpEventQueue);
+    expectAsset("app|foo.txt", "app|foo.txt");
+    buildShouldSucceed();
+  });
+
+  test("can declare outputs it doesn't emit", () {
+    initGraph(["app|foo.txt"], {"app": [
+      [new DeclareAssetsTransformer(["app|out.txt"], [])]
+    ]});
+
+    updateSources(["app|foo.txt"]);
+    expectNoAsset("app|out.txt");
+    buildShouldSucceed();
+  });
+}
\ No newline at end of file
diff --git a/pkg/barback/test/package_graph/lazy_transformer_test.dart b/pkg/barback/test/package_graph/lazy_transformer_test.dart
index df249b3..2f08772 100644
--- a/pkg/barback/test/package_graph/lazy_transformer_test.dart
+++ b/pkg/barback/test/package_graph/lazy_transformer_test.dart
@@ -82,9 +82,6 @@
     expect(transformer.numRuns, completion(equals(1)));
   });
 
-  // TODO(nweiz): enable these once DeclaringTransformers forward laziness
-  // properly (issue 16442).
-  //
   // test("a lazy asset piped into a declaring transformer isn't eagerly "
   //     "compiled", () {
   //   var transformer1 = new LazyRewriteTransformer("blub", "blab");
@@ -229,4 +226,27 @@
     expectAllAssets(["app|foo.txt"]);
     buildShouldSucceed();
   });
+
+  // Regression test.
+  test("a lazy transformer that doesn't apply updates its passed-through asset",
+      () {
+    initGraph(["app|foo.txt"], {"app": [
+      [new LazyRewriteTransformer("blub", "blab")]
+    ]});
+
+    // Pause the provider so that the transformer will start forwarding the
+    // asset while it's dirty.
+    pauseProvider();
+    updateSources(["app|foo.txt"]);
+    expectAssetDoesNotComplete("app|foo.txt");
+
+    resumeProvider();
+    expectAsset("app|foo.txt", "foo");
+    buildShouldSucceed();
+
+    modifyAsset("app|foo.txt", "bar");
+    updateSources(["app|foo.txt"]);
+    expectAsset("app|foo.txt", "bar");
+    buildShouldSucceed();
+  });
 }
diff --git a/pkg/barback/test/transformer/declare_assets.dart b/pkg/barback/test/transformer/declare_assets.dart
new file mode 100644
index 0000000..9a14525
--- /dev/null
+++ b/pkg/barback/test/transformer/declare_assets.dart
@@ -0,0 +1,44 @@
+// 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.
+
+library barback.test.transformer.declare_asset;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+
+import 'mock.dart';
+
+/// A transformer that declares some outputs and emits others.
+class DeclareAssetsTransformer extends MockTransformer
+    implements DeclaringTransformer {
+  /// The assets that the transformer declares that it will emit.
+  final List<AssetId> declared;
+
+  /// The assets that the transformer actually emits.
+  ///
+  /// These assets' contents will be identical to their ids.
+  final List<AssetId> emitted;
+
+  DeclareAssetsTransformer(Iterable<String> declared, Iterable<String> emitted)
+      : this.declared = declared.map((id) => new AssetId.parse(id)).toList(),
+        this.emitted = emitted.map((id) => new AssetId.parse(id)).toList();
+
+  Future<bool> doIsPrimary(AssetId id) => new Future.value(true);
+
+  Future doApply(Transform transform) {
+    return newFuture(() {
+      for (var id in emitted) {
+        transform.addOutput(new Asset.fromString(id, id.toString()));
+      }
+    });
+  }
+
+  Future declareOutputs(DeclaringTransform transform) {
+    return newFuture(() {
+      declared.forEach(transform.declareOutput);
+    });
+  }
+}
diff --git a/pkg/barback/test/transformer/declaring_bad.dart b/pkg/barback/test/transformer/declaring_bad.dart
new file mode 100644
index 0000000..41804ce
--- /dev/null
+++ b/pkg/barback/test/transformer/declaring_bad.dart
@@ -0,0 +1,50 @@
+// 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.
+
+library barback.test.transformer.declaring_bad;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+import 'package:barback/src/utils.dart';
+
+import 'bad.dart';
+import 'mock.dart';
+
+/// A transformer that throws an exception when run, after generating the
+/// given outputs.
+class DeclaringBadTransformer extends MockTransformer
+    implements DeclaringTransformer {
+  /// Whether this should throw an error in [declareOutputs].
+  final bool declareError;
+
+  /// Whether this should throw an error in [apply].
+  final bool applyError;
+
+  /// The id of the output asset to emit.
+  final AssetId output;
+
+  DeclaringBadTransformer(String output, {bool declareError: true,
+          bool applyError: false})
+      : this.output = new AssetId.parse(output),
+        this.declareError = declareError,
+        this.applyError = applyError;
+
+  Future<bool> doIsPrimary(AssetId id) => new Future.value(true);
+
+  Future doApply(Transform transform) {
+    return newFuture(() {
+      transform.addOutput(new Asset.fromString(output, "bad out"));
+      if (applyError) throw BadTransformer.ERROR;
+    });
+  }
+
+  Future declareOutputs(DeclaringTransform transform) {
+    return newFuture(() {
+      if (consumePrimary) transform.consumePrimary();
+      transform.declareOutput(output);
+      if (declareError) throw BadTransformer.ERROR;
+    });
+  }
+}
diff --git a/pkg/barback/test/transformer/declaring_rewrite.dart b/pkg/barback/test/transformer/declaring_rewrite.dart
new file mode 100644
index 0000000..063ebbe
--- /dev/null
+++ b/pkg/barback/test/transformer/declaring_rewrite.dart
@@ -0,0 +1,26 @@
+// 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 barback.test.transformer.declaring_rewrite;
+
+import 'dart:async';
+
+import 'package:barback/barback.dart';
+
+import 'rewrite.dart';
+
+/// Like [RewriteTransformer], but declares its assets ahead of time.
+class DeclaringRewriteTransformer extends RewriteTransformer
+    implements LazyTransformer {
+  DeclaringRewriteTransformer(String from, String to)
+      : super(from, to);
+
+  Future declareOutputs(DeclaringTransform transform) {
+    if (consumePrimary) transform.consumePrimary();
+    for (var extension in to.split(" ")) {
+      var id = transform.primaryId.changeExtension(".$extension");
+      transform.declareOutput(id);
+    }
+  }
+}
diff --git a/pkg/barback/test/transformer/lazy_rewrite.dart b/pkg/barback/test/transformer/lazy_rewrite.dart
index 1a36778..33a92cd 100644
--- a/pkg/barback/test/transformer/lazy_rewrite.dart
+++ b/pkg/barback/test/transformer/lazy_rewrite.dart
@@ -8,20 +8,12 @@
 
 import 'package:barback/barback.dart';
 
-import 'rewrite.dart';
+import 'declaring_rewrite.dart';
 
 /// Like [RewriteTransformer], but returns a lazy asset that doesn't perform the
 /// rewrite until it's materialized.
-class LazyRewriteTransformer extends RewriteTransformer
+class LazyRewriteTransformer extends DeclaringRewriteTransformer
     implements LazyTransformer {
   LazyRewriteTransformer(String from, String to)
       : super(from, to);
-
-  Future declareOutputs(DeclaringTransform transform) {
-    if (consumePrimary) transform.consumePrimary();
-    for (var extension in to.split(" ")) {
-      var id = transform.primaryId.changeExtension(".$extension");
-      transform.declareOutput(id);
-    }
-  }
 }
diff --git a/pkg/barback/test/utils.dart b/pkg/barback/test/utils.dart
index 7a77f1b..66c6abf 100644
--- a/pkg/barback/test/utils.dart
+++ b/pkg/barback/test/utils.dart
@@ -23,6 +23,9 @@
 export 'transformer/check_content_and_rename.dart';
 export 'transformer/conditionally_consume_primary.dart';
 export 'transformer/create_asset.dart';
+export 'transformer/declare_assets.dart';
+export 'transformer/declaring_bad.dart';
+export 'transformer/declaring_rewrite.dart';
 export 'transformer/emit_nothing.dart';
 export 'transformer/has_input.dart';
 export 'transformer/lazy_bad.dart';
diff --git a/pkg/mock/pubspec.yaml b/pkg/mock/pubspec.yaml
index 877f56d..33acbdb 100644
--- a/pkg/mock/pubspec.yaml
+++ b/pkg/mock/pubspec.yaml
@@ -1,5 +1,5 @@
 name: mock
-version: 0.10.0
+version: 0.10.0+1
 author: Dart Team <misc@dartlang.org>
 description: A library for mocking classes
 homepage: http://www.dartlang.org
diff --git a/pkg/mock/test/mock_stepwise_negative_test.dart b/pkg/mock/test/mock_stepwise_negative_test.dart
index a9fe2b4..769e972 100644
--- a/pkg/mock/test/mock_stepwise_negative_test.dart
+++ b/pkg/mock/test/mock_stepwise_negative_test.dart
@@ -5,7 +5,7 @@
 library mock.mock_stepwise_negative_test;
 
 import 'package:unittest/unittest.dart' show test;
-import 'package:unittest/mock.dart';
+import 'package:mock/mock.dart';
 
 main() {
   test('Mocking: stepwiseValidate', () {
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 9cf80d5..b0bd22e 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -59,7 +59,6 @@
 collection/test/equality_test/05: Fail # Issue 1533
 collection/test/equality_test/none: Pass, Fail # Issue 14348
 docgen/test/multi_library_test: Slow, Pass # issue 17060
-shelf/test/message_test: RuntimeError # Issue 18109
 third_party/angular_tests/browser_test: Pass, Slow # Large dart2js compile time
 typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
 
@@ -73,6 +72,7 @@
 
 [ $runtime == jsshell ]
 analyzer/test/generated/element_test: Pass, Slow # Issue 16473
+docgen/test/typedef_test: Slow, Pass # issue 17060
 
 [ $runtime == d8 || $runtime == jsshell ]
 async/test/stream_zip_test: RuntimeError, OK # Timers are not supported.
@@ -191,7 +191,7 @@
 
 [ $compiler == dart2js && $browser ]
 stack_trace/test/vm_test: Fail, OK # VM-specific traces
-stack_trace/test/chain_test: Fail # Issues 15171 and 15105
+stack_trace/test/chain_test: Fail, Timeout # Issues 15171, 15105, and 18142
 crypto/test/sha256_test: Slow, Pass
 crypto/test/sha1_test: Slow, Pass
 polymer/example/component: Fail # Issue 13198
@@ -341,8 +341,6 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 matcher/test/matchers_test: StaticWarning, OK # testing error creating abstract class
-scheduled_test/test/scheduled_test/on_complete_test: StaticWarning # Issue 18113
-scheduled_test/test/scheduled_test/set_up_test: StaticWarning # Issue 18113
 
 [ $runtime == vm && ($system == windows || $system == macos) ]
 watcher/test/*/linux_test: Skip
diff --git a/pkg/polymer/lib/polymer.dart b/pkg/polymer/lib/polymer.dart
index 39f5779..66428bd 100644
--- a/pkg/polymer/lib/polymer.dart
+++ b/pkg/polymer/lib/polymer.dart
@@ -69,7 +69,6 @@
 
 import 'package:logging/logging.dart' show Logger, Level;
 import 'package:observe/observe.dart';
-import 'package:observe/src/dirty_check.dart' show dirtyCheckZone;
 import 'package:path/path.dart' as path;
 import 'package:polymer_expressions/polymer_expressions.dart'
     show PolymerExpressions;
diff --git a/pkg/polymer/lib/src/build/common.dart b/pkg/polymer/lib/src/build/common.dart
index 26e6a26..e25a8a0 100644
--- a/pkg/polymer/lib/src/build/common.dart
+++ b/pkg/polymer/lib/src/build/common.dart
@@ -6,7 +6,6 @@
 library polymer.src.build.common;
 
 import 'dart:async';
-import 'dart:math' show min, max;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/error.dart';
diff --git a/pkg/polymer/lib/src/build/script_compactor.dart b/pkg/polymer/lib/src/build/script_compactor.dart
index bf8a51d..4690889 100644
--- a/pkg/polymer/lib/src/build/script_compactor.dart
+++ b/pkg/polymer/lib/src/build/script_compactor.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/generated/element.dart' hide Element;
 import 'package:analyzer/src/generated/element.dart' as analyzer show Element;
 import 'package:barback/barback.dart';
-import 'package:code_transformers/assets.dart';
 import 'package:path/path.dart' as path;
 import 'package:source_maps/span.dart' show SourceFile;
 import 'package:smoke/codegen/generator.dart';
@@ -571,7 +570,7 @@
   }
 }
 
-/// Holds types that are used in queries 
+/// Holds types that are used in queries
 class _ResolvedTypes {
   /// Element representing `HtmlElement`.
   final ClassElement htmlElementElement;
diff --git a/pkg/polymer/test/bind_test.dart b/pkg/polymer/test/bind_test.dart
index 0b3c6eb..512575a 100644
--- a/pkg/polymer/test/bind_test.dart
+++ b/pkg/polymer/test/bind_test.dart
@@ -7,7 +7,6 @@
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
 
 @CustomTag('x-bar')
 class XBar extends PolymerElement {
diff --git a/pkg/polymer/test/entered_view_test.dart b/pkg/polymer/test/entered_view_test.dart
index afd6b2d..f1859ad 100644
--- a/pkg/polymer/test/entered_view_test.dart
+++ b/pkg/polymer/test/entered_view_test.dart
@@ -9,7 +9,6 @@
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
 
 @reflectable
 class XOuter extends PolymerElement {
diff --git a/pkg/polymer/test/event_handlers_test.dart b/pkg/polymer/test/event_handlers_test.dart
index 0cbcfa0..567cea5 100644
--- a/pkg/polymer/test/event_handlers_test.dart
+++ b/pkg/polymer/test/event_handlers_test.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 import 'dart:html';
 
-import 'package:logging/logging.dart';
 import 'package:polymer/polymer.dart';
 import 'package:template_binding/template_binding.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/polymer/test/mirror_loader_1.dart b/pkg/polymer/test/mirror_loader_1.dart
index 4fbe74a..4c2f9f4 100644
--- a/pkg/polymer/test/mirror_loader_1.dart
+++ b/pkg/polymer/test/mirror_loader_1.dart
@@ -1,6 +1,5 @@
 library mirror_loader_test1;
 
-import 'dart:html';
 import 'package:polymer/polymer.dart';
 
 @CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_2.dart b/pkg/polymer/test/mirror_loader_2.dart
index d148571..4340245 100644
--- a/pkg/polymer/test/mirror_loader_2.dart
+++ b/pkg/polymer/test/mirror_loader_2.dart
@@ -1,6 +1,5 @@
 library mirror_loader_test2;
 
-import 'dart:html';
 import 'package:polymer/polymer.dart';
 
 @CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_3.dart b/pkg/polymer/test/mirror_loader_3.dart
index 1f3e511..96a449a 100644
--- a/pkg/polymer/test/mirror_loader_3.dart
+++ b/pkg/polymer/test/mirror_loader_3.dart
@@ -1,7 +1,5 @@
 library mirror_loader_test3;
 
-import 'dart:html';
-
 import 'package:polymer/polymer.dart';
 
 @CustomTag('x-b')
diff --git a/pkg/polymer/test/mirror_loader_4.dart b/pkg/polymer/test/mirror_loader_4.dart
index 7d882af..11aa763 100644
--- a/pkg/polymer/test/mirror_loader_4.dart
+++ b/pkg/polymer/test/mirror_loader_4.dart
@@ -1,6 +1,5 @@
 library mirror_loader_test4;
 
-import 'dart:html';
 import 'package:polymer/polymer.dart';
 
 @CustomTag('x-a')
diff --git a/pkg/polymer/test/mirror_loader_test.dart b/pkg/polymer/test/mirror_loader_test.dart
index 0de5500..dd34fe5 100644
--- a/pkg/polymer/test/mirror_loader_test.dart
+++ b/pkg/polymer/test/mirror_loader_test.dart
@@ -3,13 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
-import 'dart:html';
 
 import 'dart:mirrors';
 
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:path/path.dart' show url;
 
 import 'package:polymer/src/mirror_loader.dart';
 import 'mirror_loader_1.dart' as m1;
diff --git a/pkg/polymer/test/nested_binding_test.dart b/pkg/polymer/test/nested_binding_test.dart
index 7cc8858..cdc3614 100644
--- a/pkg/polymer/test/nested_binding_test.dart
+++ b/pkg/polymer/test/nested_binding_test.dart
@@ -9,7 +9,6 @@
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
 
 @CustomTag('my-test')
 class MyTest extends PolymerElement {
diff --git a/pkg/polymer/test/property_change_test.dart b/pkg/polymer/test/property_change_test.dart
index 621be39..392db92 100644
--- a/pkg/polymer/test/property_change_test.dart
+++ b/pkg/polymer/test/property_change_test.dart
@@ -8,7 +8,6 @@
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
 
 // Dart note: this is a tad different from the JS code. We don't support putting
 // expandos on Dart objects and then observing them. On the other hand, we want
diff --git a/pkg/polymer/test/property_observe_test.dart b/pkg/polymer/test/property_observe_test.dart
index 6fe6a2b..f820e4d 100644
--- a/pkg/polymer/test/property_observe_test.dart
+++ b/pkg/polymer/test/property_observe_test.dart
@@ -9,7 +9,6 @@
 import 'package:polymer/polymer.dart';
 import 'package:unittest/unittest.dart';
 import 'package:unittest/html_config.dart';
-import 'package:unittest/matcher.dart';
 
 var _changes = 0;
 final _done = new Completer();
diff --git a/pkg/polymer_expressions/test/bindings_test.dart b/pkg/polymer_expressions/test/bindings_test.dart
index d5e1063..957b358 100644
--- a/pkg/polymer_expressions/test/bindings_test.dart
+++ b/pkg/polymer_expressions/test/bindings_test.dart
@@ -84,7 +84,7 @@
 
       return new Future(() {
         var el = testDiv.query("#i1");
-        var subscription = el.onInput.listen(expectAsync1((_) {}, count: 1));
+        var subscription = el.onInput.listen(expectAsync((_) {}, count: 1));
         el.focus();
 
         expect(el.value, 'abcde');
diff --git a/pkg/polymer_expressions/test/syntax_test.dart b/pkg/polymer_expressions/test/syntax_test.dart
index 618f999..5d15e17 100644
--- a/pkg/polymer_expressions/test/syntax_test.dart
+++ b/pkg/polymer_expressions/test/syntax_test.dart
@@ -33,11 +33,11 @@
             <input id="input" value="{{ firstName }}">
           </template>'''));
       var person = new Person('John', 'Messerly', ['A', 'B', 'C']);
-      templateBind(query('#test'))
+      templateBind(querySelector('#test'))
           ..bindingDelegate = new PolymerExpressions()
           ..model = person;
       return new Future(() {}).then((_) {
-        InputElement input = query('#input');
+        InputElement input = querySelector('#input');
         expect(input.value, 'John');
         input.focus();
         input.value = 'Justin';
@@ -55,7 +55,7 @@
               {{ item }}
             </template>
           </template>'''));
-      templateBind(query('#test')).bindingDelegate =
+      templateBind(querySelector('#test')).bindingDelegate =
           new PolymerExpressions(globals: {'items': null});
       // the template should be the only node
       expect(testDiv.nodes.length, 1);
@@ -67,7 +67,7 @@
       runZoned(() {
         testDiv.nodes.add(new Element.html('''
             <template id="test" bind>{{ foo }}</template>'''));
-        templateBind(query('#test'))
+        templateBind(querySelector('#test'))
             ..bindingDelegate = new PolymerExpressions()
             ..model = [];
         return new Future(() {});
diff --git a/pkg/scheduled_test/lib/scheduled_test.dart b/pkg/scheduled_test/lib/scheduled_test.dart
index bba4687..720f260 100644
--- a/pkg/scheduled_test/lib/scheduled_test.dart
+++ b/pkg/scheduled_test/lib/scheduled_test.dart
@@ -222,7 +222,7 @@
 ///
 /// If [body] returns a [Future], that future will automatically be wrapped with
 /// [wrapFuture].
-void test(String description, Future body()) =>
+void test(String description, body()) =>
   _test(description, body, unittest.test);
 
 /// Creates a new test case with the given description and body that will be the
@@ -232,10 +232,10 @@
 ///
 /// If [body] returns a [Future], that future will automatically be wrapped with
 /// [wrapFuture].
-void solo_test(String description, Future body()) =>
+void solo_test(String description, body()) =>
   _test(description, body, unittest.solo_test);
 
-void _test(String description, Future body(), Function testFn) {
+void _test(String description, body(), Function testFn) {
   maybeWrapFuture(future, description) {
     if (future != null) wrapFuture(future, description);
   }
@@ -245,8 +245,13 @@
   testFn(description, () {
     var completer = new Completer();
 
+    // Capture this in a local variable in case we capture an out-of-band error
+    // after the schedule completes.
+    var errorHandler;
+
     Chain.capture(() {
       _currentSchedule = new Schedule();
+      errorHandler = _currentSchedule.signalError;
       return currentSchedule.run(() {
         if (_setUpFn != null) maybeWrapFuture(_setUpFn(), "set up");
         maybeWrapFuture(body(), "test body");
@@ -259,7 +264,7 @@
           unittest.registerException(error, new Chain.forTrace(stackTrace));
         }
       }).then(completer.complete);
-    }, onError: (error, chain) => currentSchedule.signalError(error, chain));
+    }, onError: (error, stackTrace) => errorHandler(error, stackTrace));
 
     return completer.future;
   });
@@ -309,7 +314,7 @@
 /// be scheduled for [currentSchedule.onComplete] or
 /// [currentSchedule.onException]. These tasks will be run after each test's
 /// schedule is completed.
-void setUp(void setUpFn()) {
+void setUp(setUpFn()) {
   _setUpScheduledTest(setUpFn);
 }
 
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index 4e0bc56..12316a9 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -1,6 +1,6 @@
 name: scheduled_test
-version: 0.11.0-dev
-author: "Dart Team <misc@dartlang.org>"
+version: 0.11.0
+author: Dart Team <misc@dartlang.org>
 homepage: http://www.dartlang.org
 description: >
   A package for writing readable tests of asynchronous behavior.
@@ -10,10 +10,10 @@
   read like synchronous, linear code, despite executing asynchronously.
 
 dependencies:
-  http: ">=0.9.0 <0.11.0"
-  path: ">=0.9.0 <2.0.0"
-  stack_trace: ">=0.9.1 <0.10.0"
-  unittest: ">=0.9.0 <0.11.0"
-  shelf: ">=0.4.0 <0.5.0"
+  http: '>=0.9.0 <0.11.0'
+  path: '>=0.9.0 <2.0.0'
+  shelf: '>=0.4.0 <0.5.0'
+  stack_trace: '>=0.9.1 <0.10.0'
+  unittest: '>=0.9.0 <0.11.0'
 environment:
-  sdk: ">=0.8.10+6 <2.0.0"
\ No newline at end of file
+  sdk: '>=0.8.10+6 <2.0.0'
diff --git a/pkg/scheduled_test/test/metatest.dart b/pkg/scheduled_test/test/metatest.dart
index 13c5a1d..7550a20 100644
--- a/pkg/scheduled_test/test/metatest.dart
+++ b/pkg/scheduled_test/test/metatest.dart
@@ -52,6 +52,38 @@
   });
 }
 
+/// Declares a test with the given [description] and [body].
+///
+/// [body] corresponds
+/// to the `main` method of a test file, and will be run in an isolate.
+///
+/// All tests must have an expected result in [expectedResults].
+void expectTests(String description, void body(),
+                 Map<String, String> expectedResults) {
+  _setUpTest(description, body, (results) {
+    expectedResults = new Map.from(expectedResults);
+
+    for (var testResult in results['results']) {
+      var description = testResult['description'];
+
+      expect(expectedResults, contains(description),
+          reason: '"$description" did not have an expected result set.\n'
+            '${_summarizeTests(results)}');
+
+      var result = testResult['result'];
+
+      expect(expectedResults, containsPair(description, result),
+          reason: 'The test "$description" not not have the expected result.\n'
+            '${_summarizeTests(results)}');
+
+      expectedResults.remove(description);
+    }
+    expect(expectedResults, isEmpty,
+        reason: 'Unexpected additional test results\n'
+            '${_summarizeTests(results)}');
+  });
+}
+
 /// Declares a test with the given [description] and [body]. [body] corresponds
 /// to the `main` method of a test file, and will be run in an isolate. Expects
 /// all tests defined by [body] to fail.
diff --git a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
index 048745d..d5c7370 100644
--- a/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
+++ b/pkg/scheduled_test/test/scheduled_test/current_schedule_errors_test.dart
@@ -13,6 +13,17 @@
 
   setUpTimeout();
 
+  expectTests('a scheduled test with an out-of-band error should fail', () {
+    mock_clock.mock().run();
+    test('test 1', () {
+      sleep(1).then((_) => throw 'error');
+    });
+
+    test('test 2', () {
+      return sleep(2);
+    });
+  }, {'test 1': ERROR, 'test 2': PASS});
+
   expectTestsPass('currentSchedule.errors contains the error in the onComplete '
       'queue', () {
     var errors;
diff --git a/pkg/stack_trace/CHANGELOG.md b/pkg/stack_trace/CHANGELOG.md
index 5e2f2c7..0b45208 100644
--- a/pkg/stack_trace/CHANGELOG.md
+++ b/pkg/stack_trace/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.9.3+1
+
+* If an error is thrown in `Chain.capture`'s `onError` handler, that error is
+  handled by the parent zone. This matches the behavior of `runZoned` in
+  `dart:async`.
+
 ## 0.9.3
 
 * Add a `Chain.foldFrames` method that parallels `Trace.foldFrames`.
diff --git a/pkg/stack_trace/lib/src/stack_zone_specification.dart b/pkg/stack_trace/lib/src/stack_zone_specification.dart
index 36e0717..9a4f7c0 100644
--- a/pkg/stack_trace/lib/src/stack_zone_specification.dart
+++ b/pkg/stack_trace/lib/src/stack_zone_specification.dart
@@ -145,10 +145,21 @@
   /// [_onError] or [parent]'s error handler.
   handleUncaughtError(Zone self, ZoneDelegate parent, Zone zone, error,
       StackTrace stackTrace) {
+    var stackChain = chainFor(stackTrace);
     if (_onError == null) {
-      return parent.handleUncaughtError(zone, error, chainFor(stackTrace));
-    } else {
-      _onError(error, chainFor(stackTrace));
+      return parent.handleUncaughtError(zone, error, stackChain);
+    }
+
+    // TODO(nweiz): Currently this copies a lot of logic from [runZoned]. Just
+    // allow [runBinary] to throw instead once issue 18134 is fixed.
+    try {
+      return parent.runBinary(zone, _onError, error, stackChain);
+    } catch (newError, newStackTrace) {
+      if (identical(newError, error)) {
+        return parent.handleUncaughtError(zone, error, stackChain);
+      } else {
+        return parent.handleUncaughtError(zone, newError, newStackTrace);
+      }
     }
   }
 
diff --git a/pkg/stack_trace/pubspec.yaml b/pkg/stack_trace/pubspec.yaml
index 99abed7..d0cc30f 100644
--- a/pkg/stack_trace/pubspec.yaml
+++ b/pkg/stack_trace/pubspec.yaml
@@ -1,5 +1,5 @@
 name: stack_trace
-version: 0.9.3
+version: 0.9.3+1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/stack_trace/test/chain_test.dart b/pkg/stack_trace/test/chain_test.dart
index d9915eb..683544f 100644
--- a/pkg/stack_trace/test/chain_test.dart
+++ b/pkg/stack_trace/test/chain_test.dart
@@ -107,6 +107,29 @@
 
       return completer.future;
     });
+
+    test('and relays them to the parent zone', () {
+      var completer = new Completer();
+
+      runZoned(() {
+        Chain.capture(() {
+          inMicrotask(() => throw 'error');
+        }, onError: (error, chain) {
+          expect(error, equals('error'));
+          expect(chain.traces[1].frames,
+              contains(frameMember(startsWith('inMicrotask'))));
+          throw error;
+        });
+      }, onError: (error, chain) {
+        expect(error, equals('error'));
+        expect(chain, new isInstanceOf<Chain>());
+        expect(chain.traces[1].frames,
+            contains(frameMember(startsWith('inMicrotask'))));
+        completer.complete();
+      });
+
+      return completer.future;
+    });
   });
 
   test('capture() without onError passes exceptions to parent zone', () {
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index bb6461e..a68b7e5 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -160,7 +160,6 @@
                Map<String, String> environment,
                bool includeParentEnvironment,
                bool runInShell) {
-    runInShell = identical(runInShell, true);
     if (runInShell) {
       arguments = _getShellArguments(path, arguments);
       path = _getShellCommand();
@@ -193,22 +192,22 @@
     }
 
     _environment = [];
-    if (environment == null) {
-      environment = {};
-    }
-    if (environment is !Map) {
-      throw new ArgumentError("Environment is not a map: $environment");
-    }
-    if (identical(true, includeParentEnvironment)) {
-      environment = new Map.from(Platform.environment)..addAll(environment);
-    }
-    environment.forEach((key, value) {
+    var environmentEntryHandler = (key, value) {
       if (key is !String || value is !String) {
         throw new ArgumentError(
-            "Environment key or value is not a string: ($key, $value)");
+        "Environment key or value is not a string: ($key, $value)");
       }
       _environment.add('$key=$value');
-    });
+    };
+    if (environment != null) {
+      if (environment is !Map) {
+        throw new ArgumentError("Environment is not a map: $environment");
+      }
+      environment.forEach(environmentEntryHandler);
+    }
+    if (includeParentEnvironment) {
+      Platform.environment.forEach(environmentEntryHandler);
+    }
 
     // stdin going to process.
     _stdin = new _StdSink(new _Socket._writePipe());
@@ -321,6 +320,7 @@
                                   _stderr._stream._nativeSocket,
                                   _exitHandler._nativeSocket,
                                   status);
+      _environment = null;  // The environment will not be needed going forward.
       if (!success) {
         completer.completeError(
             new ProcessException(_path,
@@ -376,6 +376,7 @@
                                 _stderr._stream._nativeSocket,
                                 _exitHandler._nativeSocket,
                                 status);
+    _environment = null;  // The environment will not be needed going forward.
     if (!success) {
       throw new ProcessException(_path,
                                  _arguments,
diff --git a/runtime/lib/deferred_load_patch.dart b/runtime/lib/deferred_load_patch.dart
index 2bd0027..800fdef 100644
--- a/runtime/lib/deferred_load_patch.dart
+++ b/runtime/lib/deferred_load_patch.dart
@@ -5,11 +5,11 @@
 final Set<String> _loadedLibraries = new Set<String>();
 
 patch class DeferredLibrary {
-  /* patch */ Future<bool> load() {
+  /* patch */ Future<Null> load() {
     // Dummy implementation that should eventually be replaced by real
     // implementation.
     Future future =
-        new Future<bool>.value(!_loadedLibraries.contains(libraryName));
+        new Future<Null>.value(null);
     _loadedLibraries.add(libraryName);
     return future;
   }
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 8c07d5b..2da262e 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -73,6 +73,136 @@
   return fpu_reg_names[reg];
 }
 
+
+static int CountLeadingZeros(uint64_t value, int width) {
+  ASSERT((width == 32) || (width == 64));
+  if (value == 0) {
+    return width;
+  }
+  int count = 0;
+  do {
+    count++;
+  } while (value >>= 1);
+  return width - count;
+}
+
+
+static int CountOneBits(uint64_t value, int width) {
+  // Mask out unused bits to ensure that they are not counted.
+  value &= (0xffffffffffffffffUL >> (64-width));
+
+  value = ((value >> 1) & 0x5555555555555555) + (value & 0x5555555555555555);
+  value = ((value >> 2) & 0x3333333333333333) + (value & 0x3333333333333333);
+  value = ((value >> 4) & 0x0f0f0f0f0f0f0f0f) + (value & 0x0f0f0f0f0f0f0f0f);
+  value = ((value >> 8) & 0x00ff00ff00ff00ff) + (value & 0x00ff00ff00ff00ff);
+  value = ((value >> 16) & 0x0000ffff0000ffff) + (value & 0x0000ffff0000ffff);
+  value = ((value >> 32) & 0x00000000ffffffff) + (value & 0x00000000ffffffff);
+
+  return value;
+}
+
+
+// Test if a given value can be encoded in the immediate field of a logical
+// instruction.
+// If it can be encoded, the function returns true, and values pointed to by n,
+// imm_s and imm_r are updated with immediates encoded in the format required
+// by the corresponding fields in the logical instruction.
+// If it can't be encoded, the function returns false, and the operand is
+// undefined.
+bool Assembler::IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op) {
+  ASSERT(imm_op != NULL);
+  ASSERT((width == kWRegSizeInBits) || (width == kXRegSizeInBits));
+  ASSERT((width == kXRegSizeInBits) || (value <= 0xffffffffUL));
+  uint8_t n = 0;
+  uint8_t imm_s = 0;
+  uint8_t imm_r = 0;
+
+  // Logical immediates are encoded using parameters n, imm_s and imm_r using
+  // the following table:
+  //
+  //  N   imms    immr    size        S             R
+  //  1  ssssss  rrrrrr    64    UInt(ssssss)  UInt(rrrrrr)
+  //  0  0sssss  xrrrrr    32    UInt(sssss)   UInt(rrrrr)
+  //  0  10ssss  xxrrrr    16    UInt(ssss)    UInt(rrrr)
+  //  0  110sss  xxxrrr     8    UInt(sss)     UInt(rrr)
+  //  0  1110ss  xxxxrr     4    UInt(ss)      UInt(rr)
+  //  0  11110s  xxxxxr     2    UInt(s)       UInt(r)
+  // (s bits must not be all set)
+  //
+  // A pattern is constructed of size bits, where the least significant S+1
+  // bits are set. The pattern is rotated right by R, and repeated across a
+  // 32 or 64-bit value, depending on destination register width.
+  //
+  // To test if an arbitrary immediate can be encoded using this scheme, an
+  // iterative algorithm is used.
+
+  // 1. If the value has all set or all clear bits, it can't be encoded.
+  if ((value == 0) || (value == 0xffffffffffffffffULL) ||
+      ((width == kWRegSizeInBits) && (value == 0xffffffff))) {
+    return false;
+  }
+
+  int lead_zero = CountLeadingZeros(value, width);
+  int lead_one = CountLeadingZeros(~value, width);
+  int trail_zero = Utils::CountTrailingZeros(value);
+  int trail_one = Utils::CountTrailingZeros(~value);
+  int set_bits = CountOneBits(value, width);
+
+  // The fixed bits in the immediate s field.
+  // If width == 64 (X reg), start at 0xFFFFFF80.
+  // If width == 32 (W reg), start at 0xFFFFFFC0, as the iteration for 64-bit
+  // widths won't be executed.
+  int imm_s_fixed = (width == kXRegSizeInBits) ? -128 : -64;
+  int imm_s_mask = 0x3F;
+
+  for (;;) {
+    // 2. If the value is two bits wide, it can be encoded.
+    if (width == 2) {
+      n = 0;
+      imm_s = 0x3C;
+      imm_r = (value & 3) - 1;
+      *imm_op = Operand(n, imm_s, imm_r);
+      return true;
+    }
+
+    n = (width == 64) ? 1 : 0;
+    imm_s = ((imm_s_fixed | (set_bits - 1)) & imm_s_mask);
+    if ((lead_zero + set_bits) == width) {
+      imm_r = 0;
+    } else {
+      imm_r = (lead_zero > 0) ? (width - trail_zero) : lead_one;
+    }
+
+    // 3. If the sum of leading zeros, trailing zeros and set bits is equal to
+    //    the bit width of the value, it can be encoded.
+    if (lead_zero + trail_zero + set_bits == width) {
+      *imm_op = Operand(n, imm_s, imm_r);
+      return true;
+    }
+
+    // 4. If the sum of leading ones, trailing ones and unset bits in the
+    //    value is equal to the bit width of the value, it can be encoded.
+    if (lead_one + trail_one + (width - set_bits) == width) {
+      *imm_op = Operand(n, imm_s, imm_r);
+      return true;
+    }
+
+    // 5. If the most-significant half of the bitwise value is equal to the
+    //    least-significant half, return to step 2 using the least-significant
+    //    half of the value.
+    uint64_t mask = (1UL << (width >> 1)) - 1;
+    if ((value & mask) == ((value >> (width >> 1)) & mask)) {
+      width >>= 1;
+      set_bits >>= 1;
+      imm_s_fixed >>= 1;
+      continue;
+    }
+
+    // 6. Otherwise, the value can't be encoded.
+    return false;
+  }
+}
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM64
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index cd7bd36..fd9d7cb 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -176,6 +176,12 @@
   Operand(const Operand& other)
       : ValueObject(), encoding_(other.encoding_), type_(other.type_) { }
 
+  Operand& operator=(const Operand& other) {
+    type_ = other.type_;
+    encoding_ = other.encoding_;
+    return *this;
+  }
+
   explicit Operand(Register rm) {
     ASSERT((rm != R31) && (rm != SP));
     const Register crm = ConcreteRegister(rm);
@@ -217,8 +223,19 @@
     type_ = Immediate;
   }
 
-  // TODO(zra): Add bitfield immediate operand
-  // Operand(int32_t n, int32_t imms, int32_t immr);
+  // Encodes the value of an immediate for a logical operation.
+  // Since these values are difficult to craft by hand, instead pass the
+  // logical mask to the function Assembler::IsImmLogical to get n, imm_s, and
+  // imm_r.
+  Operand(uint8_t n, int8_t imm_s, int8_t imm_r) {
+    ASSERT((n == 1) || (n == 0));
+    ASSERT(Utils::IsUint(6, imm_s) && Utils::IsUint(6, imm_r));
+    type_ = BitfieldImm;
+    encoding_ =
+      (static_cast<int32_t>(n) << kNShift) |
+      (static_cast<int32_t>(imm_s) << kImmSShift) |
+      (static_cast<int32_t>(imm_r) << kImmRShift);
+  }
 
   enum OperandType {
     Shifted,
@@ -326,12 +343,82 @@
   void add(Register rd, Register rn, Operand o) {
     AddSubHelper(kDoubleWord, false, false, rd, rn, o);
   }
+  void adds(Register rd, Register rn, Operand o) {
+    AddSubHelper(kDoubleWord, true, false, rd, rn, o);
+  }
   void addw(Register rd, Register rn, Operand o) {
     AddSubHelper(kWord, false, false, rd, rn, o);
   }
   void sub(Register rd, Register rn, Operand o) {
     AddSubHelper(kDoubleWord, false, true, rd, rn, o);
   }
+  void subs(Register rd, Register rn, Operand o) {
+    AddSubHelper(kDoubleWord, true, true, rd, rn, o);
+  }
+
+  // Logical immediate operations.
+  // TODO(zra): Add macros that check IsImmLogical, and fall back on a longer
+  // sequence on failure.
+  void andi(Register rd, Register rn, uint64_t imm) {
+    Operand imm_op;
+    const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+    ASSERT(immok);
+    EmitLogicalImmOp(ANDI, rd, rn, imm_op, kDoubleWord);
+  }
+  void orri(Register rd, Register rn, uint64_t imm) {
+    Operand imm_op;
+    const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+    ASSERT(immok);
+    EmitLogicalImmOp(ORRI, rd, rn, imm_op, kDoubleWord);
+  }
+  void eori(Register rd, Register rn, uint64_t imm) {
+    Operand imm_op;
+    const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+    ASSERT(immok);
+    EmitLogicalImmOp(EORI, rd, rn, imm_op, kDoubleWord);
+  }
+  void andis(Register rd, Register rn, uint64_t imm) {
+    Operand imm_op;
+    const bool immok = IsImmLogical(imm, kXRegSizeInBits, &imm_op);
+    ASSERT(immok);
+    EmitLogicalImmOp(ANDIS, rd, rn, imm_op, kDoubleWord);
+  }
+
+  // Logical (shifted) register operations.
+  void and_(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(AND, rd, rn, o, kDoubleWord);
+  }
+  void bic(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(BIC, rd, rn, o, kDoubleWord);
+  }
+  void orr(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(ORR, rd, rn, o, kDoubleWord);
+  }
+  void orn(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
+  }
+  void eor(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(EOR, rd, rn, o, kDoubleWord);
+  }
+  void eon(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(EON, rd, rn, o, kDoubleWord);
+  }
+  void ands(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(ANDS, rd, rn, o, kDoubleWord);
+  }
+  void bics(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(BICS, rd, rn, o, kDoubleWord);
+  }
+
+  // Comparison.
+  // rn cmp o.
+  void cmp(Register rn, Operand o) {
+    subs(ZR, rn, o);
+  }
+  // rn cmp -o.
+  void cmn(Register rn, Operand o) {
+    adds(ZR, rn, o);
+  }
 
   // Move wide immediate.
   void movk(Register rd, int32_t imm, int32_t hw_idx) {
@@ -393,6 +480,8 @@
 
   GrowableArray<CodeComment*> comments_;
 
+  bool IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op);
+
   void AddSubHelper(OperandSize os, bool set_flags, bool subtract,
                     Register rd, Register rn, Operand o) {
     ASSERT((rd != R31) && (rn != R31));
@@ -412,9 +501,9 @@
   }
 
   void EmitAddSubImmOp(AddSubImmOp op, Register rd, Register rn,
-                       Operand o, OperandSize os, bool set_flags) {
-    ASSERT((os == kDoubleWord) || (os == kWord));
-    const int32_t size = (os == kDoubleWord) ? B31 : 0;
+                       Operand o, OperandSize sz, bool set_flags) {
+    ASSERT((sz == kDoubleWord) || (sz == kWord));
+    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
     const int32_t s = set_flags ? B29 : 0;
     const int32_t encoding =
         op | size | s |
@@ -424,6 +513,42 @@
     Emit(encoding);
   }
 
+  void EmitLogicalImmOp(LogicalImmOp op, Register rd, Register rn,
+                        Operand o, OperandSize sz) {
+    ASSERT((sz == kDoubleWord) || (sz == kWord));
+    ASSERT((rd != R31) && (rn != R31));
+    ASSERT(rn != SP);
+    ASSERT((op == ANDIS) || (rd != ZR));  // op != ANDIS => rd != ZR.
+    ASSERT((op != ANDIS) || (rd != SP));  // op == ANDIS => rd != SP.
+    ASSERT(o.type() == Operand::BitfieldImm);
+    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const Register crd = ConcreteRegister(rd);
+    const Register crn = ConcreteRegister(rn);
+    const int32_t encoding =
+        op | size |
+        (static_cast<int32_t>(crd) << kRdShift) |
+        (static_cast<int32_t>(crn) << kRnShift) |
+        o.encoding();
+    Emit(encoding);
+  }
+
+  void EmitLogicalShiftOp(LogicalShiftOp op,
+                          Register rd, Register rn, Operand o, OperandSize sz) {
+    ASSERT((sz == kDoubleWord) || (sz == kWord));
+    ASSERT((rd != R31) && (rn != R31));
+    ASSERT((rd != SP) && (rn != SP));
+    ASSERT(o.type() == Operand::Shifted);
+    const int32_t size = (sz == kDoubleWord) ? B31 : 0;
+    const Register crd = ConcreteRegister(rd);
+    const Register crn = ConcreteRegister(rn);
+    const int32_t encoding =
+        op | size |
+        (static_cast<int32_t>(crd) << kRdShift) |
+        (static_cast<int32_t>(crn) << kRnShift) |
+        o.encoding();
+    Emit(encoding);
+  }
+
   void EmitAddSubShiftExtOp(AddSubShiftExtOp op,
                             Register rd, Register rn, Operand o,
                             OperandSize sz, bool set_flags) {
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index 6e26fe8..72feb31 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -391,6 +391,170 @@
   EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
 }
 
+
+// Logical register operations.
+ASSEMBLER_TEST_GENERATE(AndRegs, assembler) {
+  __ movz(R1, 43, 0);
+  __ movz(R2, 42, 0);
+  __ and_(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AndShiftRegs, assembler) {
+  __ movz(R1, 42, 0);
+  __ movz(R2, 21, 0);
+  __ and_(R0, R1, Operand(R2, LSL, 1));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndShiftRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(BicRegs, assembler) {
+  __ movz(R1, 42, 0);
+  __ movz(R2, 5, 0);
+  __ bic(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(BicRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrrRegs, assembler) {
+  __ movz(R1, 32, 0);
+  __ movz(R2, 10, 0);
+  __ orr(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrrRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrnRegs, assembler) {
+  __ movz(R1, 32, 0);
+  __ movn(R2, 0, 0);  // R2 <- 0xffffffffffffffff.
+  __ movk(R2, 0xffd5, 0);  // R2 <- 0xffffffffffffffe5.
+  __ orn(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrnRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EorRegs, assembler) {
+  __ movz(R1, 0xffd5, 0);
+  __ movz(R2, 0xffff, 0);
+  __ eor(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EorRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EonRegs, assembler) {
+  __ movz(R1, 0xffd5, 0);
+  __ movn(R2, 0xffff, 0);
+  __ eon(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EonRegs, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+// TODO(zra): ands and bics after branches are implemented.
+
+
+// Logical immediate operations.
+ASSEMBLER_TEST_GENERATE(AndImm, assembler) {
+  __ movz(R1, 42, 0);
+  __ andi(R0, R1, 0xaaaaaaaaaaaaaaaaULL);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndImm, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(AndOneImm, assembler) {
+  __ movz(R1, 43, 0);
+  __ andi(R0, R1, 1);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(AndOneImm, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(1, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(OrrImm, assembler) {
+  __ movz(R1, 0, 0);
+  __ movz(R2, 0x3f, 0);
+  __ movz(R3, 0xa, 0);
+  __ orri(R1, R1, 0x0020002000200020ULL);
+  __ orr(R1, R1, Operand(R3));
+  __ and_(R0, R1, Operand(R2));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(OrrImm, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(EorImm, assembler) {
+  __ movn(R0, 0, 0);
+  __ movk(R0, 0xffd5, 0);  // R0 < 0xffffffffffffffd5.
+  __ movz(R1, 0x3f, 0);
+  __ eori(R0, R0, 0x3f3f3f3f3f3f3f3fULL);
+  __ and_(R0, R0, Operand(R1));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(EorImm, test) {
+  typedef int (*SimpleCode)();
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(SimpleCode, test->entry()));
+}
+
+// TODO(zra): andis after branches are implemented.
+
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 8eee03d..0266e1b 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -60,7 +60,14 @@
 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
 
-DECLARE_FLAG(charp, deoptimize_filter);
+DEFINE_FLAG(int, stacktrace_every, 0,
+            "Compute debugger stacktrace on every N stack overflow checks");
+DEFINE_FLAG(charp, stacktrace_filter, NULL,
+            "Compute stacktrace in named function on stack overflow checks");
+DEFINE_FLAG(int, deoptimize_every, 0,
+            "Deoptimize on every N stack overflow checks");
+DEFINE_FLAG(charp, deoptimize_filter, NULL,
+            "Deoptimize in named function on stack overflow checks");
 
 
 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) {
@@ -1022,9 +1029,14 @@
 #else
   uword stack_pos = reinterpret_cast<uword>(&arguments);
 #endif
+  // Always clear the stack overflow flags.  They are meant for this
+  // particular stack overflow runtime call and are not meant to
+  // persist.
+  uword stack_overflow_flags = isolate->GetAndClearStackOverflowFlags();
 
   // If an interrupt happens at the same time as a stack overflow, we
-  // process the stack overflow first.
+  // process the stack overflow now and leave the interrupt for next
+  // time.
   if (stack_pos < isolate->saved_stack_limit()) {
     // Use the preallocated stack overflow exception to avoid calling
     // into dart code.
@@ -1035,16 +1047,16 @@
   }
 
   uword interrupt_bits = isolate->GetAndClearInterrupts();
-  if (interrupt_bits & Isolate::kStoreBufferInterrupt) {
+  if ((interrupt_bits & Isolate::kStoreBufferInterrupt) != 0) {
     if (FLAG_verbose_gc) {
       OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
     }
     isolate->heap()->CollectGarbage(Heap::kNew);
   }
-  if (interrupt_bits & Isolate::kMessageInterrupt) {
+  if ((interrupt_bits & Isolate::kMessageInterrupt) != 0) {
     isolate->message_handler()->HandleOOBMessages();
   }
-  if (interrupt_bits & Isolate::kApiInterrupt) {
+  if ((interrupt_bits & Isolate::kApiInterrupt) != 0) {
     // Signal isolate interrupt event.
     Debugger::SignalIsolateInterrupted();
 
@@ -1058,14 +1070,15 @@
       }
     }
   }
-  if (interrupt_bits & Isolate::kVmStatusInterrupt) {
+  if ((interrupt_bits & Isolate::kVmStatusInterrupt) != 0) {
     Dart_IsolateInterruptCallback callback = isolate->VmStatsCallback();
     if (callback) {
       (*callback)();
     }
   }
 
-  if (FLAG_use_osr && (interrupt_bits == 0)) {
+  if ((stack_overflow_flags & Isolate::kOsrRequest) != 0) {
+    ASSERT(FLAG_use_osr);
     DartFrameIterator iterator;
     StackFrame* frame = iterator.NextFrame();
     ASSERT(frame != NULL);
@@ -1112,24 +1125,65 @@
     }
   }
 
-  if (FLAG_deoptimize_filter != NULL) {
+  // The following code is used to stress test deoptimization and
+  // debugger stack tracing.
+  bool do_deopt = false;
+  bool do_stacktrace = false;
+  if (FLAG_deoptimize_every > 0 ||
+      FLAG_stacktrace_every > 0) {
+    // TODO(turnidge): To make --deoptimize_every and
+    // --stacktrace-every faster we could move this increment/test to
+    // the generated code.
+    int32_t count = isolate->IncrementAndGetStackOverflowCount();
+    if (FLAG_deoptimize_every > 0 &&
+        (count % FLAG_deoptimize_every) == 0) {
+      do_deopt = true;
+    }
+    if (FLAG_stacktrace_every > 0 &&
+        (count % FLAG_stacktrace_every) == 0) {
+      do_stacktrace = true;
+    }
+  }
+  if (FLAG_deoptimize_filter != NULL ||
+      FLAG_stacktrace_filter != NULL) {
     DartFrameIterator iterator;
     StackFrame* frame = iterator.NextFrame();
     ASSERT(frame != NULL);
     const Code& code = Code::Handle(frame->LookupDartCode());
     ASSERT(!code.IsNull());
-    if (code.is_optimized()) {
-      const Function& function = Function::Handle(code.function());
-      ASSERT(!function.IsNull());
-      if (strstr(function.ToFullyQualifiedCString(),
-                 FLAG_deoptimize_filter) != NULL) {
-        if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
-          OS::PrintErr("*** Forcing deoptimization (%s)\n",
-                       function.ToFullyQualifiedCString());
-          // TODO(turnidge): Consider changing to DeoptimizeAt for
-          // just the top frame.
-          DeoptimizeAll();
-        }
+    const Function& function = Function::Handle(code.function());
+    ASSERT(!function.IsNull());
+    const char* function_name = function.ToFullyQualifiedCString();
+    ASSERT(function_name != NULL);
+    if (code.is_optimized() &&
+        FLAG_deoptimize_filter != NULL &&
+        strstr(function_name, FLAG_deoptimize_filter) != NULL) {
+      OS::PrintErr("*** Forcing deoptimization (%s)\n",
+                   function.ToFullyQualifiedCString());
+      do_deopt = true;
+    }
+    if (FLAG_stacktrace_filter != NULL &&
+        strstr(function_name, FLAG_stacktrace_filter) != NULL) {
+      OS::PrintErr("*** Computing stacktrace (%s)\n",
+                   function.ToFullyQualifiedCString());
+      do_stacktrace = true;
+    }
+  }
+  if (do_deopt) {
+    // TODO(turnidge): Consider using DeoptimizeAt instead.
+    DeoptimizeAll();
+  }
+  if (do_stacktrace) {
+    String& var_name = String::Handle();
+    Instance& var_value = Instance::Handle();
+    DebuggerStackTrace* stack = isolate->debugger()->StackTrace();
+    intptr_t num_frames = stack->Length();
+    for (intptr_t i = 0; i < num_frames; i++) {
+      ActivationFrame* frame = stack->FrameAt(i);
+      const int num_vars = frame->NumLocalVariables();
+      intptr_t unused;
+      for (intptr_t v = 0; v < num_vars; v++) {
+        frame->VariableAt(v, &var_name, &unused, &unused, &var_value);
       }
     }
   }
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 2cffb65..308a279 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -299,6 +299,16 @@
   SUBI = AddSubImmFixed | B30,
 };
 
+// C3.4.4
+enum LogicalImmOp {
+  LogicalImmMask = 0x1f800000,
+  LogicalImmFixed = DPImmediateFixed | B25,
+  ANDI = LogicalImmFixed,
+  ORRI = LogicalImmFixed | B29,
+  EORI = LogicalImmFixed | B30,
+  ANDIS = LogicalImmFixed | B30 | B29,
+};
+
 // C3.4.5
 enum MoveWideOp {
   MoveWideMask = 0x1f800000,
@@ -308,7 +318,6 @@
   MOVK = MoveWideFixed | B30 | B29,
 };
 
-
 // C3.5.1
 enum AddSubShiftExtOp {
   AddSubShiftExtMask = 0x1f000000,
@@ -317,6 +326,19 @@
   SUB = AddSubShiftExtFixed | B30,
 };
 
+enum LogicalShiftOp {
+  LogicalShiftMask = 0x1f000000,
+  LogicalShiftFixed = DPRegisterFixed,
+  AND = LogicalShiftFixed,
+  BIC = LogicalShiftFixed | B21,
+  ORR = LogicalShiftFixed | B29,
+  ORN = LogicalShiftFixed | B29 | B21,
+  EOR = LogicalShiftFixed | B30,
+  EON = LogicalShiftFixed | B30 | B21,
+  ANDS = LogicalShiftFixed | B30 | B29,
+  BICS = LogicalShiftFixed | B30 | B29 | B21,
+};
+
 #define APPLY_OP_LIST(_V)                                                      \
 _V(DPImmediate)                                                                \
 _V(CompareBranch)                                                              \
@@ -329,8 +351,10 @@
 _V(LoadStoreReg)                                                               \
 _V(UnconditionalBranchReg)                                                     \
 _V(AddSubImm)                                                                  \
+_V(LogicalImm)                                                                 \
 _V(MoveWide)                                                                   \
 _V(AddSubShiftExt)                                                             \
+_V(LogicalShift)                                                               \
 
 
 enum Shift {
@@ -402,12 +426,20 @@
   kImm16Shift = 5,
   kImm16Bits = 16,
 
+  // Bitfield immediates.
+  kNShift = 22,
+  kNBits = 1,
+  kImmRShift = 16,
+  kImmRBits = 6,
+  kImmSShift = 10,
+  kImmSBits = 6,
+
   kHWShift = 21,
   kHWBits = 2,
 
   // Shift and Extend.
-  kShiftExtendShift = 21,
-  kShiftExtendBits = 1,
+  kAddShiftExtendShift = 21,
+  kAddShiftExtendBits = 1,
   kShiftTypeShift = 22,
   kShiftTypeBits = 2,
   kExtendTypeShift = 13,
@@ -426,6 +458,27 @@
 const uint32_t kImmExceptionIsPrintf = 0xdeb1;
 const uint32_t kImmExceptionIsDebug = 0xdeb0;
 
+// Helper functions for decoding logical immediates.
+static inline uint64_t RotateRight(
+    uint64_t value, uint8_t rotate, uint8_t width) {
+  ASSERT(width <= 64);
+  rotate &= 63;
+  return ((value & ((1UL << rotate) - 1UL)) << (width - rotate)) |
+         (value >> rotate);
+}
+
+static inline uint64_t RepeatBitsAcrossReg(
+    uint8_t reg_size, uint64_t value, uint8_t width) {
+  ASSERT((width == 2) || (width == 4) || (width == 8) || (width == 16) ||
+         (width == 32));
+  ASSERT((reg_size == kWRegSizeInBits) || (reg_size == kXRegSizeInBits));
+  uint64_t result = value & ((1UL << width) - 1UL);
+  for (unsigned i = width; i < reg_size; i *= 2) {
+    result |= (result << i);
+  }
+  return result;
+}
+
 // The class Instr enables access to individual fields defined in the ARM
 // architecture instruction set encoding as described in figure A3-1.
 //
@@ -470,7 +523,7 @@
     return (InstructionBits() >> shift) & ((1 << count) - 1);
   }
 
-
+  inline int NField() const { return Bit(22); }
   inline int SField() const { return Bit(kSShift); }
   inline int SFField() const { return Bit(kSFShift); }
   inline int SzField() const { return Bits(kSzShift, kSzBits); }
@@ -488,20 +541,29 @@
   // Immediates
   inline int Imm3Field() const { return Bits(kImm3Shift, kImm3Bits); }
   inline int Imm6Field() const { return Bits(kImm6Shift, kImm6Bits); }
+
   inline int Imm9Field() const { return Bits(kImm9Shift, kImm9Bits); }
   // Sign-extended Imm9Field()
   inline int64_t SImm9Field() const {
       return (static_cast<int32_t>(Imm9Field()) << 23) >> 23; }
-  inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
-  inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
 
+  inline int Imm12Field() const { return Bits(kImm12Shift, kImm12Bits); }
   inline int Imm12ShiftField() const {
     return Bits(kImm12ShiftShift, kImm12ShiftBits); }
+
+  inline int Imm16Field() const { return Bits(kImm16Shift, kImm16Bits); }
   inline int HWField() const { return Bits(kHWShift, kHWBits); }
 
+  inline int ImmRField() const { return Bits(kImmRShift, kImmRBits); }
+  inline int ImmSField() const { return Bits(kImmSShift, kImmSBits); }
+
   // Shift and Extend.
-  inline bool IsShift() const { return (Bit(kShiftExtendShift) == 0); }
-  inline bool IsExtend() const { return (Bit(kShiftExtendShift) == 1); }
+  inline bool IsShift() const {
+    return IsLogicalShiftOp() || (Bit(kAddShiftExtendShift) == 0);
+  }
+  inline bool IsExtend() const {
+    return !IsLogicalShiftOp() && (Bit(kAddShiftExtendShift) == 1);
+  }
   inline Shift ShiftTypeField() const {
       return static_cast<Shift>(Bits(kShiftTypeShift, kShiftTypeBits)); }
   inline Extend ExtendTypeField() const {
@@ -553,6 +615,59 @@
     return R31IsZR;
   }
 
+  // Logical immediates can't encode zero, so a return value of zero is used to
+  // indicate a failure case. Specifically, where the constraints on imm_s are
+  // not met.
+  uint64_t ImmLogical() {
+    const uint8_t reg_size =
+        SFField() == 1 ? kXRegSizeInBits : kWRegSizeInBits;
+    const int64_t n = NField();
+    const int64_t imm_s = ImmSField();
+    const int64_t imm_r = ImmRField();
+
+    // An integer is constructed from the n, imm_s and imm_r bits according to
+    // the following table:
+    //
+    //  N   imms    immr    size        S             R
+    //  1  ssssss  rrrrrr    64    UInt(ssssss)  UInt(rrrrrr)
+    //  0  0sssss  xrrrrr    32    UInt(sssss)   UInt(rrrrr)
+    //  0  10ssss  xxrrrr    16    UInt(ssss)    UInt(rrrr)
+    //  0  110sss  xxxrrr     8    UInt(sss)     UInt(rrr)
+    //  0  1110ss  xxxxrr     4    UInt(ss)      UInt(rr)
+    //  0  11110s  xxxxxr     2    UInt(s)       UInt(r)
+    // (s bits must not be all set)
+    //
+    // A pattern is constructed of size bits, where the least significant S+1
+    // bits are set. The pattern is rotated right by R, and repeated across a
+    // 32 or 64-bit value, depending on destination register width.
+
+    if (n == 1) {
+      if (imm_s == 0x3F) {
+        return 0;
+      }
+      uint64_t bits = (1UL << (imm_s + 1)) - 1;
+      return RotateRight(bits, imm_r, 64);
+    } else {
+      if ((imm_s >> 1) == 0x1F) {
+        return 0;
+      }
+      for (int width = 0x20; width >= 0x2; width >>= 1) {
+        if ((imm_s & width) == 0) {
+          int mask = width - 1;
+          if ((imm_s & mask) == mask) {
+            return 0;
+          }
+          uint64_t bits = (1UL << ((imm_s & mask) + 1)) - 1;
+          return RepeatBitsAcrossReg(reg_size,
+                                     RotateRight(bits, imm_r & mask, width),
+                                     width);
+        }
+      }
+    }
+    UNREACHABLE();
+    return 0;
+  }
+
   // Instructions are read out of a code stream. The only way to get a
   // reference to an instruction is to convert a pointer. There is no way
   // to allocate or create instances of class Instr.
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index 4859b69..2e453d1 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -347,6 +347,15 @@
       PrintMemOperand(instr);
       return 5;
     }
+    case 'b': {
+      ASSERT(STRING_STARTS_WITH(format, "bitimm"));
+      const uint64_t imm = instr->ImmLogical();
+      buffer_pos_ += OS::SNPrint(current_position_in_buffer(),
+                                 remaining_size_in_buffer(),
+                                 "0x%"Px64,
+                                 imm);
+      return 6;
+    }
     default: {
       UNREACHABLE();
       break;
@@ -414,11 +423,43 @@
 
 void ARM64Decoder::DecodeAddSubImm(Instr* instr) {
   switch (instr->Bit(30)) {
+    case 0: {
+      if ((instr->RdField() == R31) && (instr->SFField())) {
+        Format(instr, "cmni'sf 'rn, 'imm12s");
+      } else {
+        Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
+      }
+      break;
+    }
+    case 1: {
+      if ((instr->RdField() == R31) && (instr->SFField())) {
+        Format(instr, "cmpi'sf 'rn, 'imm12s");
+      } else {
+        Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
+      }
+      break;
+    }
+    default:
+      Unknown(instr);
+      break;
+  }
+}
+
+
+void ARM64Decoder::DecodeLogicalImm(Instr* instr) {
+  int op = instr->Bits(29, 2);
+  switch (op) {
     case 0:
-      Format(instr, "addi'sf's 'rd, 'rn, 'imm12s");
+      Format(instr, "andi'sf 'rd, 'rn, 'bitimm");
       break;
     case 1:
-      Format(instr, "subi'sf's 'rd, 'rn, 'imm12s");
+      Format(instr, "orri'sf 'rd, 'rn, 'bitimm");
+      break;
+    case 2:
+      Format(instr, "eori'sf 'rd, 'rn, 'bitimm");
+      break;
+    case 3:
+      Format(instr, "andi'sfs 'rd, 'rn, 'bitimm");
       break;
     default:
       Unknown(instr);
@@ -426,11 +467,14 @@
   }
 }
 
+
 void ARM64Decoder::DecodeDPImmediate(Instr* instr) {
   if (instr->IsMoveWideOp()) {
     DecodeMoveWide(instr);
   } else if (instr->IsAddSubImmOp()) {
     DecodeAddSubImm(instr);
+  } else if (instr->IsLogicalImmOp()) {
+    DecodeLogicalImm(instr);
   } else {
     Unknown(instr);
   }
@@ -511,11 +555,55 @@
 
 void ARM64Decoder::DecodeAddSubShiftExt(Instr* instr) {
   switch (instr->Bit(30)) {
+    case 0: {
+      if ((instr->RdField() == R31) && (instr->SFField())) {
+        Format(instr, "cmn'sf 'rn, 'shift_op");
+      } else {
+        Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
+      }
+      break;
+    }
+    case 1: {
+      if ((instr->RdField() == R31) && (instr->SFField())) {
+        Format(instr, "cmp'sf 'rn, 'shift_op");
+      } else {
+        Format(instr, "sub'sf's 'rd, 'rn, 'shift_op");
+      }
+      break;
+    }
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void ARM64Decoder::DecodeLogicalShift(Instr* instr) {
+  const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
+  switch (op) {
     case 0:
-      Format(instr, "add'sf's 'rd, 'rn, 'shift_op");
+      Format(instr, "and'sf 'rd, 'rn, 'shift_op");
       break;
     case 1:
-      Format(instr, "sub'sf's 'rd, 'rn, 'shift_op");
+      Format(instr, "bic'sf 'rd, 'rn, 'shift_op");
+      break;
+    case 2:
+      Format(instr, "orr'sf 'rd, 'rn, 'shift_op");
+      break;
+    case 3:
+      Format(instr, "orn'sf 'rd, 'rn, 'shift_op");
+      break;
+    case 4:
+      Format(instr, "eor'sf 'rd, 'rn, 'shift_op");
+      break;
+    case 5:
+      Format(instr, "eon'sf 'rd, 'rn, 'shift_op");
+      break;
+    case 6:
+      Format(instr, "and'sfs 'rd, 'rn, 'shift_op");
+      break;
+    case 7:
+      Format(instr, "bic'sfs 'rd, 'rn, 'shift_op");
       break;
     default:
       UNREACHABLE();
@@ -527,6 +615,8 @@
 void ARM64Decoder::DecodeDPRegister(Instr* instr) {
   if (instr->IsAddSubShiftExtOp()) {
     DecodeAddSubShiftExt(instr);
+  } else if (instr->IsLogicalShiftOp()) {
+    DecodeLogicalShift(instr);
   } else {
     Unknown(instr);
   }
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 5ba1ab7..845c7ff 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -33,10 +33,13 @@
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, use_cha);
 DECLARE_FLAG(bool, use_osr);
+DECLARE_FLAG(int, stacktrace_every);
+DECLARE_FLAG(charp, stacktrace_filter);
+DECLARE_FLAG(int, deoptimize_every);
+DECLARE_FLAG(charp, deoptimize_filter);
+
 DEFINE_FLAG(bool, enable_simd_inline, true,
     "Enable inlining of SIMD related method calls.");
-DEFINE_FLAG(charp, deoptimize_filter, NULL,
-            "Force deoptimization in named function");
 
 // Assign locations to incoming arguments, i.e., values pushed above spill slots
 // with PushArgument.  Recursively allocates from outermost to innermost
@@ -171,11 +174,22 @@
 }
 
 
-bool FlowGraphCompiler::ShouldDeoptimizeFunction() const {
-  return (is_optimizing() &&
-          (FLAG_deoptimize_filter != NULL) &&
-          (strstr(parsed_function().function().ToFullyQualifiedCString(),
-                  FLAG_deoptimize_filter) != NULL));
+bool FlowGraphCompiler::ForceSlowPathForStackOverflow() const {
+  if (FLAG_stacktrace_every > 0 || FLAG_deoptimize_every > 0) {
+    return true;
+  }
+  if (FLAG_stacktrace_filter != NULL &&
+      strstr(parsed_function().function().ToFullyQualifiedCString(),
+             FLAG_stacktrace_filter) != NULL) {
+    return true;
+  }
+  if (is_optimizing() &&
+      FLAG_deoptimize_filter != NULL &&
+      strstr(parsed_function().function().ToFullyQualifiedCString(),
+             FLAG_deoptimize_filter) != NULL) {
+    return true;
+  }
+  return false;
 }
 
 
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index e9a1476..6940af2 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -269,7 +269,7 @@
   bool CanOSRFunction() const;
   bool is_optimizing() const { return is_optimizing_; }
 
-  bool ShouldDeoptimizeFunction() const;
+  bool ForceSlowPathForStackOverflow() const;
 
   const GrowableArray<BlockInfo*>& block_info() const { return block_info_; }
   ParallelMoveResolver* parallel_move_resolver() {
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 1ae7daa..b40b3b3 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2573,6 +2573,15 @@
       : instruction_(instruction) { }
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (FLAG_use_osr) {
+      uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+      Register value = instruction_->locs()->temp(0).reg();
+      __ Comment("CheckStackOverflowSlowPathOsr");
+      __ Bind(osr_entry_label());
+      __ LoadImmediate(IP, flags_address);
+      __ LoadImmediate(value, Isolate::kOsrRequest);
+      __ str(value, Address(IP));
+    }
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
     compiler->SaveLiveRegisters(instruction_->locs());
@@ -2598,8 +2607,14 @@
     __ b(exit_label());
   }
 
+  Label* osr_entry_label() {
+    ASSERT(FLAG_use_osr);
+    return &osr_entry_label_;
+  }
+
  private:
   CheckStackOverflowInstr* instruction_;
+  Label osr_entry_label_;
 };
 
 
@@ -2621,7 +2636,10 @@
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ ldr(temp, FieldAddress(temp, Function::usage_counter_offset()));
     __ CompareImmediate(temp, threshold);
-    __ b(slow_path->entry_label(), GE);
+    __ b(slow_path->osr_entry_label(), GE);
+  }
+  if (compiler->ForceSlowPathForStackOverflow()) {
+    __ b(slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
 }
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 74a7587..d6a5573 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -2536,6 +2536,13 @@
       : instruction_(instruction) { }
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (FLAG_use_osr) {
+      uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+      __ Comment("CheckStackOverflowSlowPathOsr");
+      __ Bind(osr_entry_label());
+      __ movl(Address::Absolute(flags_address),
+              Immediate(Isolate::kOsrRequest));
+    }
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
     compiler->SaveLiveRegisters(instruction_->locs());
@@ -2561,8 +2568,14 @@
     __ jmp(exit_label());
   }
 
+  Label* osr_entry_label() {
+    ASSERT(FLAG_use_osr);
+    return &osr_entry_label_;
+  }
+
  private:
   CheckStackOverflowInstr* instruction_;
+  Label osr_entry_label_;
 };
 
 
@@ -2570,9 +2583,6 @@
   CheckStackOverflowSlowPath* slow_path = new CheckStackOverflowSlowPath(this);
   compiler->AddSlowPathCode(slow_path);
 
-  if (compiler->ShouldDeoptimizeFunction()) {
-    __ jmp(slow_path->entry_label());
-  }
   __ cmpl(ESP,
           Address::Absolute(Isolate::Current()->stack_limit_address()));
   __ j(BELOW_EQUAL, slow_path->entry_label());
@@ -2585,7 +2595,12 @@
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ cmpl(FieldAddress(EDI, Function::usage_counter_offset()),
             Immediate(threshold));
-    __ j(GREATER_EQUAL, slow_path->entry_label());
+    __ j(GREATER_EQUAL, slow_path->osr_entry_label());
+  }
+  if (compiler->ForceSlowPathForStackOverflow()) {
+    // TODO(turnidge): Implement stack overflow count in assembly to
+    // make --stacktrace-every and --deoptimize-every faster.
+    __ jmp(slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
 }
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index fe94ba22..ad6a564 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -2312,6 +2312,16 @@
       : instruction_(instruction) { }
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (FLAG_use_osr) {
+      uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+      Register value = instruction_->locs()->temp(0).reg();
+      __ TraceSimMsg("CheckStackOverflowSlowPathOsr");
+      __ Comment("CheckStackOverflowSlowPathOsr");
+      __ Bind(osr_entry_label());
+      __ LoadImmediate(TMP, flags_address);
+      __ LoadImmediate(value, Isolate::kOsrRequest);
+      __ sw(value, Address(TMP));
+    }
     __ TraceSimMsg("CheckStackOverflowSlowPath");
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
@@ -2338,8 +2348,14 @@
     __ b(exit_label());
   }
 
+  Label* osr_entry_label() {
+    ASSERT(FLAG_use_osr);
+    return &osr_entry_label_;
+  }
+
  private:
   CheckStackOverflowInstr* instruction_;
+  Label osr_entry_label_;
 };
 
 
@@ -2349,7 +2365,6 @@
   compiler->AddSlowPathCode(slow_path);
 
   __ LoadImmediate(TMP, Isolate::Current()->stack_limit_address());
-
   __ lw(CMPRES1, Address(TMP));
   __ BranchUnsignedLessEqual(SP, CMPRES1, slow_path->entry_label());
   if (compiler->CanOSRFunction() && in_loop()) {
@@ -2361,7 +2376,10 @@
     intptr_t threshold =
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ lw(temp, FieldAddress(temp, Function::usage_counter_offset()));
-    __ BranchSignedGreaterEqual(temp, threshold, slow_path->entry_label());
+    __ BranchSignedGreaterEqual(temp, threshold, slow_path->osr_entry_label());
+  }
+  if (compiler->ForceSlowPathForStackOverflow()) {
+    __ b(slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
 }
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index f5d8fc8..bbdd1fc 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2317,6 +2317,14 @@
       : instruction_(instruction) { }
 
   virtual void EmitNativeCode(FlowGraphCompiler* compiler) {
+    if (FLAG_use_osr) {
+      uword flags_address = Isolate::Current()->stack_overflow_flags_address();
+      Register temp = instruction_->locs()->temp(0).reg();
+      __ Comment("CheckStackOverflowSlowPathOsr");
+      __ Bind(osr_entry_label());
+      __ LoadImmediate(temp, Immediate(flags_address), PP);
+      __ movq(Address(temp, 0), Immediate(Isolate::kOsrRequest));
+    }
     __ Comment("CheckStackOverflowSlowPath");
     __ Bind(entry_label());
     compiler->SaveLiveRegisters(instruction_->locs());
@@ -2342,8 +2350,15 @@
     __ jmp(exit_label());
   }
 
+
+  Label* osr_entry_label() {
+    ASSERT(FLAG_use_osr);
+    return &osr_entry_label_;
+  }
+
  private:
   CheckStackOverflowInstr* instruction_;
+  Label osr_entry_label_;
 };
 
 
@@ -2366,7 +2381,10 @@
         FLAG_optimization_counter_threshold * (loop_depth() + 1);
     __ CompareImmediate(FieldAddress(temp, Function::usage_counter_offset()),
                         Immediate(threshold), PP);
-    __ j(GREATER_EQUAL, slow_path->entry_label());
+    __ j(GREATER_EQUAL, slow_path->osr_entry_label());
+  }
+  if (compiler->ForceSlowPathForStackOverflow()) {
+    __ jmp(slow_path->entry_label());
   }
   __ Bind(slow_path->exit_label());
 }
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d10bef9..aa8f2a7 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -321,6 +321,8 @@
       mutex_(new Mutex()),
       stack_limit_(0),
       saved_stack_limit_(0),
+      stack_overflow_flags_(0),
+      stack_overflow_count_(0),
       message_handler_(NULL),
       spawn_state_(NULL),
       is_runnable_(false),
@@ -662,6 +664,13 @@
 }
 
 
+uword Isolate::GetAndClearStackOverflowFlags() {
+  uword stack_overflow_flags = stack_overflow_flags_;
+  stack_overflow_flags_ = 0;
+  return stack_overflow_flags;
+}
+
+
 static int MostUsedFunctionFirst(const Function* const* a,
                                  const Function* const* b) {
   if ((*a)->usage_counter() > (*b)->usage_counter()) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 7bb26a5..2998fd8 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -226,6 +226,24 @@
   // The true stack limit for this isolate.
   uword saved_stack_limit() const { return saved_stack_limit_; }
 
+  // Stack overflow flags
+  enum {
+    kOsrRequest = 0x1,  // Current stack overflow caused by OSR request.
+  };
+
+  uword stack_overflow_flags_address() const {
+    return reinterpret_cast<uword>(&stack_overflow_flags_);
+  }
+
+  int32_t IncrementAndGetStackOverflowCount() {
+    return ++stack_overflow_count_;
+  }
+
+  // Retrieves and clears the stack overflow flags.  These are set by
+  // the generated code before the slow path runtime routine for a
+  // stack overflow is called.
+  uword GetAndClearStackOverflowFlags();
+
   // Retrieve the stack address bounds.
   bool GetStackBounds(uword* lower, uword* upper);
 
@@ -233,6 +251,7 @@
 
   static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize);
 
+  // Interrupt bits.
   enum {
     kApiInterrupt = 0x1,      // An interrupt from Dart_InterruptIsolate.
     kMessageInterrupt = 0x2,  // An interrupt to process an out of band message.
@@ -510,6 +529,8 @@
   Mutex* mutex_;  // protects stack_limit_ and saved_stack_limit_.
   uword stack_limit_;
   uword saved_stack_limit_;
+  uword stack_overflow_flags_;
+  int32_t stack_overflow_count_;
   MessageHandler* message_handler_;
   IsolateSpawnState* spawn_state_;
   bool is_runnable_;
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 1b34b63..d3cab91 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -13,7 +13,7 @@
 
 namespace dart {
 
-DEFINE_FLAG(int, heap_growth_space_ratio, 10,
+DEFINE_FLAG(int, heap_growth_space_ratio, 20,
             "The desired maximum percentage of free space after GC");
 DEFINE_FLAG(int, heap_growth_time_ratio, 3,
             "The desired maximum percentage of time spent in GC");
@@ -692,15 +692,16 @@
   if (enough_free_space && enough_free_time) {
     grow_heap_ = 0;
   } else {
-    intptr_t growth_target = static_cast<intptr_t>(
+    intptr_t used_target = static_cast<intptr_t>(
         after_total_in_words /  desired_utilization_);
-    intptr_t growth_in_words = Utils::RoundUp(
-        growth_target - after_total_in_words,
-        PageSpace::kPageSizeInWords);
-    int growth_in_pages =
-        growth_in_words / PageSpace::kPageSizeInWords;
-    grow_heap_ = Utils::Maximum(growth_in_pages, heap_growth_rate_);
-    heap->RecordData(PageSpace::kPageGrowth, growth_in_pages);
+    intptr_t capacity_growth_in_words =
+      Utils::RoundUp(Utils::Maximum(static_cast<intptr_t>(0),
+                                    used_target - after.capacity_in_words),
+                       PageSpace::kPageSizeInWords);
+    int capacity_growth_in_pages =
+        capacity_growth_in_words / PageSpace::kPageSizeInWords;
+    grow_heap_ = Utils::Maximum(capacity_growth_in_pages, heap_growth_rate_);
+    heap->RecordData(PageSpace::kPageGrowth, capacity_growth_in_pages);
   }
   heap->RecordData(PageSpace::kGarbageRatio, collected_garbage_ratio);
   heap->RecordData(PageSpace::kGCTimeFraction,
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index b549c6a..6645901 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -10323,7 +10323,9 @@
       } else {
         ASSERT(CurrentToken() == Token::kINTERPOL_START);
         ConsumeToken();
+        const bool saved_mode = SetAllowFunctionLiterals(true);
         expr = ParseExpr(kAllowConst, kConsumeCascades);
+        SetAllowFunctionLiterals(saved_mode);
         ExpectToken(Token::kINTERPOL_END);
       }
       // Check if this interpolated string is still considered a compile time
@@ -10741,7 +10743,9 @@
         ConsumeToken();
       } else if (CurrentToken() == Token::kINTERPOL_START) {
         ConsumeToken();
+        const bool saved_mode = SetAllowFunctionLiterals(true);
         SkipExpr();
+        SetAllowFunctionLiterals(saved_mode);
         ExpectToken(Token::kINTERPOL_END);
       } else {
         break;
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index d15b8e3..5a462cf 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -477,11 +477,64 @@
   }
 }
 
+
+void Simulator::DecodeLogicalImm(Instr* instr) {
+  const int op = instr->Bits(29, 2);
+  const bool set_flags = op == 3;
+  const int out_size = ((instr->SFField() == 0) && (instr->NField() == 0))
+                       ? kWRegSizeInBits : kXRegSizeInBits;
+  const Register rn = instr->RnField();
+  const Register rd = instr->RdField();
+  const int64_t rn_val = get_register(rn, instr->RnMode());
+  const uint64_t imm = instr->ImmLogical();
+  if (imm == 0) {
+    UnimplementedInstruction(instr);
+  }
+
+  int64_t alu_out = 0;
+  switch (op) {
+    case 0:
+      alu_out = rn_val & imm;
+      break;
+    case 1:
+      alu_out = rn_val | imm;
+      break;
+    case 2:
+      alu_out = rn_val ^ imm;
+      break;
+    case 3:
+      alu_out = rn_val & imm;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+
+  if (set_flags) {
+    if (out_size == kXRegSizeInBits) {
+      SetNZFlagsX(alu_out);
+    } else {
+      SetNZFlagsW(alu_out);
+    }
+    SetCFlag(false);
+    SetVFlag(false);
+  }
+
+  if (out_size == kXRegSizeInBits) {
+    set_register(rd, alu_out, instr->RdMode());
+  } else {
+    set_wregister(rd, alu_out, instr->RdMode());
+  }
+}
+
+
 void Simulator::DecodeDPImmediate(Instr* instr) {
   if (instr->IsMoveWideOp()) {
     DecodeMoveWide(instr);
   } else if (instr->IsAddSubImmOp()) {
     DecodeAddSubImm(instr);
+  } else if (instr->IsLogicalImmOp()) {
+    DecodeLogicalImm(instr);
   } else {
     UnimplementedInstruction(instr);
   }
@@ -821,9 +874,75 @@
 }
 
 
+void Simulator::DecodeLogicalShift(Instr* instr) {
+  const int op = (instr->Bits(29, 2) << 1) | instr->Bit(21);
+  const Register rd = instr->RdField();
+  const Register rn = instr->RnField();
+  const int64_t rn_val = get_register(rn, instr->RnMode());
+  const int64_t rm_val = DecodeShiftExtendOperand(instr);
+  int64_t alu_out = 0;
+  switch (op) {
+    case 0:
+      // Format(instr, "and'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val & rm_val;
+      break;
+    case 1:
+      // Format(instr, "bic'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val & (~rm_val);
+      break;
+    case 2:
+      // Format(instr, "orr'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val | rm_val;
+      break;
+    case 3:
+      // Format(instr, "orn'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val | (~rm_val);
+      break;
+    case 4:
+      // Format(instr, "eor'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val ^ rm_val;
+      break;
+    case 5:
+      // Format(instr, "eon'sf 'rd, 'rn, 'shift_op");
+      alu_out = rn_val ^ (~rm_val);
+      break;
+    case 6:
+      // Format(instr, "and'sfs 'rd, 'rn, 'shift_op");
+      alu_out = rn_val & rm_val;
+      break;
+    case 7:
+      // Format(instr, "bic'sfs 'rd, 'rn, 'shift_op");
+      alu_out = rn_val & (~rm_val);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+
+  // Set flags if ands or bics.
+  if ((op == 6) || (op == 7)) {
+    if (instr->SFField() == 1) {
+      SetNZFlagsX(alu_out);
+    } else {
+      SetNZFlagsW(alu_out);
+    }
+    SetCFlag(false);
+    SetVFlag(false);
+  }
+
+  if (instr->SFField() == 1) {
+    set_register(rd, alu_out, instr->RdMode());
+  } else {
+    set_wregister(rd, alu_out & kWRegMask, instr->RdMode());
+  }
+}
+
+
 void Simulator::DecodeDPRegister(Instr* instr) {
   if (instr->IsAddSubShiftExtOp()) {
     DecodeAddSubShiftExt(instr);
+  } else if (instr->IsLogicalShiftOp()) {
+    DecodeLogicalShift(instr);
   } else {
     UnimplementedInstruction(instr);
   }
diff --git a/sdk/lib/_internal/compiler/implementation/apiimpl.dart b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
index 1e417ab..bdfd4b4 100644
--- a/sdk/lib/_internal/compiler/implementation/apiimpl.dart
+++ b/sdk/lib/_internal/compiler/implementation/apiimpl.dart
@@ -10,7 +10,6 @@
 import 'dart2jslib.dart' as leg;
 import 'tree/tree.dart' as tree;
 import 'elements/elements.dart' as elements;
-import 'ssa/tracer.dart' as ssa;
 import '../../libraries.dart';
 import 'source_file.dart';
 
@@ -35,8 +34,6 @@
       : this.options = options,
         this.allowedLibraryCategories = getAllowedLibraryCategories(options),
         super(
-            tracer: new ssa.HTracer(
-                ssa.GENERATE_SSA_TRACE ? outputProvider('dart', 'cfg') : null),
             outputProvider: outputProvider,
             enableTypeAssertions: hasOption(options, '--enable-checked-mode'),
             enableUserAssertions: hasOption(options, '--enable-checked-mode'),
diff --git a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
index cc0eac6..2dfbb57 100644
--- a/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/compile_time_constants.dart
@@ -774,8 +774,8 @@
     assert(invariant(node, constructor.isImplementation));
 
     List<Constant> arguments = getArguments(constructor);
-    ConstructorEvaluator evaluator =
-        new ConstructorEvaluator(constructor, handler, compiler);
+    ConstructorEvaluator evaluator = new ConstructorEvaluator(
+        constructedType, constructor, handler, compiler);
     evaluator.evaluateConstructorFieldValues(arguments);
     List<Constant> jsNewArguments = evaluator.buildJsNewArguments(classElement);
 
@@ -807,6 +807,7 @@
 }
 
 class ConstructorEvaluator extends CompileTimeConstantEvaluator {
+  final InterfaceType constructedType;
   final FunctionElement constructor;
   final Map<Element, Constant> definitions;
   final Map<Element, Constant> fieldValues;
@@ -816,7 +817,8 @@
    *
    * Invariant: [constructor] must be an implementation element.
    */
-  ConstructorEvaluator(FunctionElement constructor,
+  ConstructorEvaluator(InterfaceType this.constructedType,
+                       FunctionElement constructor,
                        ConstantCompiler handler,
                        Compiler compiler)
       : this.constructor = constructor,
@@ -845,16 +847,12 @@
                             TypedElement element,
                             Constant constant) {
     if (compiler.enableTypeAssertions) {
-      DartType elementType = element.type;
+      DartType elementType = element.type.substByContext(constructedType);
       DartType constantType = constant.computeType(compiler);
-      // TODO(ngeoffray): Handle type parameters.
-      if (elementType.element.isTypeVariable()) return;
       if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
-        // TODO(johnniwinther): Provide better [node] values that point to the
-        // origin of the constant and not (just) the assignment.
         compiler.reportFatalError(
             node, MessageKind.NOT_ASSIGNABLE,
-            {'fromType': elementType, 'toType': constantType});
+            {'fromType': constantType, 'toType': elementType});
       }
     }
   }
@@ -871,9 +869,9 @@
    */
   void assignArgumentsToParameters(List<Constant> arguments) {
     // Assign arguments to parameters.
-    FunctionSignature parameters = constructor.functionSignature;
+    FunctionSignature signature = constructor.functionSignature;
     int index = 0;
-    parameters.orderedForEachParameter((Element parameter) {
+    signature.orderedForEachParameter((Element parameter) {
       Constant argument = arguments[index++];
       Node node = parameter.parseNode(compiler);
       potentiallyCheckType(node, parameter, argument);
@@ -888,6 +886,7 @@
   void evaluateSuperOrRedirectSend(List<Constant> compiledArguments,
                                    FunctionElement targetConstructor) {
     ConstructorEvaluator evaluator = new ConstructorEvaluator(
+        constructedType.asInstanceOf(targetConstructor.getEnclosingClass()),
         targetConstructor, handler, compiler);
     evaluator.evaluateConstructorFieldValues(compiledArguments);
     // Copy over the fieldValues from the super/redirect-constructor.
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index 824f203..4899ec7 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -437,7 +437,7 @@
 
   List<Uri> librariesToAnalyzeWhenRun;
 
-  final Tracer tracer;
+  Tracer tracer;
 
   CompilerTask measuredTask;
   Element _currentElement;
@@ -638,8 +638,7 @@
   /// Set by the backend if real reflection is detected in use of dart:mirrors.
   bool disableTypeInferenceForMirrors = false;
 
-  Compiler({this.tracer: const Tracer(),
-            this.enableTypeAssertions: false,
+  Compiler({this.enableTypeAssertions: false,
             this.enableUserAssertions: false,
             this.trustTypeAnnotations: false,
             this.enableConcreteTypeInference: false,
@@ -671,6 +670,7 @@
             ? NullSink.outputProvider
             : outputProvider {
     world = new World(this);
+    tracer = new Tracer(this.outputProvider);
 
     closureMapping.ClosureNamer closureNamer;
     if (emitJavaScript) {
@@ -1721,23 +1721,6 @@
   }
 }
 
-class Tracer {
-  final bool enabled = false;
-
-  const Tracer();
-
-  void traceCompilation(String methodName,
-                        ItemCompilationContext context,
-                        Compiler compiler) {
-  }
-
-  void traceGraph(String name, var graph) {
-  }
-
-  void close() {
-  }
-}
-
 class SourceSpan implements Spannable {
   final Uri uri;
   final int begin;
diff --git a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
index 008096f..c6ba9b6 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2jslib.dart
@@ -40,6 +40,7 @@
 import 'mirrors_used.dart' show MirrorUsageAnalyzerTask;
 import 'dump_info.dart';
 import 'helpers/helpers.dart';
+import 'tracer.dart' show Tracer;
 
 export 'resolution/resolution.dart' show TreeElements, TreeElementMapping;
 export 'scanner/scannerlib.dart' show isUserDefinableOperator,
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
index 94bdc2d..2d66728 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/backend.dart
@@ -236,9 +236,11 @@
         ir.Function function = compiler.irBuilder.getIr(element);
         tree.Builder builder = new tree.Builder(compiler);
         tree.Expression expr = function.accept(builder);
+        compiler.tracer.traceGraph('Tree builder', expr);
         treeElements = new TreeElementMapping(element);
         tree.Unnamer unnamer = new tree.Unnamer();
         expr = unnamer.unname(expr);
+        compiler.tracer.traceGraph('Unnamer', expr);
         tree.Emitter emitter = new tree.Emitter();
         node = emitter.emit(element, treeElements, expr);
       }
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart
new file mode 100644
index 0000000..e50ca26
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/tree_tracer.dart
@@ -0,0 +1,157 @@
+library dart_backend.tracer;
+
+import 'dart:async' show EventSink;
+import '../tracer.dart';
+import 'dart_tree.dart';
+  
+class TreeTracer extends TracerUtil implements Visitor {
+  
+  final EventSink<String> output;
+  
+  TreeTracer(this.output);
+  
+  Names names;
+  int stmtCounter;
+  
+  void traceGraph(String name, Expression exp) {
+    names = new Names();
+    stmtCounter = 0;
+    tag("cfg", () {
+      printProperty("name", name);
+      printBlock(exp);
+    });
+    names = null;
+  }
+  
+  void printBlock(Expression e) {
+    tag("block", () {
+      printProperty("name", "B0"); // Update when proper blocks exist
+      printProperty("from_bci", -1);
+      printProperty("to_bci", -1);
+      printProperty("predecessors", ""); // Update when proper blocks exist
+      printProperty("successors", ""); // Update when proper blocks exist
+      printEmptyProperty("xhandlers");
+      printEmptyProperty("flags");
+      tag("states", () {
+        tag("locals", () {
+          printProperty("size", 0);
+          printProperty("method", "None");
+        });
+      });
+      tag("HIR", () {
+        e.accept(this);
+      });
+    });
+  }
+  
+  void printStmt(String def, String contents) {
+    int bci = 0;
+    int uses = 0;
+    if (def == null) {
+      def = 'x${stmtCounter++}';
+    }
+    addIndent();
+    add("$bci $uses $def $contents <|@\n");
+  }
+  
+  visitVariable(Variable node) {
+    printStmt(null, "dead-use ${names.varName(node)}");
+  }
+  
+  visitSequence(Sequence node) {
+    for (Expression e in node.expressions) {
+      e.accept(this);
+    }
+  }
+  
+  visitLetVal(LetVal node) {
+    String name = names.varName(node.variable);
+    String rhs = expr(node.definition);
+    printStmt(name, "let $name = $rhs");
+    node.body.accept(this);
+  }
+  
+  visitInvokeStatic(InvokeStatic node) {
+    printStmt(null, expr(node));
+  }
+  
+  visitReturn(Return node) {
+    printStmt(null, "return ${expr(node.value)}");
+  }
+  
+  visitConstant(Constant node) {
+    printStmt(null, "dead-use ${node.value}");
+  }
+
+  visitNode(Node node) {}
+  visitExpression(Expression node) {}
+  
+  String expr(Expression e) {
+    return e.accept(new SubExprVisitor(names));
+  }
+  
+}
+
+class SubExprVisitor implements Visitor<String> {
+  Names names;
+  
+  SubExprVisitor(this.names);
+  
+  String visitVariable(Variable node) {
+    return names.varName(node);
+  }
+  String visitSequence(Sequence node) {
+    String exps = node.expressions.map((e) => e.accept(this)).join('; ');
+    return "{ $exps }";
+  }
+  String visitLetVal(LetVal node) {
+    String name = names.varName(node.variable);
+    String def = node.definition.accept(this);
+    String body = node.body.accept(this);
+    return "(let $name = $def in $body)";
+  }
+  String visitInvokeStatic(InvokeStatic node) {
+    String head = node.target.name;
+    String args = node.arguments.map((e) => e.accept(this)).join(', ');
+    return "$head($args)";
+  }
+  String visitReturn(Return node) {
+    return "return ${node.value.accept(this)}";
+  }
+  String visitConstant(Constant node) {
+    return "${node.value}";
+  }
+  
+  visitNode(Node node) {}
+  visitExpression(Expression node) {}
+}
+
+/**
+ * Invents (and remembers) names for Variables that do not have an associated
+ * identifier.
+ * 
+ * In case a variable is named v0, v1, etc, it may be assigned a different
+ * name to avoid clashing with a previously synthesized variable name.
+ */
+class Names {
+  
+  final Map<Variable, String> _names = {};
+  final Set<String> _usedNames = new Set();
+  int _counter = 0;
+  
+  String varName(Variable v) {
+    String name = _names[v];
+    if (name == null) {
+      if (v.identifier != null) {
+        name = v.identifier.token.value;
+      }
+      while (name == null || _usedNames.contains(name)) {
+        name = "v${_counter++}";
+      }
+      _names[v] = name;
+      _usedNames.add(name);
+    }
+    return name;
+  }
+  
+}
\ No newline at end of file
diff --git a/sdk/lib/_internal/compiler/implementation/deferred_load.dart b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
index 294fb34..81fba7f 100644
--- a/sdk/lib/_internal/compiler/implementation/deferred_load.dart
+++ b/sdk/lib/_internal/compiler/implementation/deferred_load.dart
@@ -120,10 +120,15 @@
   /// Will be `true` if the program contains deferred libraries.
   bool splitProgram = false;
 
-  /// A mapping from the name of a [DeferredLibrary] annotation to all dependent
-  /// output units.
-  final Map<String, Set<OutputUnit>> hunksToLoad =
-      new Map<String, Set<OutputUnit>>();
+  /// A mapping from the name of a defer import to all the output units it
+  /// depends on in a list of lists to be loaded in the order they appear.
+  ///
+  /// For example {"lib1": [[lib1_lib2_lib3], [lib1_lib2, lib1_lib3],
+  /// [lib1]]} would mean that in order to load "lib1" first the hunk
+  /// lib1_lib2_lib2 should be loaded, then the hunks lib1_lib2 and lib1_lib3
+  /// can be loaded in parallel. And finally lib1 can be loaded.
+  final Map<String, List<List<OutputUnit>>> hunksToLoad =
+      new Map<String, List<List<OutputUnit>>>();
   final Map<Import, String> importDeferName = new Map<Import, String>();
 
   /// A mapping from elements and constants to their output unit. Query this via
@@ -458,8 +463,7 @@
           void mapDependenciesIfResolved(Element element) {
             // If there is a target for this class, but no use of mirrors the
             // class will not be resolved. We just skip it.
-            if (element is ClassElement &&
-                !(element as ClassElement).isResolved) {
+            if (element is ClassElement &&!element.isResolved) {
               return;
             }
             _mapDependencies(element, deferredImport);
@@ -639,15 +643,36 @@
     for (OutputUnit outputUnit in allOutputUnits) {
       computeOutputUnitName(outputUnit);
     }
+    List sortedOutputUnits = new List.from(allOutputUnits);
+    // Sort the output units in descending order of the number of imports they
+    // include.
+
+    // The loading of the output units mut be ordered because a superclass needs
+    // to be initialized before its subclass.
+    // But a class can only depend on another class in an output unit shared by
+    // a strict superset of the imports:
+    // By contradiction: Assume a class C in output unit shared by imports in
+    // the set S1 = (lib1,.., lib_n) depends on a class D in an output unit
+    // shared by S2 such that S2 not a superset of S1. Let lib_s be a library in
+    // S1 not in S2. lib_s must depend on C, and then in turn on D therefore D
+    // is not in the right output unit.
+    sortedOutputUnits.sort((a, b) => b.imports.length - a.imports.length);
 
     // For each deferred import we find out which outputUnits to load.
     for (Import import in _allDeferredImports.keys) {
       if (import == _fakeMainImport) continue;
-      hunksToLoad[importDeferName[import]] = new Set<OutputUnit>();
-      for (OutputUnit outputUnit in allOutputUnits) {
+      hunksToLoad[importDeferName[import]] = new List<List<OutputUnit>>();
+      int lastNumberOfImports = 0;
+      List<OutputUnit> currentLastList;
+      for (OutputUnit outputUnit in sortedOutputUnits) {
         if (outputUnit == mainOutputUnit) continue;
         if (outputUnit.imports.contains(import)) {
-          hunksToLoad[importDeferName[import]].add(outputUnit);
+          if (outputUnit.imports.length != lastNumberOfImports) {
+            lastNumberOfImports = outputUnit.imports.length;
+            currentLastList = new List<OutputUnit>();
+            hunksToLoad[importDeferName[import]].add(currentLastList);
+          }
+          currentLastList.add(outputUnit);
         }
       }
     }
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
index fe1da9a..1bcc733 100644
--- a/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart
@@ -81,6 +81,8 @@
               return true;
             });
             nodes[element] = function;
+            compiler.tracer.traceCompilation(element.name, null, compiler);
+            compiler.tracer.traceGraph("IR Builder", function);
           }
         }
       });
diff --git a/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart b/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart
new file mode 100644
index 0000000..643d46a2
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/ir/ir_tracer.dart
@@ -0,0 +1,238 @@
+library dart2js.ir_tracer;
+
+import 'dart:async' show EventSink;
+
+import 'ir_nodes.dart' as ir;
+import 'ir_nodes.dart' hide Function;
+import '../tracer.dart';
+
+/**
+ * If true, show LetCont expressions in output.
+ */
+const bool IR_TRACE_LET_CONT = false;
+
+class IRTracer extends TracerUtil implements Visitor {
+  int indent = 0;
+  EventSink<String> output;
+
+  IRTracer(this.output);
+
+  void traceGraph(String name, ir.Function graph) {
+    tag("cfg", () {
+      printProperty("name", name);
+      visitFunction(graph);
+    });
+  }
+
+  // Temporary field used during tree walk
+  Names names;
+
+  visitFunction(ir.Function f) {
+    names = new Names();
+    BlockCollector builder = new BlockCollector(names);
+    f.accept(builder);
+
+    printNode(builder.entry);
+    for (Block block in builder.cont2block.values) {
+      printNode(block);
+    }
+    names = null;
+  }
+
+  printNode(Block block) {
+    tag("block", () {
+      printProperty("name", block.name);
+      printProperty("from_bci", -1);
+      printProperty("to_bci", -1);
+      printProperty("predecessors", block.pred.map((n) => n.name));
+      printProperty("successors", block.succ.map((n) => n.name));
+      printEmptyProperty("xhandlers");
+      printEmptyProperty("flags");
+      tag("states", () {
+        tag("locals", () {
+          printProperty("size", 0);
+          printProperty("method", "None");
+          // We could print parameters here,
+          // but does the hydra tool actually use this info??
+        });
+      });
+      tag("HIR", () {
+        block.body.accept(this);
+      });
+    });
+  }
+
+  void printStmt(String resultVar, String contents) {
+    int bci = 0;
+    int uses = 0;
+    addIndent();
+    add("$bci $uses $resultVar $contents <|@\n");
+  }
+
+  visitLetPrim(LetPrim node) {
+    String id = names.name(node.primitive);
+    printStmt(id, "LetPrim $id = ${formatPrimitive(node.primitive)}");
+    node.body.accept(this);
+  }
+
+  visitLetCont(LetCont node) {
+    if (IR_TRACE_LET_CONT) {
+      String dummy = names.name(node);
+      String id = names.name(node.continuation);
+      printStmt(dummy, "LetCont $id = <$id>");
+    }
+    node.body.accept(this);
+  }
+
+  visitInvokeStatic(InvokeStatic node) {
+    String dummy = names.name(node);
+    String callName = node.selector.name;
+    String args = node.arguments.map(formatReference).join(', ');
+    String kont = formatReference(node.continuation);
+    printStmt(dummy, "InvokeStatic $callName ($args) $kont");
+  }
+
+  visitInvokeContinuation(InvokeContinuation node) {
+    String dummy = names.name(node);
+    String kont = formatReference(node.continuation);
+    String arg = formatReference(node.argument);
+    printStmt(dummy, "InvokeContinuation $kont ($arg)");
+  }
+
+  String formatReference(Reference ref) {
+    Definition target = ref.definition;
+    if (target is Continuation && target.body == null) {
+      return "return"; // Do not generate a name for the return continuation
+    } else {
+      return names.name(ref.definition);
+    }
+  }
+
+  String formatPrimitive(Primitive p) {
+    return p.accept(this);
+  }
+
+  visitConstant(ir.Constant node) {
+    return "Constant ${node.value}";
+  }
+
+  visitParameter(Parameter node) {
+    return "Parameter ${names.name(node)}";
+  }
+
+  visitContinuation(Continuation node) {
+    return "Continuation ${names.name(node)}";
+  }
+
+  visitExpression(Expression e) {}
+  visitPrimitive(Primitive p) {}
+  visitDefinition(Definition d) {}
+  visitNode(Node n) {}
+}
+
+/** 
+ * Invents (and remembers) names for Continuations, Parameters, etc.
+ * The names must match the conventions used by IR Hydra, e.g. 
+ * Continuations and Functions must have names of form B### since they
+ * are visualized as basic blocks.
+ */
+class Names {
+  final Map<Object, String> names = {};
+  final Map<String, int> counters = {
+    'r': 0,
+    'B': 0,
+    'v': 0,
+    'x': 0
+  };
+
+  String prefix(x) {
+    if (x is Parameter) return 'r';
+    if (x is Continuation || x is ir.Function) return 'B';
+    if (x is Primitive) return 'v';
+    return 'x';
+  }
+
+  String name(x) {
+    String nam = names[x];
+    if (nam == null) {
+      String pref = prefix(x);
+      int id = counters[pref]++;
+      nam = names[x] = '${pref}${id}';
+    }
+    return nam;
+  }
+}
+
+/**
+ * A vertex in the graph visualization, used in place of basic blocks.  
+ */
+class Block {
+  String name;
+  final List<Parameter> parameters;
+  final Expression body;
+  final List<Block> succ = <Block>[];
+  final List<Block> pred = <Block>[];
+
+  Block(this.name, this.parameters, this.body);
+
+  void addEdgeTo(Block successor) {
+    succ.add(successor);
+    successor.pred.add(this);
+  }
+}
+
+class BlockCollector implements Visitor {
+  Block entry;
+  final Map<Continuation, Block> cont2block = <Continuation, Block> {};
+  Block current_block;
+
+  Names names;
+  BlockCollector(this.names);
+
+  Block getBlock(Continuation c) {
+    Block block = cont2block[c];
+    if (block == null) {
+      block = new Block(names.name(c), [c.parameter], c.body);
+      cont2block[c] = block;
+    }
+    return block;
+  }
+
+  visitFunction(ir.Function f) {
+    entry = current_block = new Block(names.name(f), [], f.body);
+    f.body.accept(this);
+  }
+  visitLetPrim(LetPrim exp) {
+    exp.body.accept(this);
+  }
+  visitLetCont(LetCont exp) {
+    exp.continuation.accept(this);
+    exp.body.accept(this);
+  }
+  visitInvokeStatic(InvokeStatic exp) {
+    Definition target = exp.continuation.definition;
+    if (target is Continuation && target.body != null) {
+      current_block.addEdgeTo(getBlock(target));
+    }
+  }
+
+  visitInvokeContinuation(InvokeContinuation exp) {
+    Definition target = exp.continuation.definition;
+    if (target is Continuation && target.body != null) {
+      current_block.addEdgeTo(getBlock(target));
+    }
+  }
+  visitConstant(ir.Constant constant) {}
+  visitParameter(Parameter p) {}
+  visitContinuation(Continuation c) {
+    var old_node = current_block;
+    current_block = getBlock(c);
+    c.body.accept(this);
+    current_block = old_node;
+  }
+
+  visitPrimitive(Primitive p) {}
+  visitDefinition(Definition d) {}
+  visitExpression(Expression e) {}
+  visitNode(Node n) {}
+}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
index a419a7b..cfd3a2f 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart
@@ -1439,17 +1439,22 @@
       // [emitOneShotInterceptors] have been called.
       emitCompileTimeConstants(mainBuffer, mainOutputUnit);
 
-      // We write a javascript mapping from DeferredLibrary elements
-      // (really their String argument) to the js hunk to load.
+      // Write a javascript mapping from Deferred import load ids (derrived from
+      // the import prefix.) to a list of lists of js hunks to load.
       // TODO(sigurdm): Create a syntax tree for this.
       // TODO(sigurdm): Also find out where to place it.
       mainBuffer.write("\$.libraries_to_load = {");
-      for (String constant in compiler.deferredLoadTask.hunksToLoad.keys) {
+      for (String loadId in compiler.deferredLoadTask.hunksToLoad.keys) {
         // TODO(sigurdm): Escape these strings.
-        mainBuffer.write('"$constant":[');
-        for (OutputUnit outputUnit in
-            compiler.deferredLoadTask.hunksToLoad[constant]) {
-          mainBuffer.write('"${outputUnit.partFileName(compiler)}.part.js", ');
+        mainBuffer.write('"$loadId":[');
+        for (List<OutputUnit> outputUnits in
+            compiler.deferredLoadTask.hunksToLoad[loadId]) {
+          mainBuffer.write("[");
+          for (OutputUnit outputUnit in outputUnits) {
+            mainBuffer
+              .write('"${outputUnit.partFileName(compiler)}.part.js", ');
+          }
+          mainBuffer.write("],");
         }
         mainBuffer.write("],\n");
       }
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 96dcd2a..0f6d7a0 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -1977,19 +1977,22 @@
 
   VariableDefinitions parseNode(Element element, DiagnosticListener listener) {
     if (definitions != null) return definitions;
-    definitions = parse(listener,
-                       element.getCompilationUnit(),
-                       (p) => p.parseVariablesDeclaration(beginToken));
-    if (!definitions.modifiers.isVar() &&
-        !definitions.modifiers.isFinal() &&
-        !definitions.modifiers.isConst() &&
-        definitions.type == null) {
-      listener.reportError(
-          definitions,
-          MessageKind.GENERIC,
-          { 'text': 'A field declaration must start with var, final, '
-                    'const, or a type annotation.' });
-    }
+    listener.withCurrentElement(element, () {
+      definitions = parse(listener,
+                          element.getCompilationUnit(),
+                          (p) => p.parseVariablesDeclaration(beginToken));
+
+      if (!definitions.modifiers.isVar() &&
+          !definitions.modifiers.isFinal() &&
+          !definitions.modifiers.isConst() &&
+          definitions.type == null) {
+        listener.reportError(
+            definitions,
+            MessageKind.GENERIC,
+            { 'text': 'A field declaration must start with var, final, '
+                      'const, or a type annotation.' });
+      }
+    });
     return definitions;
   }
 
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart b/sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
similarity index 91%
rename from sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
rename to sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
index 13056a6..5bd7e46 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/tracer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/ssa_tracer.dart
@@ -2,49 +2,28 @@
 // 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 tracer;
+library ssa.tracer;
 
 import 'dart:async' show EventSink;
 
 import 'ssa.dart';
 import '../js_backend/js_backend.dart';
 import '../dart2jslib.dart';
+import '../tracer.dart';
 
-const bool GENERATE_SSA_TRACE = false;
-const String SSA_TRACE_FILTER = null;
-
-class HTracer extends HGraphVisitor implements Tracer {
+/**
+ * Outputs SSA code in a format readable by Hydra IR.
+ * Tracing is disabled by default, see ../tracer.dart for how
+ * to enable it.
+ */
+class HTracer extends HGraphVisitor with TracerUtil {
   Compiler compiler;
   JavaScriptItemCompilationContext context;
-  int indent = 0;
   final EventSink<String> output;
-  final bool enabled = GENERATE_SSA_TRACE;
-  bool traceActive = false;
 
-  HTracer(this.output);
-
-  void close() {
-    if (enabled) output.close();
-  }
-
-  void traceCompilation(String methodName,
-                        JavaScriptItemCompilationContext compilationContext,
-                        Compiler compiler) {
-    if (!enabled) return;
-    this.context = compilationContext;
-    this.compiler = compiler;
-    traceActive =
-        SSA_TRACE_FILTER == null || methodName.contains(SSA_TRACE_FILTER);
-    if (!traceActive) return;
-    tag("compilation", () {
-      printProperty("name", methodName);
-      printProperty("method", methodName);
-      printProperty("date", new DateTime.now().millisecondsSinceEpoch);
-    });
-  }
+  HTracer(this.output, this.compiler, this.context);
 
   void traceGraph(String name, HGraph graph) {
-    if (!traceActive) return;
     tag("cfg", () {
       printProperty("name", name);
       visitDominatorTree(graph);
@@ -129,42 +108,6 @@
       });
     });
   }
-
-  void tag(String tagName, Function f) {
-    println("begin_$tagName");
-    indent++;
-    f();
-    indent--;
-    println("end_$tagName");
-  }
-
-  void println(String string) {
-    addIndent();
-    add(string);
-    add("\n");
-  }
-
-  void printEmptyProperty(String propertyName) {
-    println(propertyName);
-  }
-
-  void printProperty(String propertyName, var value) {
-    if (value is num) {
-      println("$propertyName $value");
-    } else {
-      println('$propertyName "$value"');
-    }
-  }
-
-  void add(String string) {
-    output.add(string);
-  }
-
-  void addIndent() {
-    for (int i = 0; i < indent; i++) {
-      add("  ");
-    }
-  }
 }
 
 class HInstructionStringifier implements HVisitor<String> {
diff --git a/sdk/lib/_internal/compiler/implementation/tracer.dart b/sdk/lib/_internal/compiler/implementation/tracer.dart
new file mode 100644
index 0000000..0ffc3d6
--- /dev/null
+++ b/sdk/lib/_internal/compiler/implementation/tracer.dart
@@ -0,0 +1,122 @@
+library tracer;
+
+import '../compiler.dart' as api;
+import 'dart:async' show EventSink;
+import 'ssa/ssa.dart' as ssa;
+import 'ssa/ssa_tracer.dart' show HTracer;
+import 'ir/ir_nodes.dart' as ir;
+import 'ir/ir_tracer.dart' show IRTracer;
+import 'dart_backend/dart_tree.dart' as tree;
+import 'dart_backend/tree_tracer.dart' show TreeTracer;
+import 'dart2jslib.dart';
+
+/**
+ * Set to true to enable tracing.
+ */
+const bool GENERATE_TRACE = false;
+
+/**
+ * If non-null, we only trace methods whose name contains the given substring.
+ */
+const String TRACE_FILTER = null;
+
+/**
+ * Dumps the intermediate representation after each phase in a format
+ * readable by Hydra IR. 
+ */
+class Tracer extends TracerUtil {
+  Compiler compiler;
+  ItemCompilationContext context;
+  bool traceActive = false;
+  final EventSink<String> output;
+  final bool enabled = GENERATE_TRACE;
+  
+  Tracer(api.CompilerOutputProvider outputProvider) :
+    output = GENERATE_TRACE ? outputProvider('dart', 'cfg') : null;
+  
+  void traceCompilation(String methodName,
+                        ItemCompilationContext compilationContext,
+                        Compiler compiler) {
+    if (!enabled) return;
+    this.context = compilationContext;
+    this.compiler = compiler;
+    traceActive =
+        TRACE_FILTER == null || methodName.contains(TRACE_FILTER);
+    if (!traceActive) return;
+    tag("compilation", () {
+      printProperty("name", methodName);
+      printProperty("method", methodName);
+      printProperty("date", new DateTime.now().millisecondsSinceEpoch);
+    });
+  }
+
+  void traceGraph(String name, var irObject) {
+    if (!traceActive) return;
+    if (irObject is ssa.HGraph) {
+      new HTracer(output, compiler, context).traceGraph(name, irObject);
+    }
+    else if (irObject is ir.Function) {
+      new IRTracer(output).traceGraph(name, irObject);
+    }
+    else if (irObject is tree.Expression) {
+      new TreeTracer(output).traceGraph(name, irObject);
+    }
+  }
+  
+  void close() {
+    if (output != null) {
+      output.close();
+    }
+  }
+}
+
+
+abstract class TracerUtil {
+  int indent = 0;
+  EventSink<String> get output;
+  
+
+  void tag(String tagName, Function f) {
+    println("begin_$tagName");
+    indent++;
+    f();
+    indent--;
+    println("end_$tagName");
+  }
+
+  void println(String string) {
+    addIndent();
+    add(string);
+    add("\n");
+  }
+  
+  void printEmptyProperty(String propertyName) {
+    println(propertyName);
+  }
+  
+  String formatPrty(x) {
+    if (x is num) {
+      return '${x}';
+    } else if (x is String) {
+      return '"${x}"';
+    } else if (x is Iterable) {
+      return x.map((s) => formatPrty(s)).join(' ');
+    } else {
+      throw "invalid property type: ${x}";
+    }
+  }
+  
+  void printProperty(String propertyName, value) {
+    println("$propertyName ${formatPrty(value)}");
+  }
+
+  void add(String string) {
+    output.add(string);
+  }
+
+  void addIndent() {
+    for (int i = 0; i < indent; i++) {
+      add("  ");
+    }
+  }
+}
diff --git a/sdk/lib/_internal/lib/async_patch.dart b/sdk/lib/_internal/lib/async_patch.dart
index 06bd2a5..aa1c342 100644
--- a/sdk/lib/_internal/lib/async_patch.dart
+++ b/sdk/lib/_internal/lib/async_patch.dart
@@ -33,7 +33,7 @@
 }
 
 patch class DeferredLibrary {
-  patch Future<bool> load() {
+  patch Future<Null> load() {
     return loadDeferredLibrary(libraryName, uri);
   }
 }
diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
index a7e7ee2..463fab9 100644
--- a/sdk/lib/_internal/lib/collection_patch.dart
+++ b/sdk/lib/_internal/lib/collection_patch.dart
@@ -83,13 +83,17 @@
       var nums = _nums;
       return (nums == null) ? false : _hasTableEntry(nums, key);
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, key);
-      return _findBucketIndex(bucket, key) >= 0;
+      return _containsKey(key);
     }
   }
 
+  bool _containsKey(Object key) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, key);
+    return _findBucketIndex(bucket, key) >= 0;
+  }
+
   bool containsValue(Object value) {
     return _computeKeys().any((each) => this[each] == value);
   }
@@ -108,14 +112,18 @@
       var nums = _nums;
       return (nums == null) ? null : _getTableEntry(nums, key);
     } else {
-      var rest = _rest;
-      if (rest == null) return null;
-      var bucket = _getBucket(rest, key);
-      int index = _findBucketIndex(bucket, key);
-      return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+      return _get(key);
     }
   }
 
+  V _get(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1);
+  }
+
   void operator[]=(K key, V value) {
     if (_isStringKey(key)) {
       var strings = _strings;
@@ -126,23 +134,27 @@
       if (nums == null) _nums = nums = _newHashTable();
       _addHashTableEntry(nums, key, value);
     } else {
-      var rest = _rest;
-      if (rest == null) _rest = rest = _newHashTable();
-      var hash = _computeHashCode(key);
-      var bucket = JS('var', '#[#]', rest, hash);
-      if (bucket == null) {
-        _setTableEntry(rest, hash, JS('var', '[#, #]', key, value));
+      _set(key, value);
+    }
+  }
+
+  void _set(K key, V value) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(key);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      _setTableEntry(rest, hash, JS('var', '[#, #]', key, value));
+      _length++;
+      _keys = null;
+    } else {
+      int index = _findBucketIndex(bucket, key);
+      if (index >= 0) {
+        JS('void', '#[#] = #', bucket, index + 1, value);
+      } else {
+        JS('void', '#.push(#, #)', bucket, key, value);
         _length++;
         _keys = null;
-      } else {
-        int index = _findBucketIndex(bucket, key);
-        if (index >= 0) {
-          JS('void', '#[#] = #', bucket, index + 1, value);
-        } else {
-          JS('void', '#.push(#, #)', bucket, key, value);
-          _length++;
-          _keys = null;
-        }
       }
     }
   }
@@ -160,21 +172,25 @@
     } else if (_isNumericKey(key)) {
       return _removeHashTableEntry(_nums, key);
     } else {
-      var rest = _rest;
-      if (rest == null) return null;
-      var bucket = _getBucket(rest, key);
-      int index = _findBucketIndex(bucket, key);
-      if (index < 0) return null;
-      // TODO(kasperl): Consider getting rid of the bucket list when
-      // the length reaches zero.
-      _length--;
-      _keys = null;
-      // Use splice to remove the two [key, value] elements at the
-      // index and return the value.
-      return JS('var', '#.splice(#, 2)[1]', bucket, index);
+      return _remove(key);
     }
   }
 
+  V _remove(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    if (index < 0) return null;
+    // TODO(kasperl): Consider getting rid of the bucket list when
+    // the length reaches zero.
+    _length--;
+    _keys = null;
+    // Use splice to remove the two [key, value] elements at the
+    // index and return the value.
+    return JS('var', '#.splice(#, 2)[1]', bucket, index);
+  }
+
   void clear() {
     if (_length > 0) {
       _strings = _nums = _rest = _keys = null;
@@ -370,17 +386,21 @@
 
   V operator[](Object key) {
     if (!_validKey(key)) return null;
-    return super[key];
+    return super._get(key);
+  }
+
+  void operator[]=(K key, V value) {
+    super._set(key, value);
   }
 
   bool containsKey(Object key) {
     if (!_validKey(key)) return false;
-    return super.containsKey(key);
+    return super._containsKey(key);
   }
 
   V remove(Object key) {
     if (!_validKey(key)) return null;
-    return super.remove(key);
+    return super._remove(key);
   }
 
   int _computeHashCode(var key) {
@@ -555,13 +575,17 @@
       LinkedHashMapCell cell = _getTableEntry(nums, key);
       return cell != null;
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, key);
-      return _findBucketIndex(bucket, key) >= 0;
+      return _containsKey(key);
     }
   }
 
+  bool _containsKey(Object key) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, key);
+    return _findBucketIndex(bucket, key) >= 0;
+  }
+
   bool containsValue(Object value) {
     return keys.any((each) => this[each] == value);
   }
@@ -584,16 +608,20 @@
       LinkedHashMapCell cell = _getTableEntry(nums, key);
       return (cell == null) ? null : cell._value;
     } else {
-      var rest = _rest;
-      if (rest == null) return null;
-      var bucket = _getBucket(rest, key);
-      int index = _findBucketIndex(bucket, key);
-      if (index < 0) return null;
-      LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
-      return cell._value;
+      return _get(key);
     }
   }
 
+  V _get(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    if (index < 0) return null;
+    LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+    return cell._value;
+  }
+
   void operator[]=(K key, V value) {
     if (_isStringKey(key)) {
       var strings = _strings;
@@ -604,22 +632,26 @@
       if (nums == null) _nums = nums = _newHashTable();
       _addHashTableEntry(nums, key, value);
     } else {
-      var rest = _rest;
-      if (rest == null) _rest = rest = _newHashTable();
-      var hash = _computeHashCode(key);
-      var bucket = JS('var', '#[#]', rest, hash);
-      if (bucket == null) {
-        LinkedHashMapCell cell = _newLinkedCell(key, value);
-        _setTableEntry(rest, hash, JS('var', '[#]', cell));
+      _set(key, value);
+    }
+  }
+
+  void _set(K key, V value) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(key);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      LinkedHashMapCell cell = _newLinkedCell(key, value);
+      _setTableEntry(rest, hash, JS('var', '[#]', cell));
+    } else {
+      int index = _findBucketIndex(bucket, key);
+      if (index >= 0) {
+        LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
+        cell._value = value;
       } else {
-        int index = _findBucketIndex(bucket, key);
-        if (index >= 0) {
-          LinkedHashMapCell cell = JS('var', '#[#]', bucket, index);
-          cell._value = value;
-        } else {
-          LinkedHashMapCell cell = _newLinkedCell(key, value);
-          JS('void', '#.push(#)', bucket, cell);
-        }
+        LinkedHashMapCell cell = _newLinkedCell(key, value);
+        JS('void', '#.push(#)', bucket, cell);
       }
     }
   }
@@ -637,21 +669,25 @@
     } else if (_isNumericKey(key)) {
       return _removeHashTableEntry(_nums, key);
     } else {
-      var rest = _rest;
-      if (rest == null) return null;
-      var bucket = _getBucket(rest, key);
-      int index = _findBucketIndex(bucket, key);
-      if (index < 0) return null;
-      // Use splice to remove the [cell] element at the index and
-      // unlink the cell before returning its value.
-      LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
-      _unlinkCell(cell);
-      // TODO(kasperl): Consider getting rid of the bucket list when
-      // the length reaches zero.
-      return cell._value;
+      return _remove(key);
     }
   }
 
+  V _remove(Object key) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, key);
+    int index = _findBucketIndex(bucket, key);
+    if (index < 0) return null;
+    // Use splice to remove the [cell] element at the index and
+    // unlink the cell before returning its value.
+    LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _unlinkCell(cell);
+    // TODO(kasperl): Consider getting rid of the bucket list when
+    // the length reaches zero.
+    return cell._value;
+  }
+
   void clear() {
     if (_length > 0) {
       _strings = _nums = _rest = _first = _last = null;
@@ -823,17 +859,21 @@
 
   V operator[](Object key) {
     if (!_validKey(key)) return null;
-    return super[key];
+    return super._get(key);
+  }
+
+  void operator[]=(K key, V value) {
+    super._set(key, value);
   }
 
   bool containsKey(Object key) {
     if (!_validKey(key)) return false;
-    return super.containsKey(key);
+    return super._containsKey(key);
   }
 
   V remove(Object key) {
     if (!_validKey(key)) return null;
-    return super.remove(key);
+    return super._remove(key);
   }
 
   int _computeHashCode(var key) {
@@ -995,17 +1035,25 @@
       var nums = _nums;
       return (nums == null) ? false : _hasTableEntry(nums, object);
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, object);
-      return _findBucketIndex(bucket, object) >= 0;
+      return _contains(object);
     }
   }
 
+  bool _contains(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    return _findBucketIndex(bucket, object) >= 0;
+  }
+
   E lookup(Object object) {
     if (_isStringElement(object) || _isNumericElement(object)) {
       return this.contains(object) ? object : null;
     }
+    return _lookup(object);
+  }
+
+  E _lookup(Object object) {
     var rest = _rest;
     if (rest == null) return null;
     var bucket = _getBucket(rest, object);
@@ -1025,23 +1073,27 @@
       if (nums == null) _nums = nums = _newHashTable();
       return _addHashTableEntry(nums, element);
     } else {
-      var rest = _rest;
-      if (rest == null) _rest = rest = _newHashTable();
-      var hash = _computeHashCode(element);
-      var bucket = JS('var', '#[#]', rest, hash);
-      if (bucket == null) {
-        _setTableEntry(rest, hash, JS('var', '[#]', element));
-      } else {
-        int index = _findBucketIndex(bucket, element);
-        if (index >= 0) return false;
-        JS('void', '#.push(#)', bucket, element);
-      }
-      _length++;
-      _elements = null;
-      return true;
+      return _add(element);
     }
   }
 
+  bool _add(E element) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(element);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      _setTableEntry(rest, hash, JS('var', '[#]', element));
+    } else {
+      int index = _findBucketIndex(bucket, element);
+      if (index >= 0) return false;
+      JS('void', '#.push(#)', bucket, element);
+    }
+    _length++;
+    _elements = null;
+    return true;
+  }
+
   void addAll(Iterable<E> objects) {
     for (E each in objects) {
       add(each);
@@ -1054,22 +1106,26 @@
     } else if (_isNumericElement(object)) {
       return _removeHashTableEntry(_nums, object);
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, object);
-      int index = _findBucketIndex(bucket, object);
-      if (index < 0) return false;
-      // TODO(kasperl): Consider getting rid of the bucket list when
-      // the length reaches zero.
-      _length--;
-      _elements = null;
-      // TODO(kasperl): It would probably be faster to move the
-      // element to the end and reduce the length of the bucket list.
-      JS('void', '#.splice(#, 1)', bucket, index);
-      return true;
+      return _remove(object);
     }
   }
 
+  bool _remove(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    int index = _findBucketIndex(bucket, object);
+    if (index < 0) return false;
+    // TODO(kasperl): Consider getting rid of the bucket list when
+    // the length reaches zero.
+    _length--;
+    _elements = null;
+    // TODO(kasperl): It would probably be faster to move the
+    // element to the end and reduce the length of the bucket list.
+    JS('void', '#.splice(#, 1)', bucket, index);
+    return true;
+  }
+
   void removeAll(Iterable<Object> objectsToRemove) {
     for (var each in objectsToRemove) {
       remove(each);
@@ -1275,19 +1331,21 @@
     return JS('int', '# & 0x3ffffff', _hasher(element));
   }
 
+  bool add(E object) => super._add(object);
+
   bool contains(Object object) {
     if (!_validKey(object)) return false;
-    return super.contains(object);
+    return super._contains(object);
   }
 
   E lookup(Object object) {
     if (!_validKey(object)) return null;
-    return super.lookup(object);
+    return super._lookup(object);
   }
 
   bool remove(Object object) {
     if (!_validKey(object)) return false;
-    return super.remove(object);
+    return super._remove(object);
   }
 
   bool containsAll(Iterable<Object> elements) {
@@ -1300,7 +1358,7 @@
   void removeAll(Iterable<Object> elements) {
     for (Object element in elements) {
       if (_validKey(element)) {
-        super.remove(element);
+        super._remove(element);
       }
     }
   }
@@ -1428,26 +1486,34 @@
       LinkedHashSetCell cell = _getTableEntry(nums, object);
       return cell != null;
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, object);
-      return _findBucketIndex(bucket, object) >= 0;
+      return _contains(object);
     }
   }
 
+  bool _contains(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    return _findBucketIndex(bucket, object) >= 0;
+  }
+
   E lookup(Object object) {
     if (_isStringElement(object) || _isNumericElement(object)) {
       return this.contains(object) ? object : null;
     } else {
-      var rest = _rest;
-      if (rest == null) return null;
-      var bucket = _getBucket(rest, object);
-      var index = _findBucketIndex(bucket, object);
-      if (index < 0) return null;
-      return bucket[index]._element;
+      return _lookup(object);
     }
   }
 
+  E _lookup(Object object) {
+    var rest = _rest;
+    if (rest == null) return null;
+    var bucket = _getBucket(rest, object);
+    var index = _findBucketIndex(bucket, object);
+    if (index < 0) return null;
+    return bucket[index]._element;
+  }
+
   void forEach(void action(E element)) {
     LinkedHashSetCell cell = _first;
     int modifications = _modifications;
@@ -1481,23 +1547,27 @@
       if (nums == null) _nums = nums = _newHashTable();
       return _addHashTableEntry(nums, element);
     } else {
-      var rest = _rest;
-      if (rest == null) _rest = rest = _newHashTable();
-      var hash = _computeHashCode(element);
-      var bucket = JS('var', '#[#]', rest, hash);
-      if (bucket == null) {
-        LinkedHashSetCell cell = _newLinkedCell(element);
-        _setTableEntry(rest, hash, JS('var', '[#]', cell));
-      } else {
-        int index = _findBucketIndex(bucket, element);
-        if (index >= 0) return false;
-        LinkedHashSetCell cell = _newLinkedCell(element);
-        JS('void', '#.push(#)', bucket, cell);
-      }
-      return true;
+      return _add(element);
     }
   }
 
+  bool _add(E element) {
+    var rest = _rest;
+    if (rest == null) _rest = rest = _newHashTable();
+    var hash = _computeHashCode(element);
+    var bucket = JS('var', '#[#]', rest, hash);
+    if (bucket == null) {
+      LinkedHashSetCell cell = _newLinkedCell(element);
+      _setTableEntry(rest, hash, JS('var', '[#]', cell));
+    } else {
+      int index = _findBucketIndex(bucket, element);
+      if (index >= 0) return false;
+      LinkedHashSetCell cell = _newLinkedCell(element);
+      JS('void', '#.push(#)', bucket, cell);
+    }
+    return true;
+  }
+
   void addAll(Iterable<E> objects) {
     for (E object in objects) {
       add(object);
@@ -1510,19 +1580,23 @@
     } else if (_isNumericElement(object)) {
       return _removeHashTableEntry(_nums, object);
     } else {
-      var rest = _rest;
-      if (rest == null) return false;
-      var bucket = _getBucket(rest, object);
-      int index = _findBucketIndex(bucket, object);
-      if (index < 0) return false;
-      // Use splice to remove the [cell] element at the index and
-      // unlink it.
-      LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
-      _unlinkCell(cell);
-      return true;
+      return _remove(object);
     }
   }
 
+  bool _remove(Object object) {
+    var rest = _rest;
+    if (rest == null) return false;
+    var bucket = _getBucket(rest, object);
+    int index = _findBucketIndex(bucket, object);
+    if (index < 0) return false;
+    // Use splice to remove the [cell] element at the index and
+    // unlink it.
+    LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index);
+    _unlinkCell(cell);
+    return true;
+  }
+
   void removeAll(Iterable objectsToRemove) {
     for (var each in objectsToRemove) {
       remove(each);
@@ -1734,19 +1808,21 @@
     return JS('int', '# & 0x3ffffff', _hasher(element));
   }
 
+  bool add(E element) => super._add(element);
+
   bool contains(Object object) {
     if (!_validKey(object)) return false;
-    return super.contains(object);
+    return super._contains(object);
   }
 
   E lookup(Object object) {
     if (!_validKey(object)) return null;
-    return super.lookup(object);
+    return super._lookup(object);
   }
 
   bool remove(Object object) {
     if (!_validKey(object)) return false;
-    return super.remove(object);
+    return super._remove(object);
   }
 
   bool containsAll(Iterable<Object> elements) {
@@ -1759,7 +1835,7 @@
   void removeAll(Iterable<Object> elements) {
     for (Object element in elements) {
       if (_validKey(element)) {
-        super.remove(element);
+        super._remove(element);
       }
     }
   }
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index 58ab7a9..e054097 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -3222,39 +3222,34 @@
   return JS('String', 'init.getIsolateTag(#)', name);
 }
 
-typedef Future<bool> LoadLibraryFunctionType();
+typedef Future<Null> LoadLibraryFunctionType();
 
 LoadLibraryFunctionType _loadLibraryWrapper(String loadId) {
   return () => loadDeferredLibrary(loadId);
 }
 
-final Map<String, Future<bool>> _loadedLibraries = <String, Future<bool>>{};
+final Map<String, Future<Null>> _loadedLibraries = <String, Future<Null>>{};
 
 Future<bool> loadDeferredLibrary(String loadId, [String uri]) {
-  List hunkNames = new List();
-  if (JS('bool', '\$.libraries_to_load[#] === undefined', loadId)) {
-    return new Future(() => false);
-  }
-  for (int index = 0;
-       index < JS('int', '\$.libraries_to_load[#].length', loadId);
-       ++index) {
-    hunkNames.add(JS('String', '\$.libraries_to_load[#][#]',
-                     loadId, index));
-  }
-  Iterable<Future<bool>> allLoads =
-      hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
-  return Future.wait(allLoads).then((results) {
-    return results.any((x) => x);
+
+  List<List<String>> hunkLists = JS('JSExtendableArray|Null',
+      '\$.libraries_to_load[#]', loadId);
+  if (hunkLists == null) return new Future.value(null);
+
+  return Future.forEach(hunkLists, (hunkNames) {
+    Iterable<Future<Null>> allLoads =
+        hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
+    return Future.wait(allLoads).then((_) => null);
   });
 }
 
-Future<bool> _loadHunk(String hunkName, String uri) {
+Future<Null> _loadHunk(String hunkName, String uri) {
   // TODO(ahe): Validate libraryName.  Kasper points out that you want
   // to be able to experiment with the effect of toggling @DeferLoad,
   // so perhaps we should silently ignore "bad" library names.
-  Future<bool> future = _loadedLibraries[hunkName];
+  Future<Null> future = _loadedLibraries[hunkName];
   if (future != null) {
-    return future.then((_) => false);
+    return future.then((_) => null);
   }
 
   if (uri == null) {
@@ -3266,7 +3261,7 @@
   if (Primitives.isJsshell || Primitives.isD8) {
     // TODO(ahe): Move this code to a JavaScript command helper script that is
     // not included in generated output.
-    return _loadedLibraries[hunkName] = new Future<bool>(() {
+    return _loadedLibraries[hunkName] = new Future<Null>(() {
       try {
         // Create a new function to avoid getting access to current function
         // context.
@@ -3274,14 +3269,14 @@
       } catch (error, stackTrace) {
         throw new DeferredLoadException("Loading $uri failed.");
       }
-      return true;
+      return null;
     });
   } else if (isWorker()) {
     // We are in a web worker. Load the code with an XMLHttpRequest.
-    return _loadedLibraries[hunkName] = new Future<bool>(() {
-      Completer completer = new Completer<bool>();
+    return _loadedLibraries[hunkName] = new Future<Null>(() {
+      Completer completer = new Completer<Null>();
       enterJsAsync();
-      Future<bool> leavingFuture = completer.future.whenComplete(() {
+      Future<Null> leavingFuture = completer.future.whenComplete(() {
         leaveJsAsync();
       });
 
@@ -3306,7 +3301,7 @@
             new DeferredLoadException("Evaluating $uri failed."));
           return;
         }
-        completer.complete(true);
+        completer.complete(null);
       }, 1));
 
       var fail = convertDartClosureToJS((event) {
@@ -3320,15 +3315,15 @@
     });
   }
   // We are in a dom-context.
-  return _loadedLibraries[hunkName] = new Future<bool>(() {
-    Completer completer = new Completer<bool>();
+  return _loadedLibraries[hunkName] = new Future<Null>(() {
+    Completer completer = new Completer<Null>();
     // Inject a script tag.
     var script = JS('', 'document.createElement("script")');
     JS('', '#.type = "text/javascript"', script);
     JS('', '#.src = #', script, uri);
     JS('', '#.addEventListener("load", #, false)',
        script, convertDartClosureToJS((event) {
-      completer.complete(true);
+      completer.complete(null);
     }, 1));
     JS('', '#.addEventListener("error", #, false)',
        script, convertDartClosureToJS((event) {
diff --git a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
index 71944d9..ca71b15 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/dart2js_transformer.dart
@@ -43,6 +43,9 @@
   final BuildEnvironment _environment;
   final BarbackSettings _settings;
 
+  /// Whether source maps should be generated for the compiled JS.
+  bool get _generateSourceMaps => _settings.mode != BarbackMode.RELEASE;
+
   Dart2JSTransformer.withSettings(this._environment, this._settings) {
     var invalidOptions = _settings.configuration.keys.toSet()
         .difference(_validOptions);
@@ -88,8 +91,10 @@
   Future declareOutputs(DeclaringTransform transform) {
     var primaryId = transform.primaryId;
     transform.declareOutput(primaryId.addExtension(".js"));
-    transform.declareOutput(primaryId.addExtension(".js.map"));
     transform.declareOutput(primaryId.addExtension(".precompiled.js"));
+    if (_generateSourceMaps) {
+      transform.declareOutput(primaryId.addExtension(".js.map"));
+    }
     return new Future.value();
   }
 
@@ -115,7 +120,7 @@
   /// Run the dart2js compiler.
   Future _doCompilation(Transform transform) {
     var provider = new _BarbackCompilerProvider(_environment, transform,
-        generateSourceMaps: _settings.mode != BarbackMode.RELEASE);
+        generateSourceMaps: _generateSourceMaps);
 
     // Create a "path" to the entrypoint script. The entrypoint may not actually
     // be on disk, but this gives dart2js a root to resolve relative paths
diff --git a/sdk/lib/async/deferred_load.dart b/sdk/lib/async/deferred_load.dart
index 43982ce..a770071 100644
--- a/sdk/lib/async/deferred_load.dart
+++ b/sdk/lib/async/deferred_load.dart
@@ -34,13 +34,10 @@
   /**
    * Ensure that [libraryName] has been loaded.
    *
-   * The value of the returned future is true if this invocation of
-   * [load] caused the library to be loaded.
-   *
    * If the library fails to load, the Future will complete with a
    * DeferredLoadException.
    */
-  external Future<bool> load();
+  external Future<Null> load();
 }
 
 /**
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 05c33f6..a262c21 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -461,21 +461,24 @@
 
   List<int> readAsBytesSync() {
     var opened = openSync();
-    var data;
-    var length = opened.lengthSync();
-    if (length == 0) {
-      // May be character device, try to read it in chunks.
-      var builder = new BytesBuilder(copy: false);
-      do {
-        data = opened.readSync(_BLOCK_SIZE);
-        if (data.length > 0) builder.add(data);
-      } while (data.length == _BLOCK_SIZE);
-      data = builder.takeBytes();
-    } else {
-      data = opened.readSync(length);
+    try {
+      var data;
+      var length = opened.lengthSync();
+      if (length == 0) {
+        // May be character device, try to read it in chunks.
+        var builder = new BytesBuilder(copy: false);
+        do {
+          data = opened.readSync(_BLOCK_SIZE);
+          if (data.length > 0) builder.add(data);
+        } while (data.length == _BLOCK_SIZE);
+        data = builder.takeBytes();
+      } else {
+        data = opened.readSync(length);
+      }
+      return data;
+    } finally {
+      opened.closeSync();
     }
-    opened.closeSync();
-    return data;
   }
 
   String _tryDecode(List<int> bytes, Encoding encoding) {
@@ -539,9 +542,12 @@
                         {FileMode mode: FileMode.WRITE,
                          bool flush: false}) {
     RandomAccessFile opened = openSync(mode: mode);
-    opened.writeFromSync(bytes, 0, bytes.length);
-    if (flush) opened.flushSync();
-    opened.closeSync();
+    try {
+      opened.writeFromSync(bytes, 0, bytes.length);
+      if (flush) opened.flushSync();
+    } finally {
+      opened.closeSync();
+    }
   }
 
   Future<File> writeAsString(String contents,
diff --git a/tests/_chrome/sample_test.dart b/tests/_chrome/sample_test.dart
index eb51d5c..85448ff 100644
--- a/tests/_chrome/sample_test.dart
+++ b/tests/_chrome/sample_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library sample_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:_chrome' as _chrome;
 
 main() {
diff --git a/tests/benchmark_smoke/benchmark_smoke_test.dart b/tests/benchmark_smoke/benchmark_smoke_test.dart
index c79275a..70647c8 100644
--- a/tests/benchmark_smoke/benchmark_smoke_test.dart
+++ b/tests/benchmark_smoke/benchmark_smoke_test.dart
@@ -8,9 +8,9 @@
 import 'benchmark_lib.dart';
 import 'dart:async';
 import 'dart:html';
-import '../../pkg/expect/lib/expect.dart';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:expect/expect.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 
 void main() {
   useHtmlConfiguration();
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 7020203a..a0c96a0 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -69,8 +69,8 @@
 LibTest/isolate/ReceivePort/toSendPort_A01_t01: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/ReceivePort/toSendPort_A01_t03: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/SendPort/call_A01_t01: Fail # co19-roll r706: Please triage this failure.
-LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/SendPort/send_A02_t04: Fail # co19-roll r706: Please triage this failure.
+LibTest/isolate/SendPort/send_A02_t03: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/SendPort/send_A02_t05: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/SendPort/send_A02_t06: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/SendPort/send_A03_t01: Fail # co19-roll r706: Please triage this failure.
@@ -131,9 +131,9 @@
 LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
 LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
 
-#co19 issue 677
 WebPlatformTest1/shadow-dom/*: CompileTimeError # co19 issue 677
 WebPlatformTest1/html-templates/*: CompileTimeError # co19 issue 677
+WebPlatformTest1/custom-elements/*: Pass, StaticWarning # Issue 18095.
 
 # co19 roll to r706: Please triage all these issues.
 Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A06_t03: StaticWarning # co19-roll r706: Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 03414b4..3e8938e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -70,6 +70,8 @@
 LibTest/isolate/SendPort/send_A01_t02: CompileTimeError # co19-roll r706: Please triage this failure
 LibTest/isolate/SendPort/send_A01_t03: CompileTimeError # co19-roll r706: Please triage this failure
 LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError, Pass # Dart issue 15617
+LibTest/math/Rectangle/boundingBox_A01_t01: RuntimeError, Pass # co19-roll 706: Please triage this failure.
+LibTest/math/MutableRectangle/boundingBox_A01_t01: RuntimeError, Pass # co19-roll 706: Please triage this failure.
 
 [ $compiler == dart2js && $runtime != ie9 ]
 LibTest/typed_data/ByteData/ByteData_A02_t01: fail # co19-roll r576: Please triage this failure
diff --git a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
index 20a663c..88a5680 100644
--- a/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred_load_graph_segmentation_test.dart
@@ -67,24 +67,36 @@
         .contains(inputElement));
 
     var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;
-    var hunksLib1 = new Set.from(hunksToLoad["lib1"].map((o) => o.name));
-    var hunksLib2 = new Set.from(hunksToLoad["lib2"].map((o) => o.name));
-    var hunksLib4_1 = new Set.from(hunksToLoad["lib4_1"].map((o) => o.name));
-    var hunksLib4_2 =  new Set.from(hunksToLoad["lib4_2"].map((o) => o.name));
-    Expect.equals(hunksLib1.length, 2);
-    Expect.isTrue(hunksLib1.contains("lib1"));
-    Expect.isTrue(hunksLib1.contains("lib1_lib2") ||
-                  hunksLib1.contains("lib2_lib1"));
-    Expect.isTrue(hunksLib2.contains("lib2"));
-    Expect.equals(hunksLib2.length, 2);
-    Expect.isTrue(hunksLib2.contains("lib1_lib2") ||
-                  hunksLib1.contains("lib2_lib1"));
-    Expect.isTrue(hunksLib4_1.contains("lib4_1"));
-    Expect.equals(hunksLib4_1.length, 1);
-    Expect.isTrue(hunksLib4_2.contains("lib4_2"));
-    Expect.equals(hunksLib4_2.length, 1);
-    Expect.equals(hunksToLoad["main"], null);
 
+    mapToNames(id) {
+      return hunksToLoad[id].map((l) {
+        return new Set.from(l.map((o) => o.name));
+      }).toList();
+    }
+
+    var hunksLib1 = mapToNames("lib1");
+    var hunksLib2 = mapToNames("lib2");
+    var hunksLib4_1 = mapToNames("lib4_1");
+    var hunksLib4_2 = mapToNames("lib4_2");
+    Expect.equals(hunksLib1.length, 2);
+    Expect.equals(hunksLib1[0].length, 1);
+    Expect.equals(hunksLib1[1].length, 1);
+    Expect.isTrue(hunksLib1[0].contains("lib1_lib2") ||
+                  hunksLib1[0].contains("lib2_lib1"));
+    Expect.isTrue(hunksLib1[1].contains("lib1"));
+    Expect.equals(hunksLib2.length, 2);
+    Expect.equals(hunksLib2[0].length, 1);
+    Expect.equals(hunksLib2[1].length, 1);
+    Expect.isTrue(hunksLib2[0].contains("lib1_lib2") ||
+                  hunksLib2[0].contains("lib2_lib1"));
+    Expect.isTrue(hunksLib2[1].contains("lib2"));
+    Expect.equals(hunksLib4_1.length, 1);
+    Expect.equals(hunksLib4_1[0].length, 1);
+    Expect.isTrue(hunksLib4_1[0].contains("lib4_1"));
+    Expect.equals(hunksLib4_2.length, 1);
+    Expect.equals(hunksLib4_2[0].length, 1);
+    Expect.isTrue(hunksLib4_2[0].contains("lib4_2"));
+    Expect.equals(hunksToLoad["main"], null);
   }));
 }
 
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index 20e16cf..e050421 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -58,7 +58,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 376;
+    int expectedMethodCount = 377;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
index ae4964a..5df6c73 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_class_test.dart
@@ -19,8 +19,7 @@
   Expect.isNull(x);
   int counter = 0;
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
+  lazy.load().then((_) {
     Expect.equals(1, ++counter);
     print('deferred_class_library was loaded');
     x = new lib.MyClass();
@@ -30,8 +29,7 @@
   Expect.equals(0, counter);
   Expect.isNull(x);
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isFalse(didLoad);
+  lazy.load().then((_) {
     Expect.equals(2, ++counter);
     print('deferred_class_library was loaded');
     x = new lib.MyClass();
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
index cb67911..21c4a7d 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant2_test.dart
@@ -13,8 +13,7 @@
 
 main() {
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
+  lazy.load().then((_) {
     Expect.equals(499, lib.C1.value);
     asyncEnd();
   });
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
index 876dfa3..afc2b24 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant3_test.dart
@@ -13,8 +13,7 @@
 
 main() {
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
+  lazy.load().then((_) {
     Expect.equals(499, lib.C1.value);
     Expect.equals(99, lib.C2[0].value);
     Expect.equals(42, lib.foo().value);
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
index e22d11b..ee4b0d6 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant4_test.dart
@@ -13,8 +13,7 @@
 
 main() {
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
+  lazy.load().then((_) {
     // Only Gee2.n888 to make sure no other constant pulls in its super.
     Expect.equals(888, new lib.Gee2.n888().value);
     asyncEnd();
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
index 09b27f0..aad0c57 100644
--- a/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
+++ b/tests/compiler/dart2js_extra/deferred/deferred_function_test.dart
@@ -28,8 +28,7 @@
   Expect.throws(readFoo, isNoSuchMethodError);
   int counter = 0;
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
+  lazy.load().then((_) {
     Expect.equals(1, ++counter);
     print('lazy was loaded');
     Expect.equals(42, lib.foo('b'));
@@ -38,8 +37,7 @@
   });
   Expect.equals(0, counter);
   asyncStart();
-  lazy.load().then((bool didLoad) {
-    Expect.isFalse(didLoad);
+  lazy.load().then((_) {
     Expect.equals(2, ++counter);
     print('lazy was loaded');
     Expect.equals(42, lib.foo('b'));
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart
new file mode 100644
index 0000000..3f72583
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib1.dart
@@ -0,0 +1,7 @@
+// 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.
+
+import "deferred_overlapping_lib3.dart";
+
+class C1 extends C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart
new file mode 100644
index 0000000..fdd2af1
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib2.dart
@@ -0,0 +1,7 @@
+// 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.
+
+import "deferred_overlapping_lib3.dart";
+
+class C2 extends C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart
new file mode 100644
index 0000000..80d5c9e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_lib3.dart
@@ -0,0 +1,5 @@
+// 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.
+
+class C3 {}
\ No newline at end of file
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.dart
new file mode 100644
index 0000000..0e5ee2b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_overlapping_test.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.
+
+import "deferred_overlapping_lib1.dart" deferred as lib1;
+import "deferred_overlapping_lib2.dart" deferred as lib2;
+
+// lib1.C1 and lib2.C2 has a shared base class It will go in its own hunk.
+// If lib1 or lib2s hunks are loaded before the common hunk, the program
+// will fail because the base class does not exist.
+void main() {
+  lib1.loadLibrary().then((_) {
+    var a = new lib1.C1();
+    lib2.loadLibrary().then((_) {
+      var b = new lib2.C2();
+    });
+  });
+}
\ No newline at end of file
diff --git a/tests/html/async_test.dart b/tests/html/async_test.dart
index a0d99fb..4144098 100644
--- a/tests/html/async_test.dart
+++ b/tests/html/async_test.dart
@@ -1,7 +1,7 @@
 library async_test;
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 
 import 'dart:async';
 import 'dart:isolate';
diff --git a/tests/html/audiobuffersourcenode_test.dart b/tests/html/audiobuffersourcenode_test.dart
index 15bba1e..c55c08c 100644
--- a/tests/html/audiobuffersourcenode_test.dart
+++ b/tests/html/audiobuffersourcenode_test.dart
@@ -1,6 +1,6 @@
 library AudioBufferSourceNodeTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:web_audio';
 
 main() {
diff --git a/tests/html/audiocontext_test.dart b/tests/html/audiocontext_test.dart
index dda3d25..81e4e5f 100644
--- a/tests/html/audiocontext_test.dart
+++ b/tests/html/audiocontext_test.dart
@@ -1,6 +1,6 @@
 library AudioContextTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 import 'dart:web_audio';
diff --git a/tests/html/audioelement_test.dart b/tests/html/audioelement_test.dart
index 0b518e0..2828596 100644
--- a/tests/html/audioelement_test.dart
+++ b/tests/html/audioelement_test.dart
@@ -1,6 +1,6 @@
 library AudioElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/b_element_test.dart b/tests/html/b_element_test.dart
index 1cd71b6..f208e6d 100644
--- a/tests/html/b_element_test.dart
+++ b/tests/html/b_element_test.dart
@@ -1,6 +1,6 @@
 library BElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/blob_constructor_test.dart b/tests/html/blob_constructor_test.dart
index ea3ec66..41461f5 100644
--- a/tests/html/blob_constructor_test.dart
+++ b/tests/html/blob_constructor_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library blob_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/cache_test.dart b/tests/html/cache_test.dart
index 5f110b2..d81770f 100644
--- a/tests/html/cache_test.dart
+++ b/tests/html/cache_test.dart
@@ -1,6 +1,6 @@
 library CacheTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/callbacks_test.dart b/tests/html/callbacks_test.dart
index e1aa779..c6e9498 100644
--- a/tests/html/callbacks_test.dart
+++ b/tests/html/callbacks_test.dart
@@ -1,6 +1,6 @@
 library CallbacksTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/canvas_pixel_array_type_alias_test.dart b/tests/html/canvas_pixel_array_type_alias_test.dart
index 7cdbb24..f346850 100644
--- a/tests/html/canvas_pixel_array_type_alias_test.dart
+++ b/tests/html/canvas_pixel_array_type_alias_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library CanvasTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/canvas_test.dart b/tests/html/canvas_test.dart
index 307be78..d83c1d9 100644
--- a/tests/html/canvas_test.dart
+++ b/tests/html/canvas_test.dart
@@ -1,6 +1,6 @@
 library CanvasTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart
index fa4402f..73eeeb7a 100644
--- a/tests/html/canvasrenderingcontext2d_test.dart
+++ b/tests/html/canvasrenderingcontext2d_test.dart
@@ -2,11 +2,14 @@
 // 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 canvas_rendering_context_2d_test; import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+library canvas_rendering_context_2d_test;
+
 import 'dart:html';
 import 'dart:math';
 
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+
 // Some rounding errors in the browsers.
 checkPixel(List<int> pixel, List<int> expected) {
   expect(pixel[0], closeTo(expected[0], 2));
diff --git a/tests/html/cdata_test.dart b/tests/html/cdata_test.dart
index b23a397..424d52f 100644
--- a/tests/html/cdata_test.dart
+++ b/tests/html/cdata_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library cdata_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 
diff --git a/tests/html/client_rect_test.dart b/tests/html/client_rect_test.dart
index 9bc233f..b9c9bb54 100644
--- a/tests/html/client_rect_test.dart
+++ b/tests/html/client_rect_test.dart
@@ -1,6 +1,6 @@
 library ClientRectTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/cross_frame_test.dart b/tests/html/cross_frame_test.dart
index cc852f8..b5a37f6 100644
--- a/tests/html/cross_frame_test.dart
+++ b/tests/html/cross_frame_test.dart
@@ -1,6 +1,6 @@
 library CrossFrameTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/crypto_test.dart b/tests/html/crypto_test.dart
index b4992a3..41666a5 100644
--- a/tests/html/crypto_test.dart
+++ b/tests/html/crypto_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library crypto_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/css_rule_list_test.dart b/tests/html/css_rule_list_test.dart
index 21224df..ade3833 100644
--- a/tests/html/css_rule_list_test.dart
+++ b/tests/html/css_rule_list_test.dart
@@ -1,6 +1,6 @@
 library CssRuleListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/css_test.dart b/tests/html/css_test.dart
index 01a05d0..deda6c5 100644
--- a/tests/html/css_test.dart
+++ b/tests/html/css_test.dart
@@ -1,6 +1,6 @@
 library CssTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/cssstyledeclaration_test.dart b/tests/html/cssstyledeclaration_test.dart
index 12a5f15..38bdbf3 100644
--- a/tests/html/cssstyledeclaration_test.dart
+++ b/tests/html/cssstyledeclaration_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library CssStyleDeclarationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:async';
 import 'utils.dart';
diff --git a/tests/html/custom_tags_test.dart b/tests/html/custom_tags_test.dart
index 6295af5..5f5457b 100644
--- a/tests/html/custom_tags_test.dart
+++ b/tests/html/custom_tags_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library custom_tags_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'utils.dart';
 
diff --git a/tests/html/dart_object_local_storage_test.dart b/tests/html/dart_object_local_storage_test.dart
index 32050d3..22add6a 100644
--- a/tests/html/dart_object_local_storage_test.dart
+++ b/tests/html/dart_object_local_storage_test.dart
@@ -1,6 +1,6 @@
 library DartObjectLocalStorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // TODO(vsm): Rename this to wrapper_caching_test or similar.  It's
diff --git a/tests/html/datalistelement_test.dart b/tests/html/datalistelement_test.dart
index 8af53c1..2fd9fa8 100644
--- a/tests/html/datalistelement_test.dart
+++ b/tests/html/datalistelement_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library datalistelement_dataview_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/document_test.dart b/tests/html/document_test.dart
index 355a126..7e69c1f 100644
--- a/tests/html/document_test.dart
+++ b/tests/html/document_test.dart
@@ -1,6 +1,6 @@
 library DocumentTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/documentfragment_test.dart b/tests/html/documentfragment_test.dart
index 62d4b73..b09c04d 100644
--- a/tests/html/documentfragment_test.dart
+++ b/tests/html/documentfragment_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library DocumentFragmentTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'util.dart';
 import 'dart:html';
 
diff --git a/tests/html/dom_constructors_test.dart b/tests/html/dom_constructors_test.dart
index c2f8ad0..a2bcf55 100644
--- a/tests/html/dom_constructors_test.dart
+++ b/tests/html/dom_constructors_test.dart
@@ -1,6 +1,6 @@
 library DOMConstructorsTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/domparser_test.dart b/tests/html/domparser_test.dart
index a6f6246..61ecf86 100644
--- a/tests/html/domparser_test.dart
+++ b/tests/html/domparser_test.dart
@@ -1,6 +1,6 @@
 library DOMParserTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/dromaeo_noop/dromaeo_smoke.dart b/tests/html/dromaeo_noop/dromaeo_smoke.dart
index 68c5dc4..0a1e13e 100644
--- a/tests/html/dromaeo_noop/dromaeo_smoke.dart
+++ b/tests/html/dromaeo_noop/dromaeo_smoke.dart
@@ -3,13 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library dromaeo;
+
 import 'dart:async';
-import 'dart:html';
 import "dart:convert";
-import '../../../samples/third_party/dromaeo/common/common.dart';
+import 'dart:html';
 import 'dart:math' as Math;
-import '../../../pkg/unittest/lib/unittest.dart';
-import '../../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import '../../../samples/third_party/dromaeo/common/common.dart';
+
 part '../../../samples/third_party/dromaeo/tests/Common.dart';
 part '../../../samples/third_party/dromaeo/tests/RunnerSuite.dart';
 
diff --git a/tests/html/dromaeo_smoke_test.dart b/tests/html/dromaeo_smoke_test.dart
index 51ebf35..2f71f9b6 100644
--- a/tests/html/dromaeo_smoke_test.dart
+++ b/tests/html/dromaeo_smoke_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library dromaeo;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import '../../samples/third_party/dromaeo/web/Dromaeo.dart' as originalTest;
 import 'dart:html';
 import 'dart:async';
diff --git a/tests/html/element_add_test.dart b/tests/html/element_add_test.dart
index 2ec51db..0f9cc2e 100644
--- a/tests/html/element_add_test.dart
+++ b/tests/html/element_add_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library ElementAddTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'util.dart';
 import 'dart:html';
 
diff --git a/tests/html/element_classes_test.dart b/tests/html/element_classes_test.dart
index 9ef9860..cf6a35c 100644
--- a/tests/html/element_classes_test.dart
+++ b/tests/html/element_classes_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:collection';
 import 'dart:html';
 
diff --git a/tests/html/element_constructor_1_test.dart b/tests/html/element_constructor_1_test.dart
index 74a40fa..b53e366 100644
--- a/tests/html/element_constructor_1_test.dart
+++ b/tests/html/element_constructor_1_test.dart
@@ -7,8 +7,8 @@
 // element_constructor_foo_test.dart file.
 
 library ElementConstructorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/element_offset_test.dart b/tests/html/element_offset_test.dart
index f402642..10102d3 100644
--- a/tests/html/element_offset_test.dart
+++ b/tests/html/element_offset_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library element_offset_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:async';
 import 'dart:html';
 
diff --git a/tests/html/element_test.dart b/tests/html/element_test.dart
index 936eb68..6f75758 100644
--- a/tests/html/element_test.dart
+++ b/tests/html/element_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:async';
 import 'dart:html';
 import 'dart:svg' as svg;
diff --git a/tests/html/element_types_test.dart b/tests/html/element_types_test.dart
index 960bb16..df0c488 100644
--- a/tests/html/element_types_test.dart
+++ b/tests/html/element_types_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library element_types;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/event_customevent_test.dart b/tests/html/event_customevent_test.dart
index f9168a9..cbda1a7 100644
--- a/tests/html/event_customevent_test.dart
+++ b/tests/html/event_customevent_test.dart
@@ -4,8 +4,8 @@
 
 library EventCustomEventTest;
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:js' as js;
 
diff --git a/tests/html/event_test.dart b/tests/html/event_test.dart
index e8f743b..9b7893a 100644
--- a/tests/html/event_test.dart
+++ b/tests/html/event_test.dart
@@ -4,8 +4,8 @@
 
 library EventTest;
 import "package:expect/expect.dart";
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // TODO(nweiz): Make this private to testEvents when Frog supports closures with
diff --git a/tests/html/exceptions_test.dart b/tests/html/exceptions_test.dart
index b8f26ab..d7603b9 100644
--- a/tests/html/exceptions_test.dart
+++ b/tests/html/exceptions_test.dart
@@ -1,6 +1,6 @@
 library ExceptionsTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/fileapi_test.dart b/tests/html/fileapi_test.dart
index b276e76..edc6fa2 100644
--- a/tests/html/fileapi_test.dart
+++ b/tests/html/fileapi_test.dart
@@ -1,6 +1,6 @@
 library fileapi;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:async';
 
diff --git a/tests/html/form_data_test.dart b/tests/html/form_data_test.dart
index 0435f86..6132c16 100644
--- a/tests/html/form_data_test.dart
+++ b/tests/html/form_data_test.dart
@@ -4,8 +4,8 @@
 
 library FormDataTest;
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 void main() {
diff --git a/tests/html/form_element_test.dart b/tests/html/form_element_test.dart
index b7d030c..b3b06c3 100644
--- a/tests/html/form_element_test.dart
+++ b/tests/html/form_element_test.dart
@@ -4,8 +4,8 @@
 
 library FormElementTest;
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 void main() {
diff --git a/tests/html/geolocation_test.dart b/tests/html/geolocation_test.dart
index e6dd1b3..c49e531 100644
--- a/tests/html/geolocation_test.dart
+++ b/tests/html/geolocation_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library geolocation_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/hidden_dom_1_test.dart b/tests/html/hidden_dom_1_test.dart
index b2a51bd..120136b5 100644
--- a/tests/html/hidden_dom_1_test.dart
+++ b/tests/html/hidden_dom_1_test.dart
@@ -1,6 +1,6 @@
 library HiddenDom1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // Test that the dart:html API does not leak native jsdom methods:
diff --git a/tests/html/hidden_dom_2_test.dart b/tests/html/hidden_dom_2_test.dart
index 1c1bad5..e8abc4e 100644
--- a/tests/html/hidden_dom_2_test.dart
+++ b/tests/html/hidden_dom_2_test.dart
@@ -1,6 +1,6 @@
 library HiddenDom2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // Test that the dart:html API does not leak native jsdom methods:
diff --git a/tests/html/history_test.dart b/tests/html/history_test.dart
index f8fd547..893fb77 100644
--- a/tests/html/history_test.dart
+++ b/tests/html/history_test.dart
@@ -1,6 +1,6 @@
 library HistoryTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:async';
 
diff --git a/tests/html/htmlcollection_test.dart b/tests/html/htmlcollection_test.dart
index 296f30b..9781c3c9 100644
--- a/tests/html/htmlcollection_test.dart
+++ b/tests/html/htmlcollection_test.dart
@@ -1,6 +1,6 @@
 library ElementListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // Test that List<Element> implements List<T>
diff --git a/tests/html/htmlelement_test.dart b/tests/html/htmlelement_test.dart
index f4157ed..fd22c13 100644
--- a/tests/html/htmlelement_test.dart
+++ b/tests/html/htmlelement_test.dart
@@ -1,6 +1,6 @@
 library ElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'utils.dart';
 
diff --git a/tests/html/htmloptionscollection_test.dart b/tests/html/htmloptionscollection_test.dart
index 9a633ab..cc5166a 100644
--- a/tests/html/htmloptionscollection_test.dart
+++ b/tests/html/htmloptionscollection_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library HTMLOptionsCollectionTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/indexeddb_1_test.dart b/tests/html/indexeddb_1_test.dart
index a099bf0..f4422de 100644
--- a/tests/html/indexeddb_1_test.dart
+++ b/tests/html/indexeddb_1_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:math' as math;
diff --git a/tests/html/indexeddb_2_test.dart b/tests/html/indexeddb_2_test.dart
index efd4d80..7350559 100644
--- a/tests/html/indexeddb_2_test.dart
+++ b/tests/html/indexeddb_2_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db' as idb;
diff --git a/tests/html/indexeddb_3_test.dart b/tests/html/indexeddb_3_test.dart
index d3030dc..c5034c4 100644
--- a/tests/html/indexeddb_3_test.dart
+++ b/tests/html/indexeddb_3_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB3Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db';
diff --git a/tests/html/indexeddb_4_test.dart b/tests/html/indexeddb_4_test.dart
index 76e264e..3761301 100644
--- a/tests/html/indexeddb_4_test.dart
+++ b/tests/html/indexeddb_4_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB4Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db';
diff --git a/tests/html/indexeddb_5_test.dart b/tests/html/indexeddb_5_test.dart
index 786cb0b..cbf77d1 100644
--- a/tests/html/indexeddb_5_test.dart
+++ b/tests/html/indexeddb_5_test.dart
@@ -1,6 +1,6 @@
 library IndexedDB1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html' as html;
 import 'dart:indexed_db' as idb;
diff --git a/tests/html/input_element_test.dart b/tests/html/input_element_test.dart
index 43f245c..02fb062 100644
--- a/tests/html/input_element_test.dart
+++ b/tests/html/input_element_test.dart
@@ -1,6 +1,6 @@
 library input_element_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 void check(InputElement element, String type, [bool supported = true]) {
diff --git a/tests/html/instance_of_test.dart b/tests/html/instance_of_test.dart
index 6e70809..da664db 100644
--- a/tests/html/instance_of_test.dart
+++ b/tests/html/instance_of_test.dart
@@ -1,6 +1,6 @@
 library InstanceOfTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/interactive_test.dart b/tests/html/interactive_test.dart
index e8d70ff..82a879b 100644
--- a/tests/html/interactive_test.dart
+++ b/tests/html/interactive_test.dart
@@ -6,8 +6,8 @@
 
 import 'dart:async';
 import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'utils.dart';
 
 
diff --git a/tests/html/isolates_test.dart b/tests/html/isolates_test.dart
index fa703d2..9c07ed0 100644
--- a/tests/html/isolates_test.dart
+++ b/tests/html/isolates_test.dart
@@ -1,6 +1,6 @@
 library IsolatesTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html';
 import 'dart:convert';
diff --git a/tests/html/js_interop_1_test.dart b/tests/html/js_interop_1_test.dart
index 7ba954d..c7165c4 100644
--- a/tests/html/js_interop_1_test.dart
+++ b/tests/html/js_interop_1_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library JsInterop1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 injectSource(code) {
diff --git a/tests/html/js_test.dart b/tests/html/js_test.dart
index ba5d007..081ab02 100644
--- a/tests/html/js_test.dart
+++ b/tests/html/js_test.dart
@@ -10,8 +10,8 @@
 import 'dart:indexed_db' show IdbFactory, KeyRange;
 import 'dart:js';
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 
 _injectJs() {
   final script = new ScriptElement();
diff --git a/tests/html/keyboard_event_test.dart b/tests/html/keyboard_event_test.dart
index a29f02f..8fca793 100644
--- a/tests/html/keyboard_event_test.dart
+++ b/tests/html/keyboard_event_test.dart
@@ -1,6 +1,6 @@
 library KeyboardEventTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 // Test that we are correctly determining keyCode and charCode uniformly across
diff --git a/tests/html/localstorage_test.dart b/tests/html/localstorage_test.dart
index f2823a2..3e92b10 100644
--- a/tests/html/localstorage_test.dart
+++ b/tests/html/localstorage_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library LocalStorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/location_test.dart b/tests/html/location_test.dart
index d5c8e5e..e274a2a0 100644
--- a/tests/html/location_test.dart
+++ b/tests/html/location_test.dart
@@ -1,6 +1,6 @@
 library LocationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/media_stream_test.dart b/tests/html/media_stream_test.dart
index 2c6635a..602c199 100644
--- a/tests/html/media_stream_test.dart
+++ b/tests/html/media_stream_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library media_stream_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/messageevent_test.dart b/tests/html/messageevent_test.dart
index c2c832a..a436189 100644
--- a/tests/html/messageevent_test.dart
+++ b/tests/html/messageevent_test.dart
@@ -1,6 +1,6 @@
 library SerializedScriptValueTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/mouse_event_test.dart b/tests/html/mouse_event_test.dart
index 4be967b..dcd442f 100644
--- a/tests/html/mouse_event_test.dart
+++ b/tests/html/mouse_event_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library mouse_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/mutationobserver_test.dart b/tests/html/mutationobserver_test.dart
index 8804ab6..e2de7e0 100644
--- a/tests/html/mutationobserver_test.dart
+++ b/tests/html/mutationobserver_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library mutationobserver_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 // Due to https://code.google.com/p/chromium/issues/detail?id=329103
diff --git a/tests/html/native_gc_test.dart b/tests/html/native_gc_test.dart
index 9aaf72e..5931cc8 100644
--- a/tests/html/native_gc_test.dart
+++ b/tests/html/native_gc_test.dart
@@ -1,6 +1,6 @@
 library NativeGCTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 var testEvent = new EventStreamProvider<Event>('test');
diff --git a/tests/html/navigator_test.dart b/tests/html/navigator_test.dart
index abbcc4e..2bc5cc8 100644
--- a/tests/html/navigator_test.dart
+++ b/tests/html/navigator_test.dart
@@ -1,6 +1,6 @@
 library NavigatorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart
index d142c60..3dd5679 100644
--- a/tests/html/node_test.dart
+++ b/tests/html/node_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library NodeTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:svg' as svg;
 
diff --git a/tests/html/non_instantiated_is_test.dart b/tests/html/non_instantiated_is_test.dart
index bf1ece1..b226ea7 100644
--- a/tests/html/non_instantiated_is_test.dart
+++ b/tests/html/non_instantiated_is_test.dart
@@ -6,8 +6,8 @@
 // checks of native classes that are not instantiated.
 
 import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 
 var a = [new Object()];
 
diff --git a/tests/html/performance_api_test.dart b/tests/html/performance_api_test.dart
index 7ba9d9c..f4f1d28 100644
--- a/tests/html/performance_api_test.dart
+++ b/tests/html/performance_api_test.dart
@@ -1,6 +1,6 @@
 library PerformanceApiTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/postmessage_structured_test.dart b/tests/html/postmessage_structured_test.dart
index c586fd9..9ceeebc 100644
--- a/tests/html/postmessage_structured_test.dart
+++ b/tests/html/postmessage_structured_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library postmessage_js_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:collection';  // SplayTreeMap
 import 'dart:typed_data';
diff --git a/tests/html/query_test.dart b/tests/html/query_test.dart
index 33fabc5..bffe0d9 100644
--- a/tests/html/query_test.dart
+++ b/tests/html/query_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library QueryTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/queryall_test.dart b/tests/html/queryall_test.dart
index 7b910c5..be4e67b 100644
--- a/tests/html/queryall_test.dart
+++ b/tests/html/queryall_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library NodeListTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/range_test.dart b/tests/html/range_test.dart
index 3792afd..5c2028d 100644
--- a/tests/html/range_test.dart
+++ b/tests/html/range_test.dart
@@ -1,8 +1,8 @@
 library range_test;
 
 import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 
 main() {
   useHtmlIndividualConfiguration();
diff --git a/tests/html/request_animation_frame_test.dart b/tests/html/request_animation_frame_test.dart
index f240b70..32e22c8 100644
--- a/tests/html/request_animation_frame_test.dart
+++ b/tests/html/request_animation_frame_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library RequestAnimationFrameTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/rtc_test.dart b/tests/html/rtc_test.dart
index df096ab0..e55e79f 100644
--- a/tests/html/rtc_test.dart
+++ b/tests/html/rtc_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library RealTimeCommunicationTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/selectelement_test.dart b/tests/html/selectelement_test.dart
index 81eb13d..b56912c 100644
--- a/tests/html/selectelement_test.dart
+++ b/tests/html/selectelement_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library selectelement_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/serialized_script_value_test.dart b/tests/html/serialized_script_value_test.dart
index af673b6..16c8b43 100644
--- a/tests/html/serialized_script_value_test.dart
+++ b/tests/html/serialized_script_value_test.dart
@@ -1,6 +1,6 @@
 library SerializedScriptValueTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'utils.dart';
 
diff --git a/tests/html/shadow_dom_test.dart b/tests/html/shadow_dom_test.dart
index d9ec86a..323d0e2 100644
--- a/tests/html/shadow_dom_test.dart
+++ b/tests/html/shadow_dom_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library ShadowDOMTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/shadowroot_test.dart b/tests/html/shadowroot_test.dart
index 04e0b5e..c3ac8d9 100644
--- a/tests/html/shadowroot_test.dart
+++ b/tests/html/shadowroot_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library ShadowRootTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/speechrecognition_test.dart b/tests/html/speechrecognition_test.dart
index cf3a4fa..16fd9de 100644
--- a/tests/html/speechrecognition_test.dart
+++ b/tests/html/speechrecognition_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library speech_recognition_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/storage_test.dart b/tests/html/storage_test.dart
index 5f09e20..b68e9d4 100644
--- a/tests/html/storage_test.dart
+++ b/tests/html/storage_test.dart
@@ -1,6 +1,6 @@
 library StorageTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/streams_test.dart b/tests/html/streams_test.dart
index 7a3b2ff..edd77e7 100644
--- a/tests/html/streams_test.dart
+++ b/tests/html/streams_test.dart
@@ -1,6 +1,6 @@
 library streams_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:async';
 import 'dart:html';
 
diff --git a/tests/html/table_test.dart b/tests/html/table_test.dart
index 5c1144f..7432e5d 100644
--- a/tests/html/table_test.dart
+++ b/tests/html/table_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TableTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/touchevent_test.dart b/tests/html/touchevent_test.dart
index 8d90e5b..fba6e61 100644
--- a/tests/html/touchevent_test.dart
+++ b/tests/html/touchevent_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library touch_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/transferables_test.dart b/tests/html/transferables_test.dart
index d2ad13f..f2aa905 100644
--- a/tests/html/transferables_test.dart
+++ b/tests/html/transferables_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TransferableTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/transition_event_test.dart b/tests/html/transition_event_test.dart
index 646061f..399e2ec 100644
--- a/tests/html/transition_event_test.dart
+++ b/tests/html/transition_event_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library transition_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:async';
 
diff --git a/tests/html/typed_arrays_1_test.dart b/tests/html/typed_arrays_1_test.dart
index a2de291..c3eb811 100644
--- a/tests/html/typed_arrays_1_test.dart
+++ b/tests/html/typed_arrays_1_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArrays1Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_2_test.dart b/tests/html/typed_arrays_2_test.dart
index e223ea7..5a0d83a 100644
--- a/tests/html/typed_arrays_2_test.dart
+++ b/tests/html/typed_arrays_2_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArrays2Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_3_test.dart b/tests/html/typed_arrays_3_test.dart
index 53f0b8d..efa4e17 100644
--- a/tests/html/typed_arrays_3_test.dart
+++ b/tests/html/typed_arrays_3_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArrays3Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_4_test.dart b/tests/html/typed_arrays_4_test.dart
index 11a39e8..9f00357 100644
--- a/tests/html/typed_arrays_4_test.dart
+++ b/tests/html/typed_arrays_4_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArrays4Test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_5_test.dart b/tests/html/typed_arrays_5_test.dart
index 3c6948d..db149f6 100644
--- a/tests/html/typed_arrays_5_test.dart
+++ b/tests/html/typed_arrays_5_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library typed_arrays_5_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_arraybuffer_test.dart b/tests/html/typed_arrays_arraybuffer_test.dart
index af75ab9..07541c8 100644
--- a/tests/html/typed_arrays_arraybuffer_test.dart
+++ b/tests/html/typed_arrays_arraybuffer_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library typed_arrays_arraybuffer_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_dataview_test.dart b/tests/html/typed_arrays_dataview_test.dart
index 83b076f..a56aecd 100644
--- a/tests/html/typed_arrays_dataview_test.dart
+++ b/tests/html/typed_arrays_dataview_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library typed_arrays_dataview_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_range_checks_test.dart b/tests/html/typed_arrays_range_checks_test.dart
index 2338ac1..1eb2222 100644
--- a/tests/html/typed_arrays_range_checks_test.dart
+++ b/tests/html/typed_arrays_range_checks_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArraysRangeCheckTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typed_arrays_simd_test.dart b/tests/html/typed_arrays_simd_test.dart
index b0e3176..0e3d780 100644
--- a/tests/html/typed_arrays_simd_test.dart
+++ b/tests/html/typed_arrays_simd_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library TypedArraysSimdTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/typing_test.dart b/tests/html/typing_test.dart
index c0a8389..68ba294 100644
--- a/tests/html/typing_test.dart
+++ b/tests/html/typing_test.dart
@@ -1,6 +1,6 @@
 library TypingTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/unknownelement_test.dart b/tests/html/unknownelement_test.dart
index 6632974..21ba1ef 100644
--- a/tests/html/unknownelement_test.dart
+++ b/tests/html/unknownelement_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file
 
 library UnknownElementTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/uri_test.dart b/tests/html/uri_test.dart
index af2ae82..90798849 100644
--- a/tests/html/uri_test.dart
+++ b/tests/html/uri_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/url_test.dart b/tests/html/url_test.dart
index 6852fc6..69f55ad 100644
--- a/tests/html/url_test.dart
+++ b/tests/html/url_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library url_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 
diff --git a/tests/html/util.dart b/tests/html/util.dart
index 25bb502..52735f2 100644
--- a/tests/html/util.dart
+++ b/tests/html/util.dart
@@ -5,7 +5,7 @@
 library test.html.util;
 
 import 'dart:html';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 void expectUnsupported(f) => expect(f, throwsUnsupportedError);
 
diff --git a/tests/html/webgl_1_test.dart b/tests/html/webgl_1_test.dart
index ae276eb..d6e6f1f 100644
--- a/tests/html/webgl_1_test.dart
+++ b/tests/html/webgl_1_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library web_gl_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import 'dart:typed_data';
 import 'dart:web_gl';
diff --git a/tests/html/websocket_test.dart b/tests/html/websocket_test.dart
index 2e02761..f8ba1ba 100644
--- a/tests/html/websocket_test.dart
+++ b/tests/html/websocket_test.dart
@@ -1,6 +1,6 @@
 library WebSocketTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/websql_test.dart b/tests/html/websql_test.dart
index b67d0aa..a2c3905 100644
--- a/tests/html/websql_test.dart
+++ b/tests/html/websql_test.dart
@@ -2,8 +2,8 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:web_sql';
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 
 Future<SqlTransaction> transaction(SqlDatabase db) {
   final completer = new Completer<SqlTransaction>.sync();
diff --git a/tests/html/wheelevent_test.dart b/tests/html/wheelevent_test.dart
index d733a94..8223573 100644
--- a/tests/html/wheelevent_test.dart
+++ b/tests/html/wheelevent_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library wheel_event_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 
diff --git a/tests/html/window_eq_test.dart b/tests/html/window_eq_test.dart
index 718011c..6995a90 100644
--- a/tests/html/window_eq_test.dart
+++ b/tests/html/window_eq_test.dart
@@ -1,6 +1,6 @@
 library WindowEqualityTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/window_mangling_test.dart b/tests/html/window_mangling_test.dart
index 33704b3..f1a8b38 100644
--- a/tests/html/window_mangling_test.dart
+++ b/tests/html/window_mangling_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library WindowManglingTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html' as dom;
 
 // Defined in dom.Window.
diff --git a/tests/html/window_nosuchmethod_test.dart b/tests/html/window_nosuchmethod_test.dart
index 0027d1e..93cb592 100644
--- a/tests/html/window_nosuchmethod_test.dart
+++ b/tests/html/window_nosuchmethod_test.dart
@@ -4,8 +4,8 @@
 
 library WindowNSMETest;
 import "package:expect/expect.dart";
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html' as dom;
 
 // Not defined in dom.Window.
diff --git a/tests/html/window_test.dart b/tests/html/window_test.dart
index edf822d..51ccdfd 100644
--- a/tests/html/window_test.dart
+++ b/tests/html/window_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library WindowTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/worker_test.dart b/tests/html/worker_test.dart
index 018d7fc..896781f 100644
--- a/tests/html/worker_test.dart
+++ b/tests/html/worker_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library worker_test;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/html/xhr_cross_origin_test.dart b/tests/html/xhr_cross_origin_test.dart
index 16e35cd..4a5935c 100644
--- a/tests/html/xhr_cross_origin_test.dart
+++ b/tests/html/xhr_cross_origin_test.dart
@@ -3,8 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library XHRCrossOriginTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 import "dart:convert";
 
diff --git a/tests/html/xsltprocessor_test.dart b/tests/html/xsltprocessor_test.dart
index 48d7b10..b645d81 100644
--- a/tests/html/xsltprocessor_test.dart
+++ b/tests/html/xsltprocessor_test.dart
@@ -1,6 +1,6 @@
 library XSLTProcessorTest;
-import '../../pkg/unittest/lib/unittest.dart';
-import '../../pkg/unittest/lib/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
 import 'dart:html';
 
 main() {
diff --git a/tests/isolate/spawn_uri_nested_vm_test.dart b/tests/isolate/spawn_uri_nested_vm_test.dart
index c1b084d..91b413c 100644
--- a/tests/isolate/spawn_uri_nested_vm_test.dart
+++ b/tests/isolate/spawn_uri_nested_vm_test.dart
@@ -8,7 +8,7 @@
 // OtherScripts=spawn_uri_nested_child1_vm_isolate.dart spawn_uri_nested_child2_vm_isolate.dart
 library NestedSpawnUriLibrary;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   test('isolate fromUri - nested send and reply', () {
diff --git a/tests/isolate/spawn_uri_test.dart b/tests/isolate/spawn_uri_test.dart
index 340170e5..5f64d7d 100644
--- a/tests/isolate/spawn_uri_test.dart
+++ b/tests/isolate/spawn_uri_test.dart
@@ -8,7 +8,7 @@
 // OtherScripts=spawn_uri_child_isolate.dart
 library spawn_tests;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   test('isolate fromUri - send and reply', () {
diff --git a/tests/isolate/spawn_uri_vm_test.dart b/tests/isolate/spawn_uri_vm_test.dart
index 7fbb20c..e5510a5 100644
--- a/tests/isolate/spawn_uri_vm_test.dart
+++ b/tests/isolate/spawn_uri_vm_test.dart
@@ -8,7 +8,7 @@
 // OtherScripts=spawn_uri_child_isolate.dart
 library spawn_tests;
 import 'dart:isolate';
-import '../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 main() {
   test('isolate fromUri - send and reply', () {
diff --git a/tests/language/const_constructor2_test.dart b/tests/language/const_constructor2_test.dart
new file mode 100644
index 0000000..2ebb00f
--- /dev/null
+++ b/tests/language/const_constructor2_test.dart
@@ -0,0 +1,78 @@
+// 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.
+
+// Regression test for issue 14348.
+
+class A<T> {
+  const A();
+}
+
+class B<S> extends A<S> {
+  const B();
+}
+
+class C<U> {
+  final A<U> a;
+
+  const C(A<U> this.a);
+  const C.optional([A<U> this.a]);
+  const C.named({A<U> this.a});
+  const C.untyped(this.a);
+  const C.subtyped(B<U> this.a);
+  const factory C.redirecting(B<U> a) = D;
+}
+
+class D extends C {
+  const D(B b) : super(b);
+}
+
+class E {
+  const factory E.redirecting1(var a) = F<int>;
+  const factory E.redirecting2(var a) = F<int>.redirecting;
+  const factory E.redirecting3(var a) = F<double>.redirecting;
+}
+
+class F<V> implements E {
+  final V field;
+
+  const F(this.field);
+  const factory F.redirecting(V field) = G<int>;
+}
+
+class G<W> implements F {
+  final field;
+  const G(W this.field);
+}
+
+main() {
+  const A<int> a = const B<int>();
+
+  const C c1 = const C(a); /// 01: ok
+  const C c2 = const C.optional(a); /// 02: ok
+  const C c3 = const C.named(a: a); /// 03: ok
+  const C c4 = const C.untyped(a); /// 04: ok
+  const C c5 = const C.subtyped(a); /// 05: ok
+  const C c5m = const C.redirecting(a); /// 06: ok
+
+  const C c6 = const C<int>(a); /// 07: ok
+  const C c7 = const C<int>.optional(a); /// 08: ok
+  const C c8 = const C<int>.named(a: a); /// 09: ok
+  const C c9 = const C<int>.untyped(a); /// 10: ok
+  const C c10 = const C<int>.subtyped(a); /// 11: ok
+  const C c10m = const C<int>.redirecting(a); /// 12: ok
+
+  const C c11 = const C<double>(a); /// 13: static type warning, checked mode compile-time error
+  const C c12 = const C<double>.optional(a); /// 14: static type warning, checked mode compile-time error
+  const C c13 = const C<double>.named(a: a); /// 15: static type warning, checked mode compile-time error
+  const C c14 = const C<double>.untyped(a); /// 16: static type warning, checked mode compile-time error
+  const C c15 = const C<double>.subtyped(a); /// 17: static type warning, checked mode compile-time error
+  const C c15m = const C<double>.redirecting(a); /// 18: static type warning
+
+  const E e1 = const E.redirecting1(0); /// 19: ok
+  const E e2 = const E.redirecting1(''); /// 20: checked mode compile-time error
+  const E e3 = const E.redirecting2(0); /// 21: ok
+  const E e4 = const E.redirecting2(''); /// 22: checked mode compile-time error
+  const E e5 = const E.redirecting3(0); /// 23: ok
+  const E e6 = const E.redirecting3(''); /// 24: checked mode compile-time error
+}
\ No newline at end of file
diff --git a/tests/language/disasssemble_test.dart b/tests/language/disassemble_test.dart
similarity index 100%
rename from tests/language/disasssemble_test.dart
rename to tests/language/disassemble_test.dart
diff --git a/tests/language/function_literals2_test.dart b/tests/language/function_literals2_test.dart
index 3572cbe..15be383 100644
--- a/tests/language/function_literals2_test.dart
+++ b/tests/language/function_literals2_test.dart
@@ -46,6 +46,9 @@
     Expect.equals(10, b.n);
     Expect.equals(101, (b.f)(10));
 
+    var c = new C(5);
+    Expect.equals("2*x is 10", c.s);
+
     int x = 0;
     int y = 1;
     // make sure this isn't parsed as a generic type
@@ -73,6 +76,10 @@
   B.withZ(z) : f = ((x) { return x * x + 1; }) { n = z; }
 }
 
+class C {
+  String s;
+  C(x) : s = "2*x is ${() { return 2*x; }()}";
+}
 main() {
   FunctionLiteralsTest.testMain();
 }
diff --git a/tests/language/language.status b/tests/language/language.status
index c57acaa..7069ee1 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -39,6 +39,8 @@
 deferred_constraints_constants_test/*: Fail, Pass
 deferred_shadow_load_library_test: Fail
 deferred_closurize_load_library_test: Fail
+override_inheritance_mixed_test/08: Fail # Issue 18124
+override_inheritance_mixed_test/09: Fail # Issue 18124
 
 [ $compiler == none || $compiler == dart2dart]
 # These test use the old syntax, and will be phased out.
@@ -69,8 +71,6 @@
 
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16137
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16137
 
 unicode_bom_test: Fail # Issue 16067
 
@@ -112,8 +112,9 @@
 [ $compiler == none && ( $runtime == dartium || $runtime == drt ) ]
 typed_message_test: Crash, Fail # Issue 13921, 14400
 vm/optimized_guarded_field_isolates_test: Fail # Issue 13921.
-override_inheritance_mixed_test/08: Fail # Issue 16137
-override_inheritance_mixed_test/09: Fail # Issue 16137
+
+[ $compiler == none && $runtime == drt ]
+disassemble_test: Pass, Fail # Issue 18122
 
 [ $compiler == none && $runtime == vm && $arch == mips && $checked ]
 generic_instanceof3_test: Pass, Crash # Issue 17440.
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index 6f90409..67d84da 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -29,6 +29,8 @@
 
 call_closurization_test: StaticWarning # Issue 17476
 
+function_literals2_test: Fail # Issue 18137
+
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
@@ -199,10 +201,6 @@
 override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135
 override_inheritance_generic_test/09: MissingStaticWarning # Issue 16135
 
-# missing compile-time error for getter/member override
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16136
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16136
-
 # flaky override tests
 override_inheritance_field_test/33: MissingStaticWarning, Pass # Issue 16498
 override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
@@ -466,11 +464,6 @@
 vm/type_vm_test: StaticWarning
 void_type_test: StaticWarning
 
-# Issue 16392.
-const_constructor2_test/20: MissingStaticWarning # Issue 16392.
-const_constructor2_test/22: MissingStaticWarning # Issue 16392.
-const_constructor2_test/24: MissingStaticWarning # Issue 16392.
-
 # Issue 16391. The analyzer handle compile-time error in checked only in these
 # cases:
 compile_time_constant_checked2_test/01: CompileTimeError # Issue 16391
@@ -490,4 +483,3 @@
 deferred_load_library_wrong_args_test/01: Fail
 deferred_load_library_wrong_args_test/none: Fail
 deferred_load_inval_code_test: Fail
-
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 2cd04c7..6af40b1 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -187,9 +187,11 @@
 override_inheritance_no_such_method_test/04: StaticWarning # Issue 16132
 override_inheritance_no_such_method_test/05: StaticWarning # Issue 16132
 
-# unexpected warning for override
-override_inheritance_abstract_test/27: StaticWarning # Issue 16134
-override_inheritance_generic_test/03: StaticWarning # Issue 16134
+# analyzer issue 17983
+override_inheritance_generic_test/08: MissingStaticWarning # Issue 17983
+override_inheritance_field_test/32: MissingStaticWarning # Issue 17983
+override_inheritance_field_test/09: MissingStaticWarning # Issue 17983
+override_inheritance_abstract_test/27: StaticWarning # Issue 17983
 
 # missing warning for override
 override_inheritance_generic_test/04: MissingStaticWarning # Issue 16135
@@ -197,10 +199,6 @@
 override_inheritance_generic_test/07: MissingStaticWarning # Issue 16135
 override_inheritance_generic_test/09: MissingStaticWarning # Issue 16135
 
-# missing compile-time error for getter/member override
-override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 16136
-override_inheritance_mixed_test/09: MissingCompileTimeError # Issue 16136
-
 # flaky override tests
 override_inheritance_field_test/33: MissingStaticWarning, Pass # Issue 16498
 override_inheritance_field_test/33a: MissingStaticWarning, Pass # Issue 16498
@@ -464,11 +462,6 @@
 vm/type_vm_test: StaticWarning
 void_type_test: StaticWarning
 
-# Issue 16392.
-const_constructor2_test/20: MissingStaticWarning # Issue 16392.
-const_constructor2_test/22: MissingStaticWarning # Issue 16392.
-const_constructor2_test/24: MissingStaticWarning # Issue 16392.
-
 # Issue 16391. The analyzer handle compile-time error in checked only in these
 # cases:
 compile_time_constant_checked2_test/01: CompileTimeError # Issue 16391
@@ -488,4 +481,3 @@
 deferred_load_library_wrong_args_test/01: Fail
 deferred_load_library_wrong_args_test/none: Fail
 deferred_load_inval_code_test: Fail
-
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 4b30660..c97ea0b 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,6 +3,9 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js || $compiler == dart2dart ]
+function_literals2_test: Fail # Issue 18102
+override_inheritance_mixed_test/08: Fail # Issue 18124
+override_inheritance_mixed_test/09: Fail # Issue 18124
 bad_constructor_test/05: CompileTimeError # Issue 13669
 malformed_test/05: MissingCompileTimeError # Issue 12695
 malformed_test/06: MissingCompileTimeError # Issue 12695
diff --git a/tests/language/override_inheritance_mixed_test.dart b/tests/language/override_inheritance_mixed_test.dart
index 08f8f34..199b466 100644
--- a/tests/language/override_inheritance_mixed_test.dart
+++ b/tests/language/override_inheritance_mixed_test.dart
@@ -13,8 +13,8 @@
   var member5; /// 05: ok
   var member6; /// 06: static type warning
   get member7; /// 07: static type warning
-  get member8; /// 08: compile-time error
-  get member9; /// 09: compile-time error
+  get member8; /// 08: static type warning
+  get member9; /// 09: static type warning
 }
 
 abstract class J {
diff --git a/tests/language/regress_14348_test.dart b/tests/language/regress_14348_test.dart
new file mode 100644
index 0000000..75c5308
--- /dev/null
+++ b/tests/language/regress_14348_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+// Regression test for issue 14348.
+
+import "package:collection/equality.dart";
+
+main() {
+  const Equality<Iterable> eq = const UnorderedIterableEquality();
+  const Equality<Map<dynamic,Iterable>> mapeq =
+     const MapEquality<dynamic, dynamic>(values: eq);
+}
\ No newline at end of file
diff --git a/tests/lib/async/deferred/deferred_api_test.dart b/tests/lib/async/deferred/deferred_api_test.dart
deleted file mode 100644
index f138935..0000000
--- a/tests/lib/async/deferred/deferred_api_test.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that that the basic API for deferred/lazy loading works.  This
-// test deliberately does not test that the deferred elements throw a
-// NoSuchMethodError before the deferred library is loaded.  This
-// makes it possible to pass this test without having implemented
-// deferred loading correctly.
-
-import "package:expect/expect.dart";
-import 'dart:async';
-
-@lazy
-import 'deferred_api_library.dart' as lib;
-
-const lazy = const DeferredLibrary('deferred_api_library');
-
-main() {
-  print('unittest-suite-wait-for-done');
-
-  int counter = 0;
-  lazy.load().then((bool didLoad) {
-    Expect.isTrue(didLoad);
-    Expect.equals(1, ++counter);
-    Expect.equals(42, lib.foo('b'));
-    print('lazy was loaded');
-  });
-  Expect.equals(0, counter);
-  lazy.load().then((bool didLoad) {
-    Expect.isFalse(didLoad);
-    Expect.equals(2, ++counter);
-    Expect.equals(42, lib.foo('b'));
-    print('lazy was loaded');
-    print('unittest-suite-success');
-  });
-  Expect.equals(0, counter);
-}
diff --git a/tests/lib/async/deferred/deferred_fail_to_load_test.dart b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
index 31ecee3..dbecad1 100644
--- a/tests/lib/async/deferred/deferred_fail_to_load_test.dart
+++ b/tests/lib/async/deferred/deferred_fail_to_load_test.dart
@@ -4,7 +4,7 @@
 import 'package:unittest/unittest.dart';
 
 @a import 'deferred_in_isolate_lib.dart' as lib1;
-@b import 'deferred_api_library.dart' as lib2;
+@b import 'deferred_library.dart' as lib2;
 
 const a = const DeferredLibrary("lib1");
 const b = const DeferredLibrary("NonExistingFile", uri: "wrong/wrong.js");
diff --git a/tests/lib/async/deferred/deferred_in_isolate_test.dart b/tests/lib/async/deferred/deferred_in_isolate_test.dart
index bdd8b06..2ced417 100644
--- a/tests/lib/async/deferred/deferred_in_isolate_test.dart
+++ b/tests/lib/async/deferred/deferred_in_isolate_test.dart
@@ -3,7 +3,7 @@
 import 'package:unittest/unittest.dart';
 
 @a import 'deferred_in_isolate_lib.dart' as lib1;
-@b import 'deferred_api_library.dart' as lib2;
+@b import 'deferred_library.dart' as lib2;
 
 const a = const DeferredLibrary("lib1");
 const b = const DeferredLibrary("NonExistingFile", uri: "wrong/");
diff --git a/tests/lib/async/deferred/deferred_api_library.dart b/tests/lib/async/deferred/deferred_library.dart
similarity index 87%
rename from tests/lib/async/deferred/deferred_api_library.dart
rename to tests/lib/async/deferred/deferred_library.dart
index b590770..186a11a 100644
--- a/tests/lib/async/deferred/deferred_api_library.dart
+++ b/tests/lib/async/deferred/deferred_library.dart
@@ -2,8 +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.
 
-// Imported by deferred_api_test.dart.
-
 library deferred_api_library;
 
 foo(x) {
diff --git a/tests/lib/collection/hash_map_test.dart b/tests/lib/collection/hash_map_test.dart
new file mode 100644
index 0000000..f0f1d54
--- /dev/null
+++ b/tests/lib/collection/hash_map_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2011, 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:collection";
+import "package:expect/expect.dart";
+
+void main() {
+  // Test customized maps.
+  // Regression test for issue http://dartbug.com/18109
+
+  hash(s) => s.toLowerCase().hashCode;
+  equals(a, b) => a.toLowerCase() == b.toLowerCase();
+
+  for (var m in [
+    new HashMap<String,int>(equals: equals, hashCode: hash),
+    new LinkedHashMap<String,int>(equals: equals, hashCode: hash),
+  ]) {
+    m["Abel"] = 42;
+    for (var key in ["Abel", "abel", "ABEL", "Abel"]) {
+      Expect.isTrue(m.containsKey(key), "contains $key in ${m.runtimeType} $m");
+      Expect.equals(42, m[key], "get $key in ${m.runtimeType} $m");
+      Expect.equals(42, m.remove(key), "remove $key in ${m.runtimeType} $m");
+      m[key] = 42;
+    }
+  }
+
+  abshash(n) => n.abs();
+  abseq(a, b) => a.abs() == b.abs();
+  for (var m in [
+    new HashMap<int,int>(equals: abseq, hashCode: abshash),
+    new LinkedHashMap<int,int>(equals: abseq, hashCode: abshash),
+  ]) {
+    m[1] = 42;
+    for (var key in [1, -1, 1]) {
+      Expect.isTrue(m.containsKey(key), "contains $key in ${m.runtimeType} $m");
+      Expect.equals(42, m[key], "get $key in ${m.runtimeType} $m");
+      Expect.equals(42, m.remove(key), "remove $key in ${m.runtimeType} $m");
+      m[key] = 42;
+    }
+  }
+}
diff --git a/tests/lib/collection/hash_set_test.dart b/tests/lib/collection/hash_set_test.dart
new file mode 100644
index 0000000..ab03284
--- /dev/null
+++ b/tests/lib/collection/hash_set_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2011, 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:collection";
+import "package:expect/expect.dart";
+
+void main() {
+  // Test customized sets.
+  // Regression test for issue http://dartbug.com/18109
+
+  hash(s) => s.toLowerCase().hashCode;
+  equals(a, b) => a.toLowerCase() == b.toLowerCase();
+
+  for (var m in [
+    new HashSet<String>(equals: equals, hashCode: hash),
+    new LinkedHashSet<String>(equals: equals, hashCode: hash),
+  ]) {
+    m.add("Abel");
+    var prev = "Abel";
+    for (var key in ["Abel", "abel", "ABEL", "Abel"]) {
+      Expect.isTrue(m.contains(key), "contains $key in ${m.runtimeType} $m");
+      Expect.equals(prev, m.lookup(key), "lookup $key in ${m.runtimeType} $m");
+      Expect.isTrue(m.remove(key), "remove $key in ${m.runtimeType} $m");
+      m.add(key);
+      prev = key;
+    }
+  }
+
+  abshash(n) => n.abs();
+  abseq(a, b) => a.abs() == b.abs();
+  for (var m in [
+    new HashSet<int>(equals: abseq, hashCode: abshash),
+    new LinkedHashSet<int>(equals: abseq, hashCode: abshash),
+  ]) {
+    m.add(1);
+    var prev = 1;
+    for (var key in [1, -1, 1]) {
+      Expect.isTrue(m.contains(key), "contains $key in ${m.runtimeType} $m");
+      Expect.equals(prev, m.lookup(key), "lookup $key in ${m.runtimeType} $m");
+      Expect.isTrue(m.remove(key), "remove $key in ${m.runtimeType} $m");
+      m.add(key);
+      prev = key;
+    }
+  }
+}
diff --git a/tests/lib/mirrors/library_uri_io_test.dart b/tests/lib/mirrors/library_uri_io_test.dart
index c44ff1b..25b2dc6 100644
--- a/tests/lib/mirrors/library_uri_io_test.dart
+++ b/tests/lib/mirrors/library_uri_io_test.dart
@@ -8,7 +8,7 @@
 
 import 'dart:mirrors';
 import 'dart:io';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 class Class {
 }
diff --git a/tests/lib/mirrors/library_uri_package_test.dart b/tests/lib/mirrors/library_uri_package_test.dart
index db1ceea..30fcd96 100644
--- a/tests/lib/mirrors/library_uri_package_test.dart
+++ b/tests/lib/mirrors/library_uri_package_test.dart
@@ -8,7 +8,7 @@
 
 import 'dart:mirrors';
 import 'package:args/args.dart';
-import '../../../pkg/unittest/lib/unittest.dart';
+import 'package:unittest/unittest.dart';
 
 testLibraryUri(var value, Uri expectedUri) {
   var valueMirror = reflect(value);
diff --git a/tools/VERSION b/tools/VERSION
index 759bb9d..2a1d14e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 4
 PATCH 0
-PRERELEASE 7
-PRERELEASE_PATCH 13
+PRERELEASE 1
+PRERELEASE_PATCH 0
diff --git a/tools/create_debian_packages.py b/tools/create_debian_packages.py
index 4f31dfb..d739dfd 100755
--- a/tools/create_debian_packages.py
+++ b/tools/create_debian_packages.py
@@ -10,11 +10,12 @@
 # binary packages.
 
 import optparse
+import platform
 import sys
 import tarfile
 import subprocess
 import utils
-
+import os
 from os.path import join, exists, abspath
 from shutil import copyfile
 
@@ -30,7 +31,7 @@
   result.add_option("--out_dir",
                     default=None,
                     help="Where to put the packages.")
- 
+
   return result
 
 def RunBuildPackage(opt, cwd):
@@ -49,7 +50,7 @@
   tarroot = 'dart-%s' % version
   origtarname = 'dart_%s.orig.tar.gz' % version
 
-  if not exists(join(out_dir, tarball)):
+  if not exists(tarball):
     print 'Source tarball not found'
     return -1
 
@@ -85,6 +86,7 @@
     amd64_package = [
       '%s-1_amd64.deb' % debbase
     ]
+
     for name in source_package:
       copyfile(join(temp_dir, name), join(out_dir, name))
     for name in i386_package:
@@ -102,9 +104,13 @@
   tar_filename = options.tar_filename
   if not options.out_dir:
     out_dir = join(DART_DIR, utils.GetBuildDir(HOST_OS, HOST_OS))
-  if not options.tar_filename:
-    raise Exception('Please specify the input filename.')
-  BuildDebianPackage(options.tar_filename, options.out_dir)
+
+  if not tar_filename:
+    tar_filename = join(DART_DIR,
+                        utils.GetBuildDir(HOST_OS, HOST_OS),
+                        'dart-%s.tar.gz' % utils.GetVersion())
+
+  BuildDebianPackage(tar_filename, out_dir)
 
 if __name__ == '__main__':
   sys.exit(Main())
diff --git a/tools/create_tarball.py b/tools/create_tarball.py
index 58679e0..1604ef7 100755
--- a/tools/create_tarball.py
+++ b/tools/create_tarball.py
@@ -155,10 +155,13 @@
     global verbose
     verbose = True
 
-  if not options.tar_filename:
-    raise Exception('Please specify an output filename')
+  tar_filename = options.tar_filename
+  if not tar_filename:
+    tar_filename = join(DART_DIR,
+                        utils.GetBuildDir(HOST_OS, HOST_OS),
+                        'dart-%s.tar.gz' % utils.GetVersion())
 
-  CreateTarball(options.tar_filename)
+  CreateTarball(tar_filename)
 
 if __name__ == '__main__':
   sys.exit(Main())
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index ed530cc..a3d59b9 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -670,8 +670,9 @@
   }
 
   Command _getUniqueCommand(Command command) {
-    // All Command classes have hashCode/operator==, so we check if this command
-    // has already been build, if so we return the cached one, otherwise we
+    // All Command classes implement hashCode and operator==.
+    // We check if this command has already been built.
+    //  If so, we return the cached one. Otherwise we
     // store the one given as [command] argument.
     var cachedCommand = _cachedCommands[command];
     if (cachedCommand != null) {
@@ -1674,6 +1675,69 @@
 
 
 /**
+ * An OutputLog records the output from a test, but truncates it if
+ * it is longer than MAX_HEAD characters, and just keeps the head and
+ * the last TAIL_LENGTH characters of the output.
+ */
+class OutputLog {
+  static const int MAX_HEAD = 100 * 1024;
+  static const int TAIL_LENGTH = 10 * 1024;
+  List<int> head = <int>[];
+  List<int> tail;
+  List<int> complete;
+  bool dataDropped = false;
+
+  OutputLog();
+
+  void add(List<int> data) {
+    if (complete != null) {
+      throw new StateError("Cannot add to OutputLog after calling toList");
+    }
+    if (tail == null) {
+      head.addAll(data);
+      if (head.length > MAX_HEAD) {
+        tail = head.sublist(MAX_HEAD);
+        head.length = MAX_HEAD;
+      }
+    } else {
+      tail.addAll(data);
+    }
+    if (tail != null && tail.length > 2 * TAIL_LENGTH) {
+      tail = _truncatedTail();
+      dataDropped = true;
+    }
+  }
+
+  List<int> _truncatedTail() =>
+    tail.length > TAIL_LENGTH ?
+        tail.sublist(tail.length - TAIL_LENGTH) :
+        tail;
+
+  List<int> toList() {
+    if (complete == null) {
+      complete = head;
+      if (dataDropped) {
+        complete.addAll("""
+
+*****************************************************************************
+
+Data removed due to excessive length
+
+*****************************************************************************
+
+""".codeUnits);
+        complete.addAll(_truncatedTail());
+      } else if (tail != null) {
+        complete.addAll(tail);
+      }
+      head = null;
+      tail = null;
+    }
+    return complete;
+  }
+}
+
+/**
  * A RunningProcess actually runs a test, getting the command lines from
  * its [TestCase], starting the test process (and first, a compilation
  * process if the TestCase is a [BrowserTestCase]), creating a timeout
@@ -1690,8 +1754,8 @@
   DateTime startTime;
   Timer timeoutTimer;
   int pid;
-  List<int> stdout = <int>[];
-  List<int> stderr = <int>[];
+  OutputLog stdout = new OutputLog();
+  OutputLog stderr = new OutputLog();
   bool compilationSkipped = false;
   Completer<CommandOutput> completer;
 
@@ -1814,8 +1878,8 @@
         command,
         exitCode,
         timedOut,
-        stdout,
-        stderr,
+        stdout.toList(),
+        stderr.toList(),
         new DateTime.now().difference(startTime),
         compilationSkipped,
         pid);
@@ -1823,8 +1887,8 @@
   }
 
   StreamSubscription _drainStream(Stream<List<int>> source,
-                                  List<int> destination) {
-    return source.listen(destination.addAll);
+                                  OutputLog destination) {
+    return source.listen(destination.add);
   }
 
   Map<String, String> _createProcessEnvironment() {
@@ -1875,8 +1939,8 @@
   Function _processExitHandler;
 
   bool _currentlyRunning = false;
-  List<int> _testStdout;
-  List<int> _testStderr;
+  OutputLog _testStdout;
+  OutputLog _testStderr;
   String _status;
   DateTime _startTime;
   Timer _timer;
@@ -1932,8 +1996,8 @@
 
   void doStartTest(Command command, int timeout) {
     _startTime = new DateTime.now();
-    _testStdout = [];
-    _testStderr = [];
+    _testStdout = new OutputLog();
+    _testStderr = new OutputLog();
     _status = null;
     _stdoutCompleter = new Completer();
     _stderrCompleter = new Completer();
@@ -1963,8 +2027,8 @@
     var output = createCommandOutput(_command,
                         exitCode,
                         (outcome == "TIMEOUT"),
-                        _testStdout,
-                        _testStderr,
+                        _testStdout.toList(),
+                        _testStderr.toList(),
                         new DateTime.now().difference(_startTime),
                         false);
     assert(_completer != null);
@@ -2020,8 +2084,8 @@
         } else if (line.startsWith('>>> ')) {
           throw new Exception("Unexpected command from batch runner: '$line'.");
         } else {
-          _testStdout.addAll(encodeUtf8(line));
-          _testStdout.addAll("\n".codeUnits);
+          _testStdout.add(encodeUtf8(line));
+          _testStdout.add("\n".codeUnits);
         }
         if (_status != null) {
           _stdoutSubscription.pause();
@@ -2040,8 +2104,8 @@
           _stderrSubscription.pause();
           _stderrCompleter.complete(null);
         } else {
-          _testStderr.addAll(encodeUtf8(line));
-          _testStderr.addAll("\n".codeUnits);
+          _testStderr.add(encodeUtf8(line));
+          _testStderr.add("\n".codeUnits);
         }
       });
       _stderrSubscription.pause();